block
Block(块)为由大括号{}或者关键字do/end包围的代码段。
两种形式没什么区别,除了前者的运算优先级高于后者。
当前的Ruby风格倾向于使用{},因为可以把代码放到一行中,而do/end会跨越多行:
some_array.each { |value| puts value * 3}
sum = 0 other_array.each do |value| sum += value puts value / sum end
Block和匿名函数体有几分相似。Block可以像方法那样带参数,不同的是参数出现在block的起始位置,由一对|包围。和方法一样,block仅在Ruby第一次看到它时才会执行。
Block仅出现在方法调用之后。如果方法带参数,则block出现在参数后面。
某种程度上,你可以把block看做方法的一个额外的参数。
下面例子为计算Array中各数的平方和:
sum = 0 square = "square" value = "value" [1,2,3,4].each do |value| square = value * value sum += square end puts sum # => 30 puts square # => 16 puts value # => "value"
上述代码为Ruby1.9.2版本运行结果。可以看出:
1. block的参数作用域仅限于block内,且与外部相同名字变量没有关系;不会互相影响;
2. 如果block内部有和外部同名变量,则block内部对变量的改变即是对block外部变量的修改;
2中描述的情况有些时候不是我们期望的,我们有时候并不会想到在某个block内部把我们某个变量值给”悄悄”改变了. 解决办法是定义一个block局部变量,具体做法是把变量声明放在|对中、block参数之后,block参数与block局部变量间由;隔开,如:
sum = 0 square = "square" value = "value" [1,2,3,4].each do |value ; square| # NOTICE HERE square = value * value sum += square end puts sum # => 30 puts square # => "square" puts value # => "value"