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)相关推荐

  1. Objective-C语法之代码块(block)的使用

    代码块本质上是和其它变量相似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你能够像调用其它标准函数一样,传入參数数,并得到返回值. 脱字符(^)是块的语法标记.依照我们熟悉的參数语法规约所定 ...

  2. ios 添加block 类别_iOS 关于Block代码块的详解

    概述 block 上图就是一个block简单使用,它包括了block的声明.赋值实现.调用 三个部分,其中,实现部分可以看作是一种匿名函数:跟函数一样,block也是需要调用才能执行内部代码的:赋值的 ...

  3. [译] Ruby 2.6 String的split 方法支持代码块执行

    本博客系列翻译自 Bigbinary 的 Ruby 2.6 系列, 已得到作者允许.Ruby 2.6.0-preview2 现已发布. 在Ruby 2.6之前, String#split 方法会返回一 ...

  4. iOS中得block代码块的定义及使用

    现在的无论是框架还是项目中,越来越多的使用block代码块. 个人觉得:第一可以使代码看起来更简单明了,第二可以取代以前的delegate使代码的逻辑看起来更清晰. 借一张图表达基本定义: (1)最基 ...

  5. Block代码块中使用局部变量注意点

    第一次写代码遇到报这个错,实在是想不通为什么,按常理应该是不会有问题,报错的呀??纠结了一会之后只好仔细查看报错原因咯,原来是: 当我们在block代码块中使用局部变量时,就会很容易出现如图的错误. ...

  6. iOS - OC Block 代码块

    前言 Block 是一段预先准备好的代码,可以在需要的时候执行,可以当作参数传递.Block 可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.Block 是 C 语言的,类似于一个 ...

  7. 迭代器、代码块、闭包

    迭代器each 是数组类的一个方法:大括号{ }里的代码是代码块,简称块.你可以用大括号{ }将代码组织成块,也可以用 do-end将代码组织成块.大括号{ }的优先级高于do-end. 我们来写一个 ...

  8. [ios开发基础之]代码块

    iOS4引入了一个新特性,支持代码块的使用, 这将从根本上改变你的编程方式.代码块是对C语言的一个扩展,因此在Objective-C中完全支持.如果你学过Ruby,Python或Lisp编程 语言,那 ...

  9. hbuilder边框代码是什么_HBuilder CSS 自定义代码块

    1 =begin2 本文档是CSS代码块的编辑文件.注意不要把其他语言的设置放到css里来.3 HBuilder可使用ruby脚本来编辑代码块和增强操作命令.4 1.编辑代码块5 如果要新增一个代码块 ...

  10. Xcode快捷键及代码块

    2017-02-16 吴白 CocoaChina 手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥 ...

最新文章

  1. Cacti部署及常用插件安装(2)
  2. MongoDB 小试牛刀
  3. Android动画模式
  4. 后台服务系统之Dubbo协议
  5. nginx负载均衡的简单实现
  6. 如何开始DDD(完)
  7. React 入门手册
  8. 【CodeForces - 255A】Greg's Workout (水题)
  9. golang学习之旅(1)
  10. 作者:黎建辉(1973-),男,博士,中国科学院计算机网络信息中心研究员、博士生导师。...
  11. python抽取指定url页面的title_Python使用scrapy爬虫,爬取今日头条首页推荐新闻
  12. Java基础学习总结(170)——Java8并发工具类CompletableFuture学习总结
  13. oracle 10g 创建只读用户语法
  14. lintcode:子数组之和为0
  15. 时间:2014年3月28日15:51:27框架改进 增加日志功能log类
  16. 35+ 个 Java 代码性能优化总结
  17. 【JAVA】poi操作,excel读取数据。
  18. 截图工具-Excel加载宏(图片大小可调)
  19. rpm、lpm是什么意思?
  20. (已解决)报错:collect2 error ld returned 1 exit status

热门文章

  1. visual studio 2019配置dlib读取jpeg图片
  2. numpy构建卷积网络
  3. python类基础知识
  4. Python基于OpenCV实现视频数据切割为图像数据
  5. 激活函数、损失函数及其优化方法总结
  6. VS+PCL的4099警告的解决方法
  7. 卷积的定义,知乎上有个很有名的段子:
  8. 35c语言编程,35编号c语言编程题08850.pdf
  9. delphi dbgrideh 遍历每一个单元格_BFS 的使用场景:层序遍历、最短路径问题
  10. 区块链 共识机制研究的重要定理有哪些