Olá:
Estou começando meus estudos no Ruby e me deparei com uma situação curiosa. Vejam o código abaixo:
irb(main):051:0> class MinhaClasse
irb(main):052:1> @valor = 10
irb(main):053:1> def get_valor
irb(main):054:2> @valor
irb(main):055:2> end
irb(main):056:1> end
=> nil
irb(main):057:0> m = MinhaClasse.new
=> #<MinhaClasse:0xc278b5>
irb(main):058:0> m.get_valor
=> nil
Ou seja, tenho uma class com atributo cujo valor é definido em sua declaração. Mas quando tento acessá-lo obtenho nil.
Agora uma alteração na minha classe:
irb(main):061:0> class MinhaClasse
irb(main):062:1> @valor
irb(main):063:1> def initialize(v)
irb(main):064:2> @valor = v
irb(main):065:2> end
irb(main):066:1> def get_valor
irb(main):067:2> @valor
irb(main):068:2> end
irb(main):069:1> end
=> nil
irb(main):070:0> m = MinhaClasse.new(10)
=> #<MinhaClasse:0x1efa490 @valor=10>
irb(main):071:0> m.get_valor
=> 10
Por outro lado:
irb(main):072:0> class MinhaClasse
irb(main):073:1> attr_accessor :valor
irb(main):074:1> end
=> nil
irb(main):075:0> m = MinhaClasse.new
ArgumentError: Wrong # of arguments(0 for 1)
from (irb):75:in `new'
from (irb):75:in `binding'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:150:in `evaluate'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:150:in `eval_input'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:70:in `signal_status'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:147:in `eval_input'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:70:in `each_top_level_statement'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:146:in `loop'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:146:in `catch'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:146:in `eval_input'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:70:in `start'
from C:\jruby-1.0.2\bin\..\bin\jirb_swing:41:in `catch'
from C:/jruby-1.0.2/lib/ruby/1.8/irb.rb:69:in `start'
from C:\jruby-1.0.2\bin\..\bin\jirb_swing:41
irb(main):076:0> m = MinhaClasse.new(10)
=> #<MinhaClasse:0x162f16 @valor=10>
Então a moral da história seria: “Se sua classe possui atributos sempre inicialize-os no construtor. Não adianta inicializá-los na declaração pois eles sempre vão começar com nil.”? :?
Se é assim então por que no primeiro código já não é emitido nenhum tipo de aviso ou exceção? Se existe alguma forma de contornar essa situação, como é?
Grato,



