<<Ruby元编程>>第三章笔记
2014-03-05 10:30
246 查看
1 块是一种控制作用域(scope)的强大手段,作用域指的是哪些代码可以看到哪些变量和方法.
2 只有在调用一个方法时才可以定义一个块.块会被直接传递给这个方法,然后该方法可以用yield关键字回调这个块.
3 块中最后一行代码执行的结果会被作为返回值.
4 在一个方法中,可以向Ruby询问当前的方法调用是否包含快,可以通过Kernel#block_given?()方法来做到:
作用域小结:
1 每个Ruby作用域包含一组绑定,并且不同的作用域之间被作用域门分隔开来:class,module和def.
2 如果要让一两个绑定穿越作用域门,那么可以用方法调用来替代作用域门:用一个闭包获取当前的绑定,并把这个闭包传递给该方法.可以用Class.new()方法代替class,使用Module.new代替module,以及使用Module#define_method()代替def.这就形成了一个扁平作用域,它是闭包中的一个基本概念.如果在一个扁平作用域中定义了多个方法,则这些方法可以用一个作用域门进行保护,并共享绑定,这种技术称为共享作用域.
Object#instance_eval() 方法: 在一个对象的上下文中执行一个块. 可以把传递给instance_eval()方法的块称为一个上下文探针,因为它就像是一个深入到对象中的代码片段,对其进行操作.
可调用对象:
1 一个Proc就是一个转换成对象的块,可以通过把块传给Proc.new方法来创建一个Proc,以后就可以用Proc#call()方法来执行这个由块转换而来的对象:(延迟执行)
2 还有两个内核方法可以把块转换为Proc: lambda()和proc().
3
`想把这个块传递给另外一个方法.
`想把这个块转换为一个Proc.
在这两种情况下,都需要指着那个块说:"我想用这个块" .为了做到这一点,需要给块取一个名字.要将块附加到一个绑定上,可以给这个方法添加一个特殊的参数,这个参数必须是参数列表中的最后一个,且以&符号开头.
&操作符的真正含义:这是一个Proc对象,我想把它当成一个块来使用.去掉&操作符,就能再次得到一个Proc对象.
可调用对象小结
可调用对象是可以执行的代码片段,而且它们有自己的作用域.可调用对象可以有以下几种方式:
1 块:在定义它们的作用域中执行.
2 proc:Proc类的对象,跟块一样,它们也在定义自身的作用域中执行.
3 lambda:也是Proc类的对象,但是它跟普通的proc有细微的区别.它跟块和proc一样都是闭包,因此也在定义自身的作用域中执行.
4 方法:绑定于对象,在所绑定对象的作用域中执行.它们也可以与这个作用域解除绑定,再重新绑定打另一个对象的作用域上.
不同可调用对象的区别:
1 在lambda和方法中,return语句从可调用对象中返回.
2 不同的可调用对象对传入参数数目校验有不同的反应.其中方法处理方式最严格,lambda同样严格,而proc和块则要宽松一些.
不同的可调用对象之间的转换:
1 Proc.new()方法
2 Method#to_proc()方法
3 &操作符
2 只有在调用一个方法时才可以定义一个块.块会被直接传递给这个方法,然后该方法可以用yield关键字回调这个块.
3 块中最后一行代码执行的结果会被作为返回值.
4 在一个方法中,可以向Ruby询问当前的方法调用是否包含快,可以通过Kernel#block_given?()方法来做到:
def a_method return yield if block_given? 'no block' end a_method #=> no block 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()方法的块称为一个上下文探针,因为它就像是一个深入到对象中的代码片段,对其进行操作.
class MyClass def initialize @v = 1 end end obj = MyClass.new obj.instance_eval do puts self #=>#<MyClass:0x23e7a90> puts @v #=> 1 end v = 2 obj.instance_eval{@v = v} obj.instance_eval{puts @v} #=> 2
可调用对象:
1 一个Proc就是一个转换成对象的块,可以通过把块传给Proc.new方法来创建一个Proc,以后就可以用Proc#call()方法来执行这个由块转换而来的对象:(延迟执行)
inc = Proc.new{|x| x + 1} inc.call(2) #=>3
2 还有两个内核方法可以把块转换为Proc: lambda()和proc().
dec = lambda{|x| x - 1} dec.class #=> Proc dec.call(2) #=>1
3
`想把这个块传递给另外一个方法.
`想把这个块转换为一个Proc.
在这两种情况下,都需要指着那个块说:"我想用这个块" .为了做到这一点,需要给块取一个名字.要将块附加到一个绑定上,可以给这个方法添加一个特殊的参数,这个参数必须是参数列表中的最后一个,且以&符号开头.
&操作符的真正含义:这是一个Proc对象,我想把它当成一个块来使用.去掉&操作符,就能再次得到一个Proc对象.
def my_method(&the_proc) the_proc end p = my_method {|name| "hell,#{name}"} puts p.class #=>Proc 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 &操作符
相关文章推荐
- <第三章>Node 学习笔记 |>URL网站解析<|
- <<深入Java虚拟机>>-第三章-垃圾收集器与内存分配策略-学习笔记
- <Xen虚拟化技术>阅读笔记---第三章 Xen信息页
- <<浪潮之巅>>阅读笔记一
- <<Python基础教程>>学习笔记 | 第03章 | 字符串
- <<Python基础教程>>学习笔记 | 第06章 | 抽象
- <<浪潮之巅>>阅读笔记二
- <<Linux内核完全剖析 --基于0.12内核>> 学习笔记 第4章 80x86保护模式及其编程 4.1 80x86系统寄存器和系统指令
- <<JavaScript编程全解>>阅读笔记之javascript基础
- <<Linux内核完全剖析 --基于0.12内核>>学习笔记 第4章 80x86保护模式及其编程 4.6 中断和异常处理
- <<High-Speed Tracking with Kernelized Correlation Filters>> KCF(核化相关滤波)跟踪算法学习笔记
- <<Accelerated C# 2008>>笔记3容器&&数组&&迭代器
- <<C和指针>>看书笔记
- <<Numerical Analysis>>笔记
- <<浪潮之巅>>阅读笔记三
- <<c 专家编程>> 笔记
- <<c 和指针 >> 部分笔记。
- <第四章>Node 学习笔记 |> QueryString 参数处理小利器<|
- <<连载>><<MariaDB Crash Cource>>中文笔记(第三)
- <<JavaScript编程全解>>阅读笔记之函数与闭包