Ruby 具有仅块作用域的块参数
一本书说,即使程序中的其他地方存在另一个同名的变量,也可以有一个作用域仅限于一个块的变量。您可以使用Ruby 具有仅块作用域的块参数,ruby,Ruby,一本书说,即使程序中的其他地方存在另一个同名的变量,也可以有一个作用域仅限于一个块的变量。您可以使用在垂直管道内此块变量之前 但我得到了相同的结果,无论是否使用块变量x,如下所示: def block_local_variable x = "Original x!" 3.times do |i;x| x = i puts "x in the block is now #{x}" end puts "x after the block
代码>在垂直管道内此块变量之前
但我得到了相同的结果,无论是否使用块变量x
,如下所示:
def block_local_variable
x = "Original x!"
3.times do |i;x|
x = i
puts "x in the block is now #{x}"
end
puts "x after the block ended is #{x}"
end
block_local_variable
及
就我所知,没有区别
x in the block is now 0
x in the block is now 1
x in the block is now 2
x after the block ended is Original x!
原始的x
仍受保护,不受更改
我错了吗?这个特定的代码片段可能会有相同的结果,但从更广泛的角度来看,内容确实不同,对吗?这里有一个更简单的方法来解释您的书试图告诉您的内容
1) 在创建块时,块可以看到周围范围中的所有变量。以下是一个例子:
y = 'hello world' #<-+ <--- Everything outside the block is part of the surrounding scope
# |
func = lambda do #<-|---- Block created now!
puts y #---------+
end
func.call #=>hello world
请注意,分号后面列出的变量不是参数变量——func接受0个参数。分号只是告诉ruby创建分号后面指定的变量
如果您将这些规则应用到示例中,您应该意识到,为了测试分号是如何工作的,在这两个示例中的块内部,您必须指定一个存在于块外部的变量。你的第二个例子没有做到这一点。此外,第二个示例指定了块参数变量x。一个块参数变量总是隐藏一个同名的外部变量(在ruby 1.8.7中不是这样),所以你马上就搞错了这个例子:在块内部,对x的赋值就是对x参数变量的赋值
记住两件事:
块参数变量隐藏具有相同名称的外部变量(Ruby 1.8.7-)除外
“分号变量”隐藏具有相同名称的外部变量
y = 'hello world' #<-+ <--- Everything outside the block is part of the surrounding scope
# |
func = lambda do #<-|---- Block created now!
puts y #---------+
end
func.call #=>hello world
y = 'hello world'# <-+
# |
func = lambda do # <-|------Block created now!
puts y #----------+
end
def do_stuff(f) #<--- The def keyword creates a new scope.
#----------------------+ <-- The scope surrounding the block.
y = 10 # |
f.call #=>puts y <---Block executed now!
#----------------------+
end
do_stuff(func) #=>hello world
y = 'hello world'# <-----+
# |
func = lambda do # |
y = 'goodbye' #-------+
end
func.call
puts y #=>goodbye
y = 'hello world'
func = lambda do |;y| #New y variable created, which 'hides' the outer y.
y = 'goodbye' #Assignment to the 'local' (or block) y.
end #Block y is destroyed--'unhiding' the outer y.
func.call
puts y #=>hello world