首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解释为局部变量会覆盖方法名吗?

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

Stack Overflow用户
提问于 2012-10-03 18:33:15
回答 3查看 1.3K关注 0票数 5

与在this question中一样,当在自己的赋值中使用未定义的局部变量时,它的计算结果为nil

代码语言:javascript
复制
x = x # => nil 

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

代码语言:javascript
复制
{}.instance_eval{a = keys} # => []
{}.instance_eval{keys = self.keys} # => []
{}.instance_eval{keys = keys} # => nil
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-03 20:31:34

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

代码语言:javascript
复制
foo

可以表示“在self上调用不带参数的方法foo”,也可以表示“取消引用局部变量foo”。

如果作用域中存在局部变量foo,则始终将其解释为局部变量取消引用,而不是方法调用。

那么,局部变量“在作用域中”意味着什么呢?这是在解析时从语法上确定的,而不是在运行时从语义上确定的。这是非常重要的!局部变量是在解析时定义的:如果解析器看到局部变量的赋值,则从那时起局部变量就在作用域中。然而,它只在运行时初始化,没有对代码进行编译时评估:

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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'
票数 13
EN

Stack Overflow用户

发布于 2012-10-03 18:37:03

简单的答案是,因为Matz是这样定义的。这种行为是我不喜欢Ruby的少数几个原因之一。它甚至变得更好:

代码语言:javascript
复制
a = b if a
=> nil
a
=> nil

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

票数 1
EN

Stack Overflow用户

发布于 2012-10-03 18:40:38

我认为在你的情况下,这是因为它是预期的:

代码语言:javascript
复制
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>'

Instance eval在实例级评估代码,因此您声明的每个哈希都是不同的。如果您想要返回密钥,这是可行的

代码语言:javascript
复制
1.9.3-p194 :003 > {}.instance_eval{keys = self.keys
1.9.3-p194 :004?>   keys = keys}
 => [] 
票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12706664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档