在Ruby中不能在eigenclass中定义getter方法

时间:2013-06-29 10:44:39

标签: ruby

我想为对象定义一个新的getter方法。这是我在irb写的代码:

> eigenclass = class << self; self; end
> eigenclass.class_eval { attr_reader :foo }

我想这段代码应该将foo方法添加到自我对象中。但下一行说的不同

puts foo  
=> nil
foo = 1
=> 1       #Why is there no exception?
puts foo  
=> 1
puts @foo 
=> nil

为什么?

2 个答案:

答案 0 :(得分:3)

那是因为var = val分配一个局部变量而不是调用setter方法。

你需要在它前面添加self.以便调用setter(以及实际的getter,以防你有一个同名的局部变量),这会抛出你期望的错误:

2.0.0p195 :001 > eigenclass = class << self; self; end
 => #<Class:#<Object:0x007fc6f98e24d0>>
2.0.0p195 :002 > eigenclass.class_eval { attr_reader :foo }
 => nil
2.0.0p195 :003 > foo
 => nil
2.0.0p195 :004 > foo = 20
 => 20
2.0.0p195 :005 > foo
 => 20
2.0.0p195 :006 > self.foo
 => nil
2.0.0p195 :007 > self.foo = 20
NoMethodError: undefined method `foo=' for main:Object
    from (irb):7

答案 1 :(得分:3)

你犯了两个错误: a)如果你想要完整的访问者(getter和setter),你应该使用:

eigenclass.class_eval { attr_accessor :foo }

b)如果你想使用setter方法,你应该使用self关键字,否则Ruby会设置一个局部变量:

self.foo = 1
# => 1
puts @foo
# => 1

或者,如果没有定义setter,您可以直接设置实例变量:

eigenclass.class_eval { attr_accessor :foo }
@foo = 1
puts @foo
# => 1