rails on ruby,ruby on rails 之代码块(一)

代码块
终于来到代码块的知识,其实这个函数式编程语言中比较晦涩难懂的一部分。其实,我们在举method_missing方法例子的时候已经用过一次块。这里再举一个更直观的例子:

blocks/basics_failure.rb
def a_method(a,b)
   a + yeild(a, b)
end
  a_method(1,2) { |x, y| (x+y)*3 } #=>10  

代码块可以用大括号定义,也可以用do…end关键字定义,通常,只用一行的块用的是大括号,而多行的块用的是do…end。 只用在调用一个方法时,才可以定义一个块。 这里的yeild主要是起到一个占位的作用。

在一个方法中,我们还可以询问当前的方法调用是否包含块。可以用过Kernel#block_given?方法做到。

def a_method
   return yield if block_given?
   'no block'
end   

a_method
a_method { 'here 's a block' }

代码块闭包
代码块不是浮在空中的,它不可能独立地运行。运行代码需要一个执行环境:局部变量,实例变量,self等。由于这些东西都是绑定在对象上的名字,所以把它们简称为绑定,代码块之所以可以运行,是因为它既包含代码,也包含一组绑定。

当块被传入一个方法时,它会带着这些绑定一块进入该方法:

blocks/blocks_and_bindings.rb
def my_method
   x = "Goodbye"
   yield("cruel")
end

x = "Hello" 
my_method { |y| "#{x}, #{y} world" } # => "Hello, cruel world"   

在上面的例子中,代码块的绑定中包含一个名为x的变量。虽然在方法中也定义了一个变量x,但代码块看到但x还是在代码块定义时绑定但x,方法中的x对这个代码块来说是不可见的。
我们还可以在代码块内部定义额外的绑定,但是这些绑定在代码块结束时就消失了:

blocks/block_local_vars_failure.rb
def just_yield
    yield
end

top_level_variable = 1

just_yield do
   top_level_variable += 1
   local_to_block = 1
end

top_level_variable  #=>2 
local_to_block    #=>Error!   

基于这样的特性,我们将代码块称之为闭包。换句话说,代码块可以获取局部绑定,并一直带着它们。

猜你喜欢

转载自blog.csdn.net/zyhmz/article/details/80149946