在David Flanagan和松本行弘合著的《Ruby编程语言》一书中,他们指出变量前缀($、@、@@)是我们能够省略方法调用括号的代价之一。有人可以向我解释一下这句话的意思吗?
以下是我的不成熟看法。如果我错了,请纠正我。
假设实例变量没有@
前缀,那么我们如何声明实例变量?
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
foo
使用假设的语法进行初始化。self.foo = 'bar'
foo
属于当前实例并且不是局部变量。bar
中,如果没有强制使用括号进行方法调用,解释器如何判断 self.foo
是方法调用还是实例变量访问?MyClass
定义之外:obj = MyClass.new
# Call instance method
obj.foo
bar
中,self.foo
(没有括号)是一个实例变量访问。这种语法上的不一致可能会导致错误。此外,它使解释器本身的实现变得困难。def foo
10
end
p foo
#=> 10
foo = 'hi'
p foo
#=> hi
p foo()
#=> 10
如果我们在同一作用域中定义一个与方法名称相同的局部变量,那么我们将失去对方法名称的绑定,因为变量名称优先。为了消除歧义,必须使用括号。
这本书似乎详细阐述了这种现象,并设计了决策,以提供灵活性,其中需要使用符号(如@
)来定义实例变量,以便可以调用相应的访问器方法(var
和var=
)而无需使用括号,人们会有一种访问变量的印象,即使实际上是调用方法。
……您会注意到Ruby变量名称开头的标点符号:全局变量以$为前缀,实例变量以@为前缀,类变量以@@为前缀。这些前缀可能需要一点时间来适应,但是过一段时间后,您可能会欣赏前缀告诉您变量范围的事实。这些前缀是必需的,以消除Ruby非常灵活的语法的歧义。变量前缀的一种思考方式是,它们是我们为能够省略方法调用周围的括号所付出的代价之一。