Ruby 块(Blocks)
示例
块是括在括号之间的代码块{}(通常用于单行块)或do..end(用于多行块)。
5.times { puts "Hello world" } # recommended style for single line blocks
5.times do
print "Hello "
puts "world"
end # 多行块的推荐样式
5.times {
print "hello "
puts "world" } # 不会引发错误,但是不建议注意:花括号的优先级高于do..end
屈服
可以在单词和方法内部使用块yield:
def block_caller
puts "some code"
yield
puts "other code"
end
block_caller { puts "My own block" } # the block is passed as an argument to the method.
#一些代码
#我自己的街区
#其他代码请注意,如果yield不加阻塞地调用它会引发LocalJumpError。为此,ruby提供了另一种方法,block_given?该方法可让您在调用yield之前检查是否已通过块
def block_caller
puts "some code"
if block_given?
yield
else
puts "default"
end
puts "other code"
end
block_caller
# 一些代码
# 默认
# 其他代码
block_caller { puts "not defaulted"}
# 一些代码
# 没有违约
# 其他代码yield也可以为块提供参数
def yield_n(n)
p = yield n if block_given?
p || n
end
yield_n(12) {|n| n + 7 }
#=> 19
yield_n(4)
#=> 4尽管这是一个简单的示例,但yield对于允许直接访问另一个对象的上下文中的实例变量或评估而言,这可能非常有用。例如:
class Application
def configuration
@configuration ||= Configuration.new
block_given? ? yield(@configuration) : @configuration
end
end
class Configuration; end
app =Application.newapp.configuration do |config|
puts config.class.name
end
# 组态
#=> nil
app.configuration
#=> #<Configuration:0x2bf1d30>如您所见,yield以这种方式使用使代码比连续调用更具可读性app.configuration.#method_name。相反,您可以在包含代码的块内执行所有配置。
变数
块的变量是块的局部变量(类似于函数的变量),它们在执行块时消失。
my_variable = 8
3.times do |x|
my_variable = x
puts my_variable
end
puts my_variable
#=> 0
# 1
# 2
# 8块无法保存,一旦执行就会死亡。为了保存块,您需要使用procs和lambdas。