In The Ruby Programming Language by David Flanagan; Yukihiro Matsumoto, they state that the variable prefixes ($, @, @@) are one price we pay for being able to omit parentheses around method invocations. Can someone explain this to me?
Here is my immature opinion. If I'm wrong, please correct me.
Suppose the instance variables don't have a @
prefix, then how do we declare an instance variable?
class MyClass
def initialize
# Here foo is an instance variable
self.foo = 'bar'
end
# Here foo is an instance method
def foo
end
def bar
# Call method. No doubt.
self.foo()
# Call method? Access instance variable?
self.foo
end
end
In the case above, the instance variable foo
is initialized using the hypothetical syntax
self.foo = 'bar'
because we must have a way to tell the ruby interpreter that foo
belongs to the current instance and is not a local variable.
Then in the method bar
, if parentheses are not enforced in method invocation, how can the interpreter tell whether self.foo
is a method invocation or an instance variable access?
Maybe we can let instance variables shadow instance methods when parentheses are missing, but this causes syntax inconsistency of the language itself. For example, from outside the MyClass
definition:
obj = MyClass.new
# Call instance method
obj.foo
It's an instance method invocation because all instance variables are invisible from outside (at least without using meta programming). But the self.foo
(without parentheses) in the method bar
is an instance variable access. This syntax inconsistency may lead to bugs. Also, it brings difficulty in implementing the interpreter itself.
Then what about letting instance methods shadow instance variables? Then the programmers have to ensure the instance variable names don't collide with instance method names, otherwise the instance variables become inaccessible. It's very difficult if a class have a long ancestors chain because one must check collisions not only in the current class definition, but also in its ancestors, and this breaks encapsulation.
Either way, the price is much higher than adding a prefix to instance variables. For class and global variables, the situations are similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With