块
yield用法
其他编程语言中被称为闭包。 它由一组代码组成,它们始终用大括号括起来,或者在do..end之间书写。 大括号语法总是具有比do..end语法更高的优先级。也就是说大括号优先级高,do..end优先级低
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
def test
puts "在 test 方法内"
yield
puts "你又回到了 test 方法内"
yield
end
test {puts "你在块内"}
这里的块得放在函数后面,然名变量名字必须一样
还可以传递带有参数的 yield 语句
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
def test
yield 5
puts "在 test 方法内"
yield 100
end
test {|i| puts "你在块 #{i} 内"}
想要传递多个参数,那么 yield 语句如下所示:
yield a, b
此时,块如下所示:
test {|a, b| statement}
BEGIN 和 END 块
每个 Ruby 源文件可以声明当文件被加载时要运行的代码块(BEGIN 块),以及程序完成执行后要运行的代码块(END 块)
#!/usr/bin/ruby
BEGIN {
# BEGIN 代码块
puts "BEGIN 代码块"
}
END {
# END 代码块
puts "END 代码块"
}
# MAIN 代码块
puts "MAIN 代码块"
输出结果
BEGIN 代码块
MAIN 代码块
END 代码块
块变量
可以在块参数外部和内部使用相同的变量,看看下面的例子。
#!/usr/bin/ruby
x = "Outer variable"
3.times do |x|
puts "Inside the block: #{x}"
end
puts "Outside the block: #{x}"
#输出结果
=begin
Inside the block: 0
Inside the block: 1
Inside the block: 2
Outside the block: Outer variable
=end
符号参数(&块)
&
块是一种将参考(而不是局部变量)传递给块的方法。这里,块之后的&
只是一个引用的名字,任何其他的名字都可以用它来代替。
#!/usr/bin/ruby
def met(&block)
puts "This is method"
block.call
end
met { puts "This is &block example" }
=begin
This is method
This is &block example
=end
这里,met
方法中的块变量是对块的引用,它使用call
来执行。 调用方法与yield
方法相同
使用默认值初始化对象
Ruby有一个初始化器,称为yield(self)
。 在这里,self
是被初始化的对象。yield(self)是类的初始化器(构造函数)中使用的一种常见技术。
当你在一个类的初始化器中调用yield(self)
时,它会执行与当前对象相关联的块代码。这允许你在对象实例化的过程中执行一些自定义的逻辑或初始化操作,同时让块代码能够访问当前对象的实例变量和方法。
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
yield(self) if block_given? # 调用块代码,并传递当前对象
end
end
person = Person.new("John", 25) do |p|
puts "Custom initialization for #{p.name}"
# 执行额外的自定义逻辑或初始化操作
end
Person
类具有name
和age
实例变量,并定义了一个初始化器。当创建一个Person
对象时,可以传递一个块代码给初始化器,并使用yield(self)
调用该块代码。块代码可以访问传递给它的Person
对象,以便执行自定义的初始化操作。
通过使用yield(self)
,你可以在对象实例化的过程中以一种灵活的方式执行额外的代码,并与当前对象进行交互。这对于执行一些初始化逻辑、设置默认值或注册回调等操作非常有用。
注意:attr_accessor :name, :age
是Ruby中的一个简便方法,用于定义对象的属性(属性访问器)。
attr_accessor
是一个Ruby的关键字,它接受一个或多个属性名作为参数,并为每个属性生成对应的读取器(getter)和写入器(setter)方法。
在这个特定的例子中,attr_accessor :name, :age
会为类或模块中的实例变量@name
和@age
生成以下方法:
- 读取器方法(getter):生成一个方法来获取属性的值。对于属性
:name
,生成的方法名为name
,通过调用object.name
来获取@name
的值。对于属性:age
,生成的方法名为age
,通过调用object.age
来获取@age
的值。 - 写入器方法(setter):生成一个方法来设置属性的值。对于属性
:name
,生成的方法名为name=
,通过调用object.name = new_value
来设置@name
的值为new_value
。对于属性:age
,生成的方法名为age=
,通过调用object.age = new_value
来设置@age
的值为new_value
。