zoukankan      html  css  js  c++  java
  • <<Ruby元编程>>第三章笔记

    1 块是一种控制作用域(scope)的强大手段,作用域指的是哪些代码可以看到哪些变量和方法.
    2 只有在调用一个方法时才可以定义一个块.块会被直接传递给这个方法,然后该方法可以用yield关键字回调这个块.
    3 块中最后一行代码执行的结果会被作为返回值.
    4 在一个方法中,可以向Ruby询问当前的方法调用是否包含快,可以通过Kernel#block_given?()方法来做到:

    1 def a_method
    2  return yield if block_given?
    3  'no block'
    4 end
    5 
    6 a_method    #=> no block
    7 a_method {"here's a block!"} #=> here's a block!

    作用域小结:
    1 每个Ruby作用域包含一组绑定,并且不同的作用域之间被作用域门分隔开来:class,module和def.
    2 如果要让一两个绑定穿越作用域门,那么可以用方法调用来替代作用域门:用一个闭包获取当前的绑定,并把这个闭包传递给该方法.可以用Class.new()方法代替class,使用Module.new代替module,以及使用Module#define_method()代替def.这就形成了一个扁平作用域,它是闭包中的一个基本概念.如果在一个扁平作用域中定义了多个方法,则这些方法可以用一个作用域门进行保护,并共享绑定,这种技术称为共享作用域.


    Object#instance_eval() 方法: 在一个对象的上下文中执行一个块. 可以把传递给instance_eval()方法的块称为一个上下文探针,因为它就像是一个深入到对象中的代码片段,对其进行操作.

     1 class MyClass
     2  def initialize
     3   @v = 1
     4  end
     5 end
     6 
     7 obj = MyClass.new
     8 obj.instance_eval do
     9  puts self     #=>#<MyClass:0x23e7a90>
    10  puts @v    #=> 1
    11 end
    12 
    13 v = 2
    14 obj.instance_eval{@v = v}
    15 obj.instance_eval{puts @v}  #=> 2

    可调用对象:
    1 一个Proc就是一个转换成对象的块,可以通过把块传给Proc.new方法来创建一个Proc,以后就可以用Proc#call()方法来执行这个由块转换而来的对象:(延迟执行)

    1 inc = Proc.new{|x| x + 1}
    2 inc.call(2)  #=>3

    2 还有两个内核方法可以把块转换为Proc:  lambda()和proc().

    1 dec = lambda{|x| x - 1}
    2 dec.class #=> Proc
    3 dec.call(2) #=>1

    3
    `想把这个块传递给另外一个方法.
    `想把这个块转换为一个Proc.
    在这两种情况下,都需要指着那个块说:"我想用这个块" .为了做到这一点,需要给块取一个名字.要将块附加到一个绑定上,可以给这个方法添加一个特殊的参数,这个参数必须是参数列表中的最后一个,且以&符号开头.
    &操作符的真正含义:这是一个Proc对象,我想把它当成一个块来使用.去掉&操作符,就能再次得到一个Proc对象.

    1 def my_method(&the_proc)
    2  the_proc
    3 end
    4 p = my_method {|name| "hell,#{name}"}
    5 puts p.class #=>Proc
    6 puts p.call("bill") #=> hello bill

    可调用对象小结

    可调用对象是可以执行的代码片段,而且它们有自己的作用域.可调用对象可以有以下几种方式:
    1 块:在定义它们的作用域中执行.
    2 proc:Proc类的对象,跟块一样,它们也在定义自身的作用域中执行.
    3 lambda:也是Proc类的对象,但是它跟普通的proc有细微的区别.它跟块和proc一样都是闭包,因此也在定义自身的作用域中执行.
    4 方法:绑定于对象,在所绑定对象的作用域中执行.它们也可以与这个作用域解除绑定,再重新绑定打另一个对象的作用域上.

    不同可调用对象的区别:
    1 在lambda和方法中,return语句从可调用对象中返回.
    2 不同的可调用对象对传入参数数目校验有不同的反应.其中方法处理方式最严格,lambda同样严格,而proc和块则要宽松一些.

    不同的可调用对象之间的转换:
    1 Proc.new()方法
    2 Method#to_proc()方法
    3 &操作符

  • 相关阅读:
    HDU 2089 不要62
    HDU 5038 Grade(分级)
    FZU 2105 Digits Count(位数计算)
    FZU 2218 Simple String Problem(简单字符串问题)
    FZU 2221 RunningMan(跑男)
    FZU 2216 The Longest Straight(最长直道)
    FZU 2212 Super Mobile Charger(超级充电宝)
    FZU 2219 StarCraft(星际争霸)
    FZU 2213 Common Tangents(公切线)
    FZU 2215 Simple Polynomial Problem(简单多项式问题)
  • 原文地址:https://www.cnblogs.com/leaf526/p/3581879.html
Copyright © 2011-2022 走看看