Ruby 块外局部变量
我正在读关于ruby作用域的书,书中说局部变量在定义它们的块之外是不可访问的 例如,在下面的示例中<代码>b不应在Ruby 块外局部变量,ruby,scope,Ruby,Scope,我正在读关于ruby作用域的书,书中说局部变量在定义它们的块之外是不可访问的 例如,在下面的示例中b不应在if块之外访问 a=3 Ruby中的“块”基本上是包含在do…end内或大括号之间的代码。(在Ruby中还有其他的创建块的方法,但这个定义会让你坚持很长一段时间。)如果……end不被认为是块。当…结束时,两者都不是。使问题进一步复杂化的是,您在之后添加的do,而也不会使其成为块;Ruby只是很有帮助地忽略了它 卡里已经在评论中解释了这一点,但我会看看是否能为你澄清一下。我将简化并清理您的代码
if
块之外访问
a=3
Ruby中的“块”基本上是包含在do…end
内或大括号之间的代码。(在Ruby中还有其他的创建块的方法,但这个定义会让你坚持很长一段时间。)如果……end
不被认为是块。当…结束时,两者都不是。使问题进一步复杂化的是,您在之后添加的do
,而也不会使其成为块;Ruby只是很有帮助地忽略了它
卡里已经在评论中解释了这一点,但我会看看是否能为你澄清一下。我将简化并清理您的代码:
a = 3
while a < 10
b = a * 3
a += 1
end
puts b
我会得到这个:
undefined local variable or method `b' for main:Object (NameError)
这正是你所期待的。这是因为而是一个语句<代码>while…end
可以包含几行代码,但不算作块。(与if
相同)但循环实际上是一种将块作为参数的方法,因此Cary在其评论中描述的范围规则适用。在Ruby中,“块”基本上是包含在do…end
内或大括号之间的代码。(在Ruby中还有其他的创建块的方法,但这个定义会让你坚持很长一段时间。)如果……end
不被认为是块。当…结束时,两者都不是。使问题进一步复杂化的是,您在之后添加的do
,而也不会使其成为块;Ruby只是很有帮助地忽略了它
卡里已经在评论中解释了这一点,但我会看看是否能为你澄清一下。我将简化并清理您的代码:
a = 3
while a < 10
b = a * 3
a += 1
end
puts b
我会得到这个:
undefined local variable or method `b' for main:Object (NameError)
这正是你所期待的。这是因为而是一个语句<代码>while…end
可以包含几行代码,但不算作块。(与if
相同)但循环实际上是一种将块作为参数的方法,因此Cary在其注释中描述的作用域规则适用。对于,而和直到循环不创建新的作用域。在循环之前定义的局部变量在循环中可用,然后在循环之后可用。正如您所发现的,在循环中创建的局部变量在循环之后也是可见的。这与具有块的方法不同,例如每个
和循环
。对于这些,之前定义的局部变量在块中和之后仍然可见,但在块中创建的局部变量的可见性仅限于块。例如,a=5;循环do;a=a+6;b=3;打破终止a#=>11;b#=>名称错误(…)
。代码中没有任何块。对于
,当
和循环时,直到
循环不创建新范围。在循环之前定义的局部变量在循环中可用,然后在循环之后可用。正如您所发现的,在循环中创建的局部变量在循环之后也是可见的。这与具有块的方法不同,例如每个
和循环
。对于这些,之前定义的局部变量在块中和之后仍然可见,但在块中创建的局部变量的可见性仅限于块。例如,a=5;循环do;a=a+6;b=3;打破终止a#=>11;b#=>namererror(…)
。code.OP中没有任何块很可能来自必须使用索引显式循环的语言。您可以使用(3…10)。每个都执行一个结束
,以获得相同的结果。或者,如果OP使用它来访问某种数组,你可以将数组切片(3…10)。每个do | item |end
注意,我使用了三个点,它们散发出范围的末端。我实际上认为,do end
中的任何东西都是一个块。我不知道ruby会忽略do for,而
@VedantShetty也有人用end
来表示doc所称的“语法块”的结尾。作为方法一部分的块有这里讨论的范围规则。作为控制表达式一部分的块,如而或如果没有。在这种情况下添加do
不会改变这一点。OP很可能来自一种必须使用索引显式循环的语言。您可以使用(3…10)。每个都执行一个结束
,以获得相同的结果。或者,如果OP使用它来访问某种数组,你可以将数组切片(3…10)。每个do | item |end
注意,我使用了三个点,它们散发出范围的末端。我实际上认为,do end
中的任何东西都是一个块。我不知道ruby会忽略do for,而
@VedantShetty也有人用end
来表示doc所称的“语法块”的结尾。作为方法一部分的块有这里讨论的范围规则。作为控制表达式一部分的块,如而或如果没有。在这种情况下,添加do
不会改变这一点。