解释为局部变量会覆盖方法名称?

问题描述 投票:0回答:4

这个问题所示,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为

nil

x = x # => nil 

但是当局部变量的名称与现有方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回

nil

{}.instance_eval{a = keys} # => []
{}.instance_eval{keys = self.keys} # => []
{}.instance_eval{keys = keys} # => nil
ruby local-variables self-reference
4个回答
13
投票

在 Ruby 中,由于可以在没有显式接收器和括号的情况下调用方法,因此局部变量引用和无接收器无参数方法调用之间存在语法歧义:

foo

可以 either 表示“在

foo
上不带参数调用方法
self
”或“取消引用局部变量
foo
”。

如果作用域中存在局部变量

foo
,则always解释为局部变量取消引用,never解释为方法调用。

那么,局部变量“在作用域内”意味着什么?这是在解析时语法上确定的,而不是在运行时在语义上确定的。这个非常重要!局部变量是在解析时定义的:如果解析器看到对局部变量的赋值,则局部变量从那时起就在范围内。然而,它只是在 runtime initialized,没有正在进行的代码编译时评估: if false foo = 42 # from this point on, the local variable foo is in scope end foo # evaluates to nil, since it is declared but not initialized

为什么局部变量“影子”方法有意义,而不是相反?好吧,如果方法确实隐藏了局部变量,那么就不再有办法取消引用这些局部变量。但是,如果局部变量影子方法,那么仍然有一种方法可以调用这些方法:记住,歧义仅存在于无接收器无参数方法调用,如果添加显式接收器或显式参数列表,您仍然可以调用该方法: 

def bar; 'Hello from method' end; public :bar bar # => 'Hello from method' bar = 'You will never see this' if false bar # => nil bar = 'Hello from local variable' bar # => 'Hello from local variable' bar() # => 'Hello from method' self.bar # => 'Hello from method'



1
投票

a = b if a => nil a => nil

变量 
a

被初始化为 nil,即使理论上 a = b 语句在任何情况下都不应该被执行。

    


0
投票
self

def some_class_method
  another_class_method_local = self.another_class_method
  # do stuff with the *_local variable
  self.another_class_method = another_class_method_local
end



-3
投票

1.9.3-p194 :001 > {}.instance_eval{a=1} => 1 1.9.3-p194 :002 > {}.instance_eval{a} NameError: undefined local variable or method `a' for {}:Hash from (irb):2:in `block in irb_binding' from (irb):2:in `instance_eval' from (irb):2 from /Users/rafael/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

实例评估在实例级别评估代码,因此您声明的每个哈希都是不同的。如果你想归还钥匙,这可行

1.9.3-p194 :003 > {}.instance_eval{keys = self.keys 1.9.3-p194 :004?> keys = keys} => []

© www.soinside.com 2019 - 2024. All rights reserved.