方法内/外的Ruby块变量范围

方法内/外的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] 在块外部创建的变量在块中可用。为什么会这样?这就是如何定义局部变量的范围。局部变量可以渗透到块中,但不能渗透到方法定义中。这就是局部变

我得到了以下不同的结果:

测试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
  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
    无关。这是因为块中
    y
    的范围仅限于块。Ruby只能得到块返回的内容,而不能得到块内部发生的事情
  • 块确实返回块中
    y
    的值,但这只是因为
    y=10
    是块中执行的最后一条语句。该语句的执行返回
    10
    ,因此块返回
    10
    。包含
    y=10的块;7
    7
    将被返回
  • myblock
    中的变量
    y
    未捕获
    yield(x)
    的值,因此该值无效。1
一个鲜为人知的事实是Ruby实际上将这些值发射到了外层空间

这表明这里发生了三件事:

  • 块中的
    y
    myblock
    中的
    y
    无关。这是因为块中
    y
    的范围仅限于块。Ruby只能得到块返回的内容,而不能得到块内部发生的事情
  • 块确实返回块中
    y
    的值,但这只是因为
    y=10
    是块中执行的最后一条语句。该语句的执行返回
    10
    ,因此块返回
    10
    。包含
    y=10的块;7
    7
    将被返回
  • myblock
    中的变量
    y
    未捕获
    yield(x)
    的值,因此该值无效。1

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}
可以工作(但没有多大意义)。