混淆setter方法

时间:2013-03-10 20:53:43

标签: ruby

class Test
  attr_accessor :something
end

class Test
  alias :old_something= :something=
  def something=(a)
    a += 2              # do something with the argument
    old_something=(a)   # then pass it on
  end
end

我希望如果我说

t = Test.new
t.something = 3
puts t.something

它会打印出5。但它会打印nil。为什么这不起作用?

3 个答案:

答案 0 :(得分:2)

表格

foo = bar

分配给局部变量。您需要明确表示要调用方法:

self.foo = bar

答案 1 :(得分:0)

编辑:@Jörg的答案可能是真正的问题,但我在下面的原始答案也可能有所帮助。从旧的答案中删除了一些误导性的细节。

如果完全删除def something=,您将获得something的设置者,其别名为old_something

class Test
  attr_accessor :something
end

class Test
  alias :old_something= :something=
end


1.9.3p327 :001 > require "./test.rb"
=> true
1.9.3p327 :002 > t = Test.new
=> #<Test:0x000000018eb740>
1.9.3p327 :003 > t.something = "blah"
=> "blah"
1.9.3p327 :004 > t.something
=> "blah"
1.9.3p327 :005 > t.old_something = "moo"
=> "moo"
1.9.3p327 :006 > t.something
=> "moo"

答案 2 :(得分:0)

原因是@something从未被分配给任何东西。

此代码将执行您要执行的操作:

class Test
  attr_accessor :something
end

class Test
  alias :old_something= :something=
  def something=(a)
    @something = a += 2 # do something with the argument
    old_something=(a)   # then pass it on
  end
end

t = Test.new
t.something=( 3)
puts t.something

区别在于将实例变量@something分配给一个值,然后允许您的代码通过传入的a变量递增它。