Specifying the default value for the setter method

Consider the following code:

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> 

The attr= method seems to discard the default value of the parameter and in any case assigns the nil variable to the instance variable, but assigning an explicit value works in the attr2= method. Why is this happening?

Edit:

I had to express myself more clearly. Assigning an explicit value obviously works in the attr2= method. This leaves only one explanation - the setter methods discard the default value of the parameter. Why does this drop occur?

+5
source share
3 answers

Methods ending with = are not ordinary methods, because they are identified by the ruby โ€‹โ€‹interpreter as setters and therefore have syntactic sugar:

 d.attr = 4 

When you call d.attr=() , you actually call d.attr=(()) . () in ruby โ€‹โ€‹returns nil :

 () # => nil 

The Ruby interpreter will not let you go without any arguments, because if you drop () at all, ruby โ€‹โ€‹will simply take the result of the next line as a parameter or throw syntax error if you try to break the line using ;

 d.attr= 5 # => 5 d.attr=; # => syntax error, unexpected ';' 

To see your default argument, you can use send :

 d.send(:attr=) # => 10 d # => #<Dummy:0x007f8d6430e2a8 @attr=10, @attr2=20> 
+7
source

This is because you are not setting the value of the instance variable using the default argument arg in setter attr2 . You hardcode the value 20 in the method, so it is set until attr is set.

Having said that, I believe that you cannot leave arguments in a method that ends with equal in Ruby and does not expect to skip anything; I believe that nil will be passed without arguments.

0
source

Good explanation from @Uri Agassi. But I think we do not need to use send here. we can do the following: -

 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=(); pd 
0
source

Source: https://habr.com/ru/post/1209475/


All Articles