In Ruby, if we define a call to the c = method, why can't it be called c = 3?

For example, if we

def c=(foo) p "hello" end c = 3 c=(3) 

and no hello will be printed. I know that it can be called self.c = 3 , but why? and in what other way can it be called?

+5
ruby
Feb 24 2018-11-21T00:
source share
3 answers

c = 3 (and c = (3) , which is completely equivalent to it) is always interpreted as the local assignment of variables. You could say that this should be interpreted as assigning a local variable only if the c= method c= not defined for itself, but there are various problems with this:

  • At the very least, the MRI should know during parsing which local variables are defined in a given area. However, during the parsing, it is not known whether this method is determined or not. Thus, Ruby could not know whether c = 3 defines the variable c or invokes the c= method until runtime, which means that it will not know if the local variable c defined during parsing. This means that the MRI will need to change the way the local variables are processed in the parser so that it works the way you want.

  • It is not possible to define a local variable named c if the c= method c= already defined. You can say that everything is in order, because local variables and methods with the same name are confused anyway. However, consider the case in which you define method_missing so that foo= is defined for every possible foo (such as for OpenStruct ). In this case, it is generally impossible to define local variables.

  • You cannot say for sure whether the object responds to c= without starting it, because it can be handled by method_missing . Thus, all this would indeed be insoluble.

+8
Feb 24 '11 at 10:40
source share

Because local variables take precedence over previously defined methods / variables with the same name. In this case, you need to qualify as "I", so c is not interpreted as declaring / assigning a local variable.

+7
Feb 24 2018-11-22T00:
source share

Ruby only calls this method if the code cannot be interpreted as a variable assignment. There is no better way to force a method call.

 self.c = 1 send(:c=, 1) __send__(:c=, 1) method(:c=).call(1) method(:c=)[1] 
+3
Feb 24 2018-11-21T00:
source share



All Articles