红宝石中是否有“管道”等效物?

时间:2012-10-11 21:41:30

标签: ruby

有时候在编写Ruby时,我发现自己想要一个pipe方法,类似于tap但返回结果self作为参数调用块,像这样:

class Object
  def pipe(&block)
    block.call(self)
  end
end

some_operation.pipe { |x| some_other_operation(x) }

..但到目前为止,我还没有设法找出它的名称,如果存在的话。它存在吗?

如果没有,我知道我可以通过猴子补丁来添加它,但是,你知道,这很糟糕。除非有一个辉煌的,保证永不冲突(和描述性和简短)的名称,我可以用它......

3 个答案:

答案 0 :(得分:12)

核心中不存在这种抽象。我通常将其称为as,它简短且具有说服力:

class Object
  def as
    yield(self)
  end
end

"3".to_i.as { |x| x*x } #=> 9

Raganwald通常在帖子中提到抽象,他称之为into

总而言之,有些名称:pipeasintopegthru

答案 1 :(得分:2)

Ruby 2.5 introduced Object.yield_self,它正是您正在使用的管道运算符:它接收一个块,将self作为第一个参数传递给它,并返回计算块的结果。

class Object
  def yield_self(*args)
    yield(self, *args)
  end
end

使用示例:

"Hello".yield_self { |str| str + " World" }
# Returns "Hello World"

您还可以在以下博客文章中阅读更多相关内容:

  1. Explains the difference with Rails' try and Ruby's tap methods
  2. Some very nice examples of using yield_self to simplify code

答案 2 :(得分:0)

这是我用来链接对象的技术。除了我不重新打开Foo { Parents Moo::Object public methods (2) : attr, new private methods (1) : _explicitly_set_attr internals: { attr 1 } } 类之外,它几乎与上面完全相同。相反,我创建了一个Object,我将使用它来扩展我正在使用的任何对象实例。见下文:

Module

我已经定义了这种方法来禁止变异方法改变原始对象。以下是使用此模块的一个简单示例:

module Chainable
  def as
    (yield self.dup).extend(Chainable)
  end
end

如果有人发现此代码有任何问题,请告诉我们!希望这会有所帮助。