Ruby代码块(Block)
1、什么是代码块
在Ruby中,{}或do...end之间的代码是一个代码块。代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上,由yield关键字调用。例如:
[1,2,3,4,5].each { |i| puts i }[1,2,3,4,5].each do |i| puts i end
块变量:以yield关键字调用block也可以传递参数,block中竖线(|)之间给出的参数名用于接收来自yield的参数。
竖线之间(如上例中的 | i |)的变量被称作块变量,作用和一个正常方法的参数一样
2、{}和do...end优先级不同
在传递一个block时,使用{}传递的block比使用do…end的优先级要高;
为了避免引起歧义,最好使用()将参数括起来。例如:
1.upto 3 do |x|puts x end
是正确的,但是 1.upto 3 {|x| puts x} 编译不通过,应该写成 1.upto(3) {|x| puts x}
原因:
1.upto 3 do…end 中block会传递到upto方法里面,3会作为一个参数传递给upto
1.upto 3 {|x| puts x} 一句会把3当做函数名,将block传递到这个函数,其返回值作为upto方法的参数,所以编译不过,需加()。
3、代码块转化为对象的方法
代码块并不是对象,但可以通过以下三种方法转化为Proc类的对象:
(1)将一个代码块传递给最后一个参数以 & 开始的方法。例:
def meth1(p1, p2, &block)puts block.inspectputs block.call end meth1(1, 2) { "This is a block" }
(2)使用Proc.new方法,代码块作为参数:
block = Proc.new { "a block" }
(3)调用Kernel.lambda方法:
block = lambda { "a block" }
前两种方法是等价的,会检查参数的数量,但Proc.new 创建的对象不会;
用 lambda 和 Proc.new 生成的 Proc 对象之间也是有差别的。这个差别与 return 关键字相关。lambda 中的 return 从 lambda 返回。而 Proc.new 中的 return 从外围方法返回。
# 执行后"Never come here"不会被输出,执行p.call相当于在test_proc方法内执行了return语句。 def test_procp = Proc.new { return 1 } # test_proc方法返回p.call puts "Never come here" # 永远不会执行到 end# 使用lambda生成的Proc对象执行call方法调用时,return表示从lambda包围得块内返回。 def test_lambdap = lambda { return 1 }result = p.callputs "The value is: #{result}" end
Note:在一个代码块中执行next语句会导致代码块返回。返回值就是next语句后带的参数。如果next后没有参数,那么返回值为nil。
def meth2result = yieldp "The block result is #{result}" endputs meth2 { next 9 } pr = Proc.new { next 100 } puts pr.call pr = lambda { next } puts pr.call执行结果为: The block result is 9 100 nil
4、yield关键字调用代码块
在方法中可以使用 yield 来执行代码块的内容,就好像传入的代码块是这个方法的一部分一样。每当碰到一个 yield,代码块的内容就会被执行一次,代码块执行结束后,程序会回到 yield 的那一行继续向下执行。
使用 yield 可以向代码块传递参数,也可以从代码块取回返回值,返回值就是代码块中最后一个表达式的值。
def fibonacii(max)f1, f2 = 1, 1while f1 <= maxyield f1f1, f2 = f2, f1+f2end endfibonacii(1000) { |f| print f, " " }执行结果为: 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
(1)在这个例子中,yield 接收一个参数f1,这个参数将会在执行的时候传递给指定的代码块。在代码块中,接收的参数使用两个竖线括起来放在代码块的头部。
(2)另外,在使用 yield 关键字调用代码块时,如果传入的参数个数少于代码块中定义的参数个数,那么没有传递的参数会自动转为nil。反之,则最后一个参数为一个数组,该数组包含了剩余的传递参数;
转载于:https://www.cnblogs.com/zs-note/p/3347035.html
Ruby代码块(Block)相关推荐
- Objective-C语法之代码块(block)的使用
代码块本质上是和其它变量相似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你能够像调用其它标准函数一样,传入參数数,并得到返回值. 脱字符(^)是块的语法标记.依照我们熟悉的參数语法规约所定 ...
- ios 添加block 类别_iOS 关于Block代码块的详解
概述 block 上图就是一个block简单使用,它包括了block的声明.赋值实现.调用 三个部分,其中,实现部分可以看作是一种匿名函数:跟函数一样,block也是需要调用才能执行内部代码的:赋值的 ...
- [译] Ruby 2.6 String的split 方法支持代码块执行
本博客系列翻译自 Bigbinary 的 Ruby 2.6 系列, 已得到作者允许.Ruby 2.6.0-preview2 现已发布. 在Ruby 2.6之前, String#split 方法会返回一 ...
- iOS中得block代码块的定义及使用
现在的无论是框架还是项目中,越来越多的使用block代码块. 个人觉得:第一可以使代码看起来更简单明了,第二可以取代以前的delegate使代码的逻辑看起来更清晰. 借一张图表达基本定义: (1)最基 ...
- Block代码块中使用局部变量注意点
第一次写代码遇到报这个错,实在是想不通为什么,按常理应该是不会有问题,报错的呀??纠结了一会之后只好仔细查看报错原因咯,原来是: 当我们在block代码块中使用局部变量时,就会很容易出现如图的错误. ...
- iOS - OC Block 代码块
前言 Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递.Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.Block 是 C 语言的,类似于一个 ...
- 迭代器、代码块、闭包
迭代器each 是数组类的一个方法:大括号{ }里的代码是代码块,简称块.你可以用大括号{ }将代码组织成块,也可以用 do-end将代码组织成块.大括号{ }的优先级高于do-end. 我们来写一个 ...
- [ios开发基础之]代码块
iOS4引入了一个新特性,支持代码块的使用, 这将从根本上改变你的编程方式.代码块是对C语言的一个扩展,因此在Objective-C中完全支持.如果你学过Ruby,Python或Lisp编程 语言,那 ...
- hbuilder边框代码是什么_HBuilder CSS 自定义代码块
1 =begin2 本文档是CSS代码块的编辑文件.注意不要把其他语言的设置放到css里来.3 HBuilder可使用ruby脚本来编辑代码块和增强操作命令.4 1.编辑代码块5 如果要新增一个代码块 ...
- Xcode快捷键及代码块
2017-02-16 吴白 CocoaChina 手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥 ...
最新文章
- Cacti部署及常用插件安装(2)
- MongoDB 小试牛刀
- Android动画模式
- 后台服务系统之Dubbo协议
- nginx负载均衡的简单实现
- 如何开始DDD(完)
- React 入门手册
- 【CodeForces - 255A】Greg's Workout (水题)
- golang学习之旅(1)
- 作者:黎建辉(1973-),男,博士,中国科学院计算机网络信息中心研究员、博士生导师。...
- python抽取指定url页面的title_Python使用scrapy爬虫,爬取今日头条首页推荐新闻
- Java基础学习总结(170)——Java8并发工具类CompletableFuture学习总结
- oracle 10g 创建只读用户语法
- lintcode:子数组之和为0
- 时间:2014年3月28日15:51:27框架改进 增加日志功能log类
- 35+ 个 Java 代码性能优化总结
- 【JAVA】poi操作,excel读取数据。
- 截图工具-Excel加载宏(图片大小可调)
- rpm、lpm是什么意思?
- (已解决)报错:collect2 error ld returned 1 exit status