ruby的Proc和代码块(Block)

    在ruby中代码块是在大括号和do-end中间的部分,代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上。代码块的内容并不会被马上执行,当执行到被调用的方法时,解释器的运行时环境会记住代码块出现的现场,然后执行被调用的方法。

[1,2,3,4,5].each { |i|
   puts i
}

[1,2,3,4,5].each do |i|
   puts i
end

一般的使用习惯是:(to-do 具体解释)

当关心边际(side effect)效应时使用 do/end。

当关心返回结果应时使用大括号

****** {} 和 do end 前者优先级高。

Proc类和代码块的关

代码块并不是对象,但可以方便的转化为Proc类的对象。有三种转化的方法:

将一个代码块传递给最后一个参数以&开始的方法不是很明白?????

def meth1(p1, p2, &block)

     puts block.inspect

     puts block.call

end

meth1(1, 2) { "This is a block" }

② 使用Proc.new方法,后边的参数为一个代码块:

block = Proc.new { puts "a block" } # 代码不会运行

block.call    #现在我们调用Proc存放的代码

#结果: a block

③ 调用Kernel.lambda方法:

      block = lambda { "a block" }

前两种方法是等价的,而第三种方法,用 lambda 生成的 Proc 对象和用 Proc.new 生成的 Proc 对象之间是有差别的。这是一个微妙的差别,这个差别与 return 关键字相关。lambda 中的 return 从 lambda 返回。而 Proc 中的 return 从外围方法返回。

可以看以下两个例子:

def test_proc

   p = Proc.new { return 1 }

   p.call

   puts "Never come here"

end

test_proc    #=> 1

执行后"Never come here"不会被输出,执行p.call相当于在test_proc方法内执行了return语句既是在Proc 中的 return 从外围方法返回;

def test_lambda

   p = lambda { return 1 }

   result = p.call

   puts "The value is: #{result}"

end

test_lambda

执行后的结果为:

The value is: 1 

可见使用lambda生成的Proc对象执行call方法调用时,return表示从lambda包围的块内返回。return 从 lambda 返回;

向Proc和Block中传递参数    (向Proc和Block中传递参数的方式是一样的)

def dumb_hello_world_test
  yield(5)
end
dumb_hello_world_test {|i| puts i * 2 }
# => 10

my_silly_proc = Proc.new {|name| puts name.upcase }
my_silly_proc.call("August Lilleaas")
# => "AUGUST LILLEAAS"


 

 

 

你可能感兴趣的:(Ruby,lambda)