ruby中是否有“管道”等效物?

偶尔写Ruby的时候我发现自己想要一个pipe方法,类似于tap但是返回调用块的结果 ,并将self作为参数,如下所示:

 class Object def pipe(&block) block.call(self) end end some_operation.pipe { |x| some_other_operation(x) } 

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

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

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

 class Object def as yield(self) end end "3".to_i.as { |x| x*x } #=> 9 

Raganwald通常会在他的post中提到抽象,他称之为。

所以,总结一下,有些名字: pipeasintopegthru

Ruby 2.5 引入了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. 解释了Rails的try和Ruby的tap方法的区别
  2. 使用yield_self简化代码的一些非常好的例子

这是我用来链接对象的技术。 除了我不重新打开Object类之外,它几乎与上面完全相同。 相反,我创建了一个Module ,我将用它来扩展我正在使用的任何对象实例。 见下文:

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

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

 [3] pry(main)> m = 'hi' => "hi" [4] pry(main)> m.extend(Chainable).as { |m| m << '!' }.as { |m| m+'?'} => "hi!?" [5] pry(main)> m => "hi" 

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