指定setter方法的默认值

时间:2014-12-18 18:03:19

标签: ruby

请考虑以下代码:

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方法丢弃默认参数值。为什么要丢弃?

3 个答案:

答案 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