加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Ruby:块内的收益率

发布时间:2020-12-17 02:22:41 所属栏目:百科 来源:网络整理
导读:以下是扫描示例: "abcdeabcabc".scan("a") 所以它返回一个3 a的数组.另一个扫描示例: "abcdeabcabc".scan("a") {|x| puts x} 它只输出每个“a”,但仍然输出一个数组,这次它实际上是它返回的原始字符串. 因此,从上面的文档和行为中,扫描要么返回一个数组(没
以下是扫描示例:

"abcdeabcabc".scan("a")

所以它返回一个3 a的数组.另一个扫描示例:

"abcdeabcabc".scan("a") {|x| puts x}

它只输出每个“a”,但仍然输出一个数组,这次它实际上是它返回的原始字符串.

因此,从上面的文档和行为中,扫描要么返回一个数组(没有给出块),要么返回原始字符串,在此之前会发生一些副作用.关键是两种情况都会返回一些东西.

那么如果我在块中放置“收益”会发生什么?什么将被退回?或者,没有?返回值的类型是什么?

"abcdeabcabc".scan("a") {|x| yield x}

上面的内容不起作用,因为Ruby抱怨没有给出任何阻止??.这对我来说很有意义.但是,如果它是类方法的一部分,比如说,自我实现的“每个”,则以下工作:

class Test
  def my_each
    "abcdeabcabc".scan("a") {|x| yield x}
  end
end
# => :my_each

t = Test.new
# => #<Test:0x007ff00a8d79b0>

t.my_each {|x| puts "so this is #{x}"}
# it works. Outpus 3 a's then return the original string.

那么,Test类的my_each方法的返回值是多少?这是收益率列表还是什么?但正如之前所讨论的“abcdeabcabc”.scan(“a”){| x |在给出一个块之前,Ruby会抱怨yield x}段.内部发生了什么事情,将my_each块提供给my_each实现中的段?

解决方法

该块与该函数的参数类似地传递.这可以明确指定,如下所示:

class Test
  def my_each(&block)
    "abcdeabcabc".scan("a") do |x|
      puts "!!! block"
      yield x
      # Could be replaced with: block.call(x)
    end
  end
end

从技术上讲,它完全相同(放在那里澄清),它的存在不会像通常为参数做的那样进行检查.如果你忘记给它一个块,函数将停止它必须执行的第一个yield与完全相同的LocalJumpError(至少,这是我得到的Rubinius).但是,请注意控制台中的“!!! block”.

这样做是有原因的.您可以检查您的函数是否被赋予块,如果使用if块明确指定,则跳过yield.一个很好的例子是Rails的content_tag帮助器.这个助手的调用可以是块嵌套的.一个简单的例子:

content_tag :div do
  content_tag :div
end

……产生如下输出:

<div>
  <div></div>
</div>

因此,块在您的方法的“顶部”(就调用堆栈而言)执行.每次产量发生时都会调用它,就像块上的某种函数调用一样.之后执行块时,它不会累积在任何地方.

UPD:

许多eaches返回的枚举器由许多迭代器显式构造,以保存应该发生的事件的上下文.

它可以像my_each一样实现:

class Test
  def my_each(&block)
    if block
      "abcdeabcabc".scan("a") { |x| yield x }
    else
      Enumerator.new(self,:my_each)
    end
  end
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读