ruby 疑难点之—— yield 和 yield self
yield
所有的"方法(methods)"隐式跟上一个"块(block)"参数。
块参数也可以明确给定,形式就是在参数前面加一个"&",比如 def fn(arg1, arg2, &block) end,其中的 &block 就是明确给定的块参数。
块参数的动作,可以通过调用 call() 方法执行,还可以用 yield 来执行 —— yield 其实就是一个语法糖。
所以以下几种写法常常是等价的:
#method receives an invisible block argument
def foo1()
yield 1
end #specify it explicitly
def foo2(&block)
yield 1
end #yield is equal to block.call
def foo3(&block)
block.call(1)
end #function call
foo1 {|x| puts x} # =>
foo2 {|x| puts x} # =>
foo3 {|x| puts x} # =>
Proc
前面说到所有方法都可以隐式或显式指定一个块参数,那么块参数到底是什么呢?
答案是 Proc 对象,一个具有 call 方法的对象。
Proc 对象的定义有几种形式:
- 直接使用 {}
- 使用 Proc.new {}
- 使用 proc {}
- 使用 lambda {}
#yield is equal to block.call
def foo(&block)
puts block.class
puts block.to_s
yield 1
end #function call
# Proc created using {} syntax
foo {|x| puts x}
# => Proc
# => #<Proc:0x00000000e0b140@(ruby):9>
# => # Proc created with the "proc" keyword. Note & syntax when calling.
my_proc = proc { |n| puts n }
foo(&my_proc)
# => Proc
# => #<Proc:0x00000000e0b140@(ruby):12>
# => # Proc creates with Proc.new
my_proc = Proc.new { |n| puts n }
foo(&my_proc) # => 1
# => Proc
# => #<Proc:0x00000000e0b140@(ruby):16>
# => # Proc created with the "lambda" keyword. Nearly same thing.
my_proc = lambda { |n| puts n }
foo(&my_proc)
# => Proc
# => #<Proc:0x00000000e0b140@(ruby):20 (lambda)>
# =>
yield self
在一个对象中,self 表示是一个当前对象的引用。
所以,常见的 yield self if block_given? 中的 self 就和其它地方使用 self 一样,没什么特殊的。
class C1
def foo(&block)
puts block.class
puts block.to_s
yield self if block_given?
yield "AAAAAAAAA"
end
end class C2
def foo(&block)
puts block.class
puts block.to_s
yield self if block_given?
yield "BBBBBBBBB"
end def to_s
"XXXXXXXXXX"
end
end c1 = C1.new
c1.foo {|x| puts x}
# => Proc
# => #<Proc:0x00000001c84aa0@(ruby):23>
# => #<Context::C1:0x00000001c84af0>
# => AAAAAAAAA c2 = C2.new
c2.foo {|x| puts x}
# => Proc
# => #<Proc:0x00000001c842f8@(ruby):26>
# => XXXXXXXXXX
# => BBBBBBBBB
注意事项
method 定义中 &block 参数必须在最后
# 正确示例
def foo(arg1, arg2, &block)
puts block
end #function call
block = proc {|x| puts x}
foo( 1, 2, &block)
# => #<Proc:0x000000011f3aa0@(ruby):14> #错误示例
def foo(arg1, &block, arg2) # => (ruby): syntax error
puts block
end
yield 相当于是 block.call() 方法的调用,所以参数个数也需要对应
def foo()
yield 1,2,3 # 这里的 1 2 3 就是传递的参数
end #function call
foo {|x| puts x} # => 1
foo {|x,y,z| puts z} # => 3
foo {|x,y,z,k| puts k} # 为空
ruby 疑难点之—— yield 和 yield self的更多相关文章
- python yield 与 yield from转
python yield 与 yield from转 https://blog.csdn.net/chenbin520/article/details/78111399?locationNum=7&a ...
- yield与yield from
yield 通过yield返回的是一个生成器,yield既可以产出值又可以生成值,yield可以用next()来启动生成器,同时可以用send向生成器传递值:在初次启动生成器时,需调用next()或s ...
- 从yield 到yield from再到python协程
yield 关键字 def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b yield 是在:PEP 255 -- Simple Generator ...
- 60、简述 yield和yield from关键字。
1.可迭代对象与迭代器的区别 可迭代对象:指的是具备可迭代的能力,即enumerable. 在Python中指的是可以通过for-in 语句去逐个访问元素的一些对象,比如元组tuple,列表list ...
- python yield、yield from与协程
从生成器到协程 协程是指一个过程,这个过程与调用方协作,产出由调用方提供的值.生成器的调用方可以使用 .send(...)方法发送数据,发送的数据会成为yield表达式的值.因此,生成器可以作为协程使 ...
- python协程--yield和yield from
字典为动词“to yield”给出了两个释义:产出和让步.对于 Python 生成器中的 yield 来说,这两个含义都成立.yield item 这行代码会产出一个值,提供给 next(...) 的 ...
- 简述 yield和yield from关键字
1.可迭代对象与迭代器的区别 可迭代对象:指的是具备可迭代的能力,即enumerable. 在Python中指的是可以通过for-in 语句去逐个访问元素的一些对象,比如元组tuple,列表list ...
- python yield && scrapy yield
title: python yield && scrapy yield date: 2020-03-17 16:00:00 categories: python tags: 语法 yi ...
- 从yield到yield from再到python协程
yield 关键字 def fib(): a,b = 0,1 while 1: yield b a,b = b,a+b yield是在:PEP 255 -- Simple Generators 这个p ...
随机推荐
- mysql 错误解决
1. Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE ...
- 【转】新建maven工程为什么jdk会是默认版本 而不是自己设置的版本?
原文链接:为什么我eclipse新建项目的时候默认的是JRE1.5? 修改Maven中conf目录里的setting.xml文件内容,加上如下内容: <profiles> <!-- ...
- jquery easyui的layout
1.创建一个布局:layout是一个容器,它有5个区域:north(北),south(南),east(东),west(西):center(中)-----------学习中文网地址 <body c ...
- My97DatePicker时间控件使用说明
常规调用: <input id="date01" type="text" onClick="WdatePicker()"/> & ...
- javascript实现颜色渐变
渐变(Gradient)是美学中一条重要的形式美法则,与其相对应的是突变.形状.大小.位置.方向.色彩等视觉因素都可以进行渐变.在色彩中,色相.明度.纯度也都可以产生渐变效果,并会表现出具有丰富层次的 ...
- ajax。表单
JQuery读书笔记--JQuery-Form中的ajaxForm和ajaxSubmit的区别JQuery中的ajaxForm和ajaxSubmit使用差不多功能也差不多.很容易误解. 按照作者的解释 ...
- C#编程简短总结
封装 field一般为private,定义的时候可以不赋值.不赋值的时候一般被构造函数初始化赋值,其值用来保存类实例的数据,可以被内部方法使用作为计算的数据来源.当需要继承类继承本类的时候,field ...
- iPhone Push消息全攻略.1
要做一个iPhone Push消息的需求,从简单test的开始. 1.先添加一个app ID 2.点击Edit来配置push服务. 3.生成两个证书,一个用于开发,一个用于发布. 4.按下图操作创建一 ...
- 得到内网域管理员的5种常见方法<转>
1.Netbios and LLMNR Name Poisoning 这个方法在WIN工作组下渗透很有用,WIN的请求查询顺序是下面三个步骤:本地hosts文件(%windir%\System32\d ...
- w3cmark前端精彩博文周报 10.13-10.19
w3cmark推出每周精选前端博文推荐,通过阅读别人的代码,学习别人的经验,提升自己的水平.欢迎关注 @前端笔记网 微博.其实如果是关注我们微博的朋友都对下面的文章熟悉,因为我们会一旦发现有价值的.精 ...