方法内/外的Ruby块变量范围
我得到了以下不同的结果: 测试1:方法内/外的Ruby块变量范围,ruby,variables,block,Ruby,Variables,Block,我得到了以下不同的结果: 测试1: def myblock x = 1 y = 1 yield(x) [x, y] end myblock do |x| y = 10 end # => [1,1] 测试2: x = 1 y = 1 1.upto(2) do |x| y = 20 end [x,y] # => [1,20] 在块外部创建的变量在块中可用。为什么会这样?这就是如何定义局部变量的范围。局部变量可以渗透到块中,但不能渗透到方法定义中。这就是局部变
def myblock
x = 1
y = 1
yield(x)
[x, y]
end
myblock do |x|
y = 10
end
# => [1,1]
测试2:
x = 1
y = 1
1.upto(2) do |x|
y = 20
end
[x,y]
# => [1,20]
在块外部创建的变量在块中可用。为什么会这样?这就是如何定义局部变量的范围。局部变量可以渗透到块中,但不能渗透到方法定义中。这就是局部变量范围的定义方式。局部变量可以渗透到块中,但不能渗透到方法定义中
def myblock
x = 1
y = 1
z = yield(x)
puts "y=#{y}, z=#{z}"
[x, y]
end
myblock do |x|
y = 10
end
y=1, z=10
#=> [1, 1]
这表明这里发生了三件事:
- 块中的
与y
中的myblock
无关。这是因为块中y
的范围仅限于块。Ruby只能得到块返回的内容,而不能得到块内部发生的事情y
- 块确实返回块中
的值,但这只是因为y
是块中执行的最后一条语句。该语句的执行返回y=10
,因此块返回10
。包含10
,y=10的块;7
将被返回7
中的变量myblock
未捕获y
的值,因此该值无效。1yield(x)
- 块中的
与y
中的myblock
无关。这是因为块中y
的范围仅限于块。Ruby只能得到块返回的内容,而不能得到块内部发生的事情y
- 块确实返回块中
的值,但这只是因为y
是块中执行的最后一条语句。该语句的执行返回y=10
,因此块返回10
。包含10
,y=10的块;7
将被返回7
中的变量myblock
未捕获y
的值,因此该值无效。1yield(x)
1众所周知,Ruby实际上将这些值发射到了外层空间。经过更多的测试和搜索: 对于Test1,x和y是方法级局部变量,它们不与block共享作用域。块中的y是一个新的局部变量(块级别) 对于Test2,x和y是类级局部变量,它们与块共享作用域,块中的y仍然是外部的y(类级)
这都是因为我弄乱了范围,谢谢大家。经过更多的测试和搜索: 对于Test1,x和y是方法级局部变量,它们不与block共享作用域。块中的y是一个新的局部变量(块级别) 对于Test2,x和y是类级局部变量,它们与块共享作用域,块中的y仍然是外部的y(类级)
这都是因为我弄乱了范围,谢谢大家。技术上还有另一个问题;在第一个片段中,没有跨越方法定义边界的局部变量;在第一个代码段中,没有跨越方法定义边界的局部变量。“为什么会这样?”-因为ruby中的块是闭包。但是为什么2rd块可以更改“y”?“为什么会这样?”-因为ruby中的块是闭包。但是为什么2rd块可以更改“y”?这对于test1是有意义的,但是test2呢?看起来“Ruby知道块内发生了什么”,所以y改为20。我说的对吗?谢谢在测试2中,这是因为
y
是在块之前定义的,块中的y
与y
相同。如果删除y=1
并运行代码(尝试),则说明y
是在块之前初始化的,它与块内的y
相同。删除y=1
和[x,y]
将引发异常:“名称错误:未定义的局部变量“y”。只有这样,块才能在块计算中使用先前定义的变量。这里y=1。最多(2){x | 20}
可以工作(但没有多大意义)。这对test1来说是有意义的,但是test2呢?看起来“Ruby知道块内发生了什么”,所以y改为20。我说的对吗?谢谢在测试2中,这是因为y
是在块之前定义的,块中的y
与y
相同。如果删除y=1
并运行代码(尝试),则说明y
是在块之前初始化的,它与块内的y
相同。删除y=1
和[x,y]
将引发异常:“名称错误:未定义的局部变量“y”。只有这样,块才能在块计算中使用先前定义的变量。这里y=1。最多(2){| x | 20}
可以工作(但没有多大意义)。