本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、块的表示
Ruby的块又称为代码块,它总是从与其具有相同名称的函数调用,在同名函数中使用yield调用
以下是一个块的简单定义
def block
do
end
block{
do1
do2
...
}
块不能被单独定义,否则报错,它总是与同名函数一起出现
block{
puts "Inside the block 1"
}
undefined method `block' for main:Object (NoMethodError)
二、块的调用
yield
如上所示,如果要调用块,使用yield
若省略了yield,函数被调用了但是没有进块内
def block
puts "Inside the function"
puts "Inside the function"
end
block{
puts "Inside the block"
}
Inside the function
Inside the function
如果是需要传参的函数,同理
def block(a)
puts "Inside the function #{a}"
yield
puts "Inside the function #{a}"
end
block(1){
puts "Inside the block"
}
Inside the function 1
Inside the block
Inside the function 1
可以定义多个同名块
def block(a)
puts "Inside the function #{a}"
yield
puts "Inside the function #{a}"
end
block(1){
puts "Inside the block 1"
}
puts
block(2){
puts "Inside the block 2"
}
Inside the function 1
Inside the block 1
Inside the function 1
Inside the function 2
Inside the block 2
Inside the function 2
因此:如果定义了块,默认调用一次同名的函数,如果出现yield,则进入块内
argv.call
除了yield还支持&argv传入块,然后使用argv.call调用
def test(i,&block)
puts "Inside the function #{i}"
block.call
end
test(1){
puts 'Inside the block'
}
Inside the function 1
Inside the block
三、块传参
如果要对块传入参数,需要在yield跟随参数,并且在块使用竖线表示接收传参
以下是错误的
def block(a)
puts "Inside the function #{a}"
yield
puts "Inside the function #{a}"
end
block(1){
puts "Inside the block #{a}"
}
Inside the function 1
script.rb:11:in `block in <main>': undefined local variable or method `a' for main:Object (NameError)
from script.rb:6:in `block'
from script.rb:10:in `<main>'
Exited with error status 1
以下是正确将参数传入块的操作,多个参数用逗号分隔即可
def block(a)
puts "Inside the function #{a}"
yield a
puts "Inside the function #{a}"
end
# |a|表示接收参数
block(1){|a|
puts "Inside the block #{a}"
}
Inside the function 1
Inside the block 1
Inside the function 1
call传参也是同理
def test(i,&block)
puts "Inside the function #{i}"
block.call(i)
end
test(1){|i|
puts "Inside the block #{i}"
}
四、特殊块——BEGIN和END
Ruby 源文件可以声明当文件被加载时要运行的代码块(BEGIN 块),以及程序完成执行后要运行的代码块(END 块)。一个程序可以包含多个 BEGIN 和 END 块。BEGIN 块按照它们出现的顺序执行。END 块按照它们出现的相反顺序执行。
BEGIN {
puts "BEGIN 1"
}
BEGIN {
puts "BEGIN 2"
}
puts "MAIN 3"
END {
puts "END 5"
}
END {
puts "END 4"
}
BEGIN 1
BEGIN 2
MAIN 3
END 4
END 5