请考虑以下代码:
class Dummy
def attr=(arg = 10)
@attr = arg
end
def attr2=(arg = 20)
@attr2 = 20
end
end;
d = Dummy.new; d.attr=(); d.attr2=(); d
=> #<Dummy:0x007f8d6430e2a8 @attr=nil, @attr2=20>
似乎attr=
方法丢弃了默认参数值,并且无论如何都将nil
分配给实例变量,但是在attr2=
方法中分配显式值是有效的。为什么会这样?
我应该以更清晰的方式表达自己。分配显式值显然适用于attr2=
方法。这只留下一个解释 - setter方法丢弃默认参数值。为什么要丢弃?
答案 0 :(得分:7)
以=
结尾的方法不是普通的方法,因为它们被ruby解释器识别为setter,因此具有语法糖:
d.attr = 4
当您致电d.attr=()
时,您实际上正在呼叫d.attr=(())
。 ruby中的()
返回nil
:
()
# => nil
Ruby解释器不会让你没有任何参数,因为如果你完全删除()
,ruby只会将下一行的结果作为参数,或抛出syntax error
如果你试图使用;
d.attr=
5
# => 5
d.attr=;
# => syntax error, unexpected ';'
要查看您的默认参数,您可以使用send
:
d.send(:attr=)
# => 10
d
# => #<Dummy:0x007f8d6430e2a8 @attr=10, @attr2=20>
答案 1 :(得分:0)
这是因为你没有使用setter arg
中的默认参数 - attr2
来设置实例变量的值。您正在对方法中的值20进行硬编码,这就是为什么在设置器attr
不设置时它被设置的原因。
话虽如此,我相信你不能在一个方法中省略参数,这个方法在Ruby中以相同的方式结束并期望什么都不通过;我相信nil会在没有参数的情况下通过。
答案 2 :(得分:0)
@Uri Agassi的精彩解释。但我想我们不需要在这里使用发送。我们可以做到以下几点: -
class Dummy
def attr=(arg)
#assign default value here
arg = 10 if arg.nil?
@attr = arg
end
def attr2=(arg = 20)
@attr2 = 20
end
end;
d = Dummy.new; d.attr=(); d.attr2=(); p d