今天在书上看到这么一个例子,虽然我多多少少对 Ruby 的 block 有一些了解,但是第一次见到下面这种时,还是有点懵的:

# Rubydef block_args_testyield()yield(1)yield(1, 2, 3)
endputs "通过 |a| 接收块变量"
block_args_test do |a|p [a]
end
putsputs "通过 |a, b, c| 接收块变量"
block_args_test do |a, b, c|p [a, b, c]
end
putsputs "通过 |*a| 接收块变量"
block_args_test do |*a|p [a]
end
puts------------------------------------------------------------
通过 |a| 接收块变量
[nil]
[1]
[1]通过 |a, b, c| 接收块变量
[nil, nil, nil]
[1, nil, nil]
[1, 2, 3]通过 |*a| 接收块变量
[[]]
[[1]]
[[1, 2, 3]]

所以,为了啃下这块硬骨头,先从一个简单的例子讲起吧!

不带参的块

# Ruby
# 定义块
def myloopwhile trueyield     # 执行块end
endnum = 1
myloop doputs "num is #{num}"break  if num > 10num *= 2
end------------------------------------------------------------
num is 1
num is 2
num is 4
num is 8
num is 16

首先是定义块,在定义好块以后,使用块的 do ~ end 语句时,其实质是把块里边的代码:

  puts "num is #{num}"break  if num > 10num *= 2

放到了 yield 的地方去执行,所以这儿是比较好理解的。

携带参的块

我们把上面的简单例子稍微改造一下,改成可以传参给 block,下面还是可以得到同上面一样的输出。

# Ruby
# 定义块
def myloopwhile trueyield(2)     # 执行块end
endnum = 1
myloop do |i|puts "num is #{num}"break  if num > 10num *= i
end------------------------------------------------------------
num is 1
num is 2
num is 4
num is 8
num is 16

虽然比不传参的稍微复杂一点,但是我相信大家还是能看懂的。

传参数目不一致

现在,我们再复杂化一点,块定义的时候设定两个参数,但是 block  执行的时候只给块传一个参数。

# Ruby
# 定义块
def myloopwhile trueyield(2, 3)     # 执行块end
endnum = 1
myloop do |i|puts "num is #{num}"break  if num > 10num *= i
end------------------------------------------------------------
num is 1
num is 2
num is 4
num is 8
num is 16

还是一样的结果,似乎多的参数对执行结果并没有什么影响。到现在,我们基本上能把最开始的例子解释一下了。

结果解释

# Rubydef block_args_testyield()yield(1)yield(1, 2, 3)
endputs "通过 |a| 接收块变量"
block_args_test do |a|p [a]
end
putsputs "通过 |a, b, c| 接收块变量"
block_args_test do |a, b, c|p [a, b, c]
end
putsputs "通过 |*a| 接收块变量"
block_args_test do |*a|p [a]
end
puts------------------------------------------------------------
通过 |a| 接收块变量
[nil]  # yield() 没传递参数,所以 a 没接收到参数,a 为 nil
[1]    # yield(1) 传递一个参数,所以 a 接收到传递的参数,a 为 1
[1]    # yield(1, 2, 3) 传递三个参数,但是只有一个块变量接收,所以接收到第一个参数,a 为 1通过 |a, b, c| 接收块变量
[nil, nil, nil]   # yield() 没传递参数,所以三个块变量 a, b, c 均为 nil
[1, nil, nil]     # yield() 传递一个参数,所以 a 接收到传递的参数,a 为 1,剩下 2 个块变量 b, c 均为 nil
[1, 2, 3]         # yield() 传递三个个参数,a, b, c 三个块变量分别接收一个通过 |*a| 接收块变量
# *a 是匹配任意个的意思,所以无论 yield 传递过来多少参数,块变量都会将多个参数变成一个数组
# 我们可以来个下面的简单例子印证一下
# [20] pry(main)> def test(*args)
# [20] pry(main)*   p [args]
# [20] pry(main)* end
# => :test
# [21] pry(main)> test(1, 2, 3)
# [[1, 2, 3]]
# => [[1, 2, 3]][[]]              # yield() 没传递参数,所以 a 为 []
[[1]]             # yield() 传递一个参数,所以 a 为 [1]
[[1, 2, 3]]       # yield() 传递三个个参数,匹配三个参数以后,所以 a 为 [1, 2, 3]

Ruby 的 yield 浅析相关推荐

  1. 深入理解Python中的yield和send

    send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互. 但是需要注意,在一个生成器对象没有执行next方法之前,由 ...

  2. 黑客用python还是ruby-python和ruby,我选谁?

    最近在考虑学习一门后端语言,在ruby和python直接犹豫,然后自己做了一些对比,希望能帮到有同样问题的你. 一.异同对比选择 1.Python和ruby的相同点: •都强调语法简单,都具有更一般的 ...

  3. 什么是Scala的收益?

    本文翻译自:What is Scala's yield? I understand Ruby and Python's yield. 我理解Ruby和Python的收益率. What does Sca ...

  4. python-函数进阶

    python-函数进阶 1,名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定 ...

  5. python html 制作pdf,python将html转成PDF的实现代码(包含中文) -电脑资料

    前提: 安 html2pdf https://pypi.python.org/pypi/xhtml2pdf/ 下载字体:微软雅黑:给个地址:http://www.jb51.net/fonts/8481 ...

  6. 2020-12-11 Python yield 使用浅析

    Python yield 使用浅析 您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ? 我们先抛开 generator,以一 ...

  7. 1、【转载】Python yield 使用浅析

    1.[转载]Python yield 使用浅析 [注:此文转载自https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ ...

  8. [转]Python yield 使用浅析

    您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ? 我们先抛开 generator,以一个常见的编程题目来展示 yield ...

  9. 辛星浅析ruby下的mkmf.rb can't find header files for ruby at

    有时候在ruby下使用gem安装包的时候,会报错如下: ERROR:  Error installing bluecloth:     ERROR: Failed to build gem nativ ...

最新文章

  1. 国内技术原创氛围为什么那么差?记EAWorld(普元)是如何靠“借鉴”产出原创文章的!
  2. Luogu P1262 间谍网络 【强连通分量/缩点】By cellur925
  3. C++ WINDOWS API 第1章 Windows 应用程序开发入门
  4. 深入理解内存(3):内存交换技术,虚拟内存
  5. python元组类型_Python数据类型之元组
  6. [Python2.x] 标准库 urllib2 的使用细节
  7. Docker学习总结(23)——Docker搭建大规模测试环境的实践
  8. Atitit php pdo的api使用 目录 1.1. PHP PDO简介 1 1.2. 若要使用数据库长连接,:PDO::ATTR_PERSISTENT 1 2. 其他设置 2 2.1. )、P
  9. mysql sql语句优化面试题_SQL面试题之SQL优化
  10. 绿联串口线linux驱动下载,绿联pl2303转串口驱动下载
  11. Premiere Pro之视频转场效果(四)
  12. Order by 多条件排序
  13. HTML5开发工具有哪些?
  14. 数值分析思考题(钟尔杰版)参考解答——第七章
  15. 违反唯一约束条件oracle,oracle imp遇到违反唯一约束条件 (GZW.SYS_C006112)
  16. 如何看待国企纷纷卸载微软Office改用金山WPS?
  17. app 自动化 打开app (二)
  18. win2003配置apache支持php_asp,Win2003下配置asp+cgi+php+mysql
  19. PAT甲级1009 Product of Polynomials (25分)
  20. 计算机网络技术2020,计算机网络技术超星2020试题及答案

热门文章

  1. Java class类文件和类加载器详解以及代码优化
  2. 机器学习的数学基础(下)
  3. 计算机病毒与网络安全的小报,校园网络安全手抄报图片
  4. 【苹果新编程语言】Swift简介
  5. 储罐液位开关c语言编程,基于PLC的储罐液位控制系统研究.doc
  6. 你离脱单之间只差一个表白神器 难道就不想遇到契合的灵魂相守一生
  7. 西北工业大学NOJ数据结构—014求广义表深度
  8. PlusFo干货篇:区块链共识机制的重要性
  9. 【在Unity中创建生存游戏 】4~6
  10. 数学建模系列-评价模型(五)---灰色综合评价法