Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我不知道';我不理解ruby的局部作用域_Ruby - Fatal编程技术网

我不知道';我不理解ruby的局部作用域

我不知道';我不理解ruby的局部作用域,ruby,Ruby,在这个例子中 def foo(x) if(x > 5) bar = 100 end puts bar end 然后foo(6)输出:100 foo(3)不输出任何内容 但是如果我把定义改为 def foo(x) if(x > 5) bar = 100 end puts bob end 我得到一个“未定义的局部变量或方法”错误 所以我的问题是,当我调用foo(3)时,为什么没有得到这个错误,而bar从未设置?我不知道你在问什么。使用第二个定义

在这个例子中

def foo(x)
  if(x > 5)
    bar = 100
  end
  puts bar
end
然后foo(6)输出:100 foo(3)不输出任何内容

但是如果我把定义改为

def foo(x)
  if(x > 5)
    bar = 100
  end
  puts bob
end
我得到一个“未定义的局部变量或方法”错误


所以我的问题是,当我调用foo(3)时,为什么没有得到这个错误,而bar从未设置?

我不知道你在问什么。使用第二个定义运行
foo(3)
总是会出现错误,因为从未定义过
bob
。该方法的参数并没有改变这一点。

所以不要把它当作福音(因为它更多的是基于观察而不是理解),但ruby解释器似乎会将等号左侧的任何单词(前面没有符号)标记为局部。你的例子很奇怪,这更奇怪

def foo
  bar = bar
  puts bar // nil, which gets coerced into ""
end

我不明白它为什么或者是如何工作的,但你已经知道了。

这里发生了一些事情。首先,在
if
块中声明的变量与在方法顶层声明的变量具有相同的局部作用域,这就是为什么
bar
if
之外可用的原因。第二,您得到这个错误是因为
bob
被直接引用了。Ruby解释器以前从未见过它,也从未见过它被初始化。但是,它在if语句中看到了之前初始化的
bar
。所以当它到达酒吧时,它知道它的存在。把这两者结合起来,这就是你的答案

您的第二个示例实际上是在转移注意力:您得到异常的原因不是因为
bob
未初始化,而是因为它不明确。不可能分辨它是一个变量还是一个方法

您的第一个示例有效,因为未初始化的局部变量(以及全局变量和实例变量)的计算结果为
nil
。因此,
put bar
非常好:在一种情况下,
bar
被初始化为
100
,其计算结果为
100
,在另一种情况下,它未初始化,因此计算结果为
nil
调用放在其参数上,该参数是为
nil
定义的(它只返回空字符串),因此一切都很好

另请参见

foo(3)
不输出任何内容。它输出一个换行符

使用
inspect
会给您更多提示:

def foo(x)
  if(x > 5)
    bar = 100
  end
  puts bar.inspect
end

foo(3)
打印出来

nil

bar
是一个完全成熟的变量,其值恰好为
nil

+1!JavaScript的工作方式也是如此。它将所有声明移到顶部,并将赋值保留在原来的位置。这可能有点令人困惑。赋值的LHS上的所有内容都将初始化为nil:
>如果为false;测试=无论什么;结束;测试#=>nil
。这也是像
x | | |=5
这样的东西的工作原理,因为它意味着
x=x | | 5
,如果x之前没有定义,那么它将是
x=nil | | 5
。@jwueller Ruby不会将所有赋值移到顶部<代码>放置b;b=b导致
NameError:main:Object
@MichaelKohl的未定义局部变量或方法“b”
x | | |=5
不一定等同于
x=x | | 5
x
x=/code>是方法时。例如,
object.x | |=5
()。不过在大多数情况下,你是对的。谢谢,是的,我知道鲍勃的错误在哪里,只是不知道为什么我没有得到一个酒吧的错误。你知道我是否可以依赖这种行为,它是规范的一部分吗?例如,我可以在if语句之后检查bar是否为nil,还是应该在if语句之前显式声明bar=nil?是的,这是可靠的行为。声明bar=nil肯定会更加明确。但我不知道大多数红宝石爱好者会这么做。如果你保持方法的小型化,就不难理解或了解bar的来源。我不知道Ruby,但如果这是正确的,那么Todd接受的答案大概是不正确的。他暗示bob的问题不是它为零,而是它未初始化。其他的答案表明你是对的。@Jörg:非常感谢你,现在你把它说得非常清楚了。我想知道马茨是否太忙了,没有你现在解释的那么清楚。回答得好!