ruby中的可调用对象--proc和lamdba
ruby中将块转变成对象的三种方法
ruby中的大部分东西都是对象,但是块不是。那么,如果你想存下来一个块,方便以后使用,你就需要一个对象。ruby中有三种方法,把块转换成可以利用的对象。
- Proc.new
- lambda #kernel的方法
- proc #等价于Proc.new
这三种很类似,如下:
inc = Proc.new{|x|x+1}
p inc.call(1) inc = proc{|x|x+1}
p inc.call(1) dec = lambda{|x|x-1}
p dec.class
p dec.call(1)
输出
2
2
Proc
0
ruby中把Proc对象转变成块
说完了把块变成对象,那么怎么把对象再变成块呢?那就要用到&操作符
先说一下ruby中调用块的方法
ruby有一个yield关键字,在方法用yield语句可以调用一个块。
如下:
def square
yield(2)
end
square{|x|puts "#{x*x}"}
输出
4
方法中使用了yield语句,带有参数2,然后在调用方法时,带着一个块,块中也有一个参数x。执行到yield语句的时候,把块代进去执行。
但是用yield有两种情况下不适用:
- 想把这个块传给另一个方法
- 想把这个块转换成一个Proc
这两种情况下,都要把块取一个名字。通过这个名字来进行调用块。这个块做参数的时候,必须是参数列表的最后一个,并且以&开头。
如下:
def square
yield(2)
end
def show(&block)
square(&block)
end
show{|x|puts "#{x*x}"}
输出
4
如例子所示,在调用show的时候,如果没有加一个块,&block就会是nil。那么在调用square的时候将失败。
&的含义:&表示紧接着的变量是一个Proc对象,但是要把它当成一个块来使用。如果去掉&,就是再次得到Proc对象。
如下:
def method(&block)
block
end a = method{p "hello world"}
p a.class
输出
Proc
Proc.new(proc)和lambda的区别
Proc.new和lambda有两个重要的区别:一个和return关键字有关,一个和参数检验有关。
在return上的不同
def square
p = Proc.new{|x|return x}
result = p.call(2)
return result*result
end
p square def square1
l = lambda{|x|return x}
result = l.call(2)
return result*result
end
p square1
输出2 4
Proc.new是从定义proc的作用域返回——如上示例,Proc定义在square方法中,因此Proc.new中定义的return x,是作为这个方法的返回结果。最后一句return result*result没有执行。
lamdba是从仅仅从lambda中返回。和我们正常的逻辑一样。返回result =2 ,然后再执行最后一句。
检查参数方式不同
如下:
p = Proc.new{|a,b|[a,b]}
p p.call(1,2)
p p.call(1,2,3)
p p.call(1) l = lambda{|a,b|[a,b]}
p l.call(1,2)
p l.call(1,2,3)
p l.call(1)
输出
[1, 2]
[1, 2]
[1, nil]
[1, 2]
a.rb:6:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError)
from a.rb:8:in `call'
from a.rb:8:in `<main>'
如输出结果所示,Proc.new在参数数目不对的时候会自动调整,而lambda会报错。
总结:在ruby调用一个方法时,可以选择是否提供一个代码块,这样可以让方法匿名调用该代码块,用yield。
Proc.new(proc)和lamdba方法都可以把块转化成Proc对象,但是选择的时候一般优先lambda。因为lambda对参数数量要求严格,而且调用return只从代码中返回。除非要用到Proc.new的一些特殊功能。
可以用Proc#lambda?()方法来检测Proc是不是lambda。
ruby中的可调用对象--proc和lamdba的更多相关文章
- ruby中的可调用对象--方法
上一篇讲了ruby中的可调用对象proc和lambda,他们都是块转换成的对象.ruby中的可调用对象还有方法.通过使用method方法,并且以方法名作为参数(字符串或者符号),就可以得到一个方法对象 ...
- C++中的可调用对象
在C++中,常常会利用函数来简化程序流程.函数的存在使得C++整体更加“模块化”,因而也使得代码可读性大大提高. 在C++程序中,常常会很灵活地调用函数来实现不同的功能与目的(函数重载.继承多态等等) ...
- Delphi 中的DLL 封装和调用对象技术(刘艺,有截图)
Delphi 中的DLL 封装和调用对象技术本文刊登2003 年10 月份出版的Dr.Dobb's 软件研发第3 期刘 艺摘 要DLL 是一种应用最为广泛的动态链接技术但是由于在DLL 中封装和调用对 ...
- 理解Ruby中的作用域
作用域对于Ruby以及其它编程语言都是一个需要理解的至关重要的基础知识.在我刚开始学习ruby的时候遇到很多诸如变量未定义.变量没有正确赋值之类的问题,归根结底是因为自己对于ruby作用域的了解不够, ...
- ruby中的方法查找
ruby中的方法调用都是 对象.方法 的形式,那么对象如何找到这个方法呢? 首先必须了解祖先链的概念,祖先链就是从一个类开始,到它的父类,再到父类的父类...一直到最终的起点(ruby中是BasicO ...
- C++之可调用对象
C++中的可调用对象分为以下几种: 函数 函数指针 lambda表达式 bind创建的对象 重载了函数调用运算符(即“()”)的类 函数.函数指针不再介绍.lambda表达式与bind创建的类参考—— ...
- Ruby中Block, Proc, 和Lambda
Block Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3]. ...
- ruby中Block, Proc 和 Lambda 浅析
Block 与Proc的区别: Block是代码块,Proc是对象: 参数列表中最多只能有一个Block, 但是可以有多个Proc或Lambda; Block可以看成是Proc的一个类实例. Proc ...
- ruby中如何调用与局部变量同名的私有方法
如果ruby中一个局部变量名和私有方法名同名的话,默认该名称被解释为变量而不是方法: x=10; def x;puts "what?" end 当你输入x实际不能执行x方法.解释器 ...
随机推荐
- JSON美化输出
echo '{"a": 1, "b": 2}' | python -m json.tool 转自: http://blog.csdn.net/chosen0ne ...
- db2 将逗号分隔数据转换为多值IN列表
将逗号分隔数据转换为多值IN列表 2010-03-15 11:16:59| 分类: 数据库技术|举报|字号 订阅 下载LOFTER我的照片书 | 原文:http://book.cs ...
- mysql查询各种类型的前N条记录
mysql查询各种类型的前N条记录,将3改为N(需查询条数)即可 (select * from event_info where event_type = 1 limit 3)union all( ...
- 一道money计算题引发的思考
网友提出一个问题如下 是小学和中学时候学到了增长折线问题,有点像数学问题,不过这个要求用编程来实现,恐怕还是有些逻辑要处理的,话不多说看代码吧 我给出的代码如下 代码清单: <?php func ...
- 自定义控件_StickyNavLaout
关注我一.View结构原理1.extends linearLayout 继承想要用的布局,首先完成布局的填充在 onFinishInflate 方法中 findViewById(); @Overrid ...
- 使用jq实现打印机的效果
本例中使用的是jq和es6的语法,代码如下: html: <div id="box"> this is test <br/> 这是测试用的 </di ...
- 第4章 Vim编辑器与Shell命令脚本
章节简述: 本章节将教给您如何使用Vim编辑器来编写文档.配置主机名称.网卡参数以及yum仓库 ,熟练使用各个模式和命令快捷键. 我们可以通过Vim编辑器将Linux命令放入合适的逻辑测试语句(if. ...
- 解决 Unable to load native-hadoop library for your platform
安装hadoop启动之后总有警告:Unable to load native-hadoop library for your platform... using builtin-java classe ...
- [黑金原创教程] FPGA那些事儿《设计篇 I》- 图像处理前夕
简介 一本为入门图像处理的入门书,另外还教你徒手搭建平台(片上系统),内容请看目录. 注意 为了达到最好的实验的结果,请准备以下硬件. AX301开发板, OV7670摄像模块, VGA接口显示器, ...
- 【BZOJ3648】寝室管理 树分治
[BZOJ3648]寝室管理 Description T64有一个好朋友,叫T128.T128是寄宿生,并且最近被老师叫过去当宿管了.宿管可不是一件很好做的工作,碰巧T128有一个工作上的问题想请T6 ...