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的更多相关文章

  1. python yield 与 yield from转

    python yield 与 yield from转 https://blog.csdn.net/chenbin520/article/details/78111399?locationNum=7&a ...

  2. yield与yield from

    yield 通过yield返回的是一个生成器,yield既可以产出值又可以生成值,yield可以用next()来启动生成器,同时可以用send向生成器传递值:在初次启动生成器时,需调用next()或s ...

  3. 从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 ...

  4. 60、简述 yield和yield from关键字。

    1.可迭代对象与迭代器的区别 可迭代对象:指的是具备可迭代的能力,即enumerable.  在Python中指的是可以通过for-in 语句去逐个访问元素的一些对象,比如元组tuple,列表list ...

  5. python yield、yield from与协程

    从生成器到协程 协程是指一个过程,这个过程与调用方协作,产出由调用方提供的值.生成器的调用方可以使用 .send(...)方法发送数据,发送的数据会成为yield表达式的值.因此,生成器可以作为协程使 ...

  6. python协程--yield和yield from

    字典为动词“to yield”给出了两个释义:产出和让步.对于 Python 生成器中的 yield 来说,这两个含义都成立.yield item 这行代码会产出一个值,提供给 next(...) 的 ...

  7. 简述 yield和yield from关键字

    1.可迭代对象与迭代器的区别 可迭代对象:指的是具备可迭代的能力,即enumerable.  在Python中指的是可以通过for-in 语句去逐个访问元素的一些对象,比如元组tuple,列表list ...

  8. python yield && scrapy yield

    title: python yield && scrapy yield date: 2020-03-17 16:00:00 categories: python tags: 语法 yi ...

  9. 从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 ...

随机推荐

  1. 十个提升你Emacs生产力的高招

    转载 十个提升你Emacs生产力的高招   Emacs是世界上最好的编辑器(真的有很多人这么认为).不要以为emacs只是在编写程序时很牛X,其实只要你真正精通了emacs,会发现她几乎在所有用到打字 ...

  2. homework-02,第二次作业——寻找矩阵最大子序列和

    经过漫漫漫~~~~~~~~~~~~~~长的编译和调试,第二次作业终于告一段落了 先放出源码,思路后面慢慢道来 #include<stdio.h> #include<stdlib.h& ...

  3. 关于Js脚本的延迟执行

      关于标签,我们有一般会放在两个地方,一个是在标签的内部,另一个是放在前面.这一次我们着重讲解一下放在标签内部.在我们用Js操作DOM元素时,如果不延时执行,DOM元素其实是根本还没有被渲染出来的. ...

  4. Python 发送邮件包含附件报表示例

    之前需要用Python发送报表邮件,在网上找了下资料,基本上符合要求了. 相关的示例如下,懂python的人应该都知道. from email.mime.text import MIMEText fr ...

  5. Spring Autowiring @Qualifier example

    In Spring, @Qualifier means, which bean is qualify to autowired on a field. See following scenario : ...

  6. Algorithms Part 1-Question 6- 2SUM Median-数和以及中位数问题

    本次有两个编程问题,一个是求两个数的和满足一定值的数目,另一个是求中位数. 2SUM问题 问题描述 The goal of this problem is to implement a variant ...

  7. HDU 3966 Aragorn's Story (树链点权剖分,成段修改单点查询)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 树链剖分的模版,成段更新单点查询.熟悉线段树的成段更新的话就小case啦. //树链剖分 边权修 ...

  8. Codeforces Round #350 (Div. 2) E. Correct Bracket Sequence Editor (链表)

    题目链接:http://codeforces.com/contest/670/problem/E 给你n长度的括号字符,m个操作,光标初始位置是p,'D'操作表示删除当前光标所在的字符对应的括号字符以 ...

  9. java functional syntax overview

    Defining a Functional Interface @FunctionalInterface public interface TailCall<T> { TailCall&l ...

  10. UITableView section header 不固定

    iOS系统自带的UITableView,当数据分为多个section的时候,在UITableView滑动的过程中,默认section header是固定在顶部的,滑动到下一个section的时候,下一 ...