『Ruby』块(Block)

114 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、块的表示

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