Ruby方法链接 - “tap”替换

时间:2013-01-08 11:05:48

标签: ruby function functional-programming

  

可能重复:
  Is there a `pipe` equivalent in ruby?

我正在查看Ruby中的tap方法 - 但遗憾的是,传递的块返回的对象未被传递。我使用什么方法传递对象?

这是我正在尝试(不成功)做的事情:

obj.tap{ |o| first_transform(o) }.tap{ |o| second_transform(o)}

这当然等同于second_transform(first_transform(o))。我只想问第一种方法。

使用列表执行此操作非常简单:

list.map{ |item| first_transform(item) }.map{ |item| second_transform(item)}

为什么对象不那么容易?

3 个答案:

答案 0 :(得分:3)

class Object
  def as
    yield self
  end
end

有了这个,你可以[1,2,3].as{|l| l << 4}.as{|l| l << 5}

答案 1 :(得分:-1)

您还可以考虑制作项目类的#first_transform#second_transform实例方法(并返回转换后的项目)。

这些方法定义应如下所示:

class ItemClass
  # If you want your method to modify the object you should
  # add a bang at the end of the method name: first_transform!
  def first_transform
    # ... Manipulate the item (self) then return it
    transformed_item
  end
end

这样你就可以通过这种方式简单地链接方法:

list.map {|item| item.first_transform.second_transform }

我的拙见甚至更好;)

答案 2 :(得分:-1)

简单的答案是tap不符合你的想法。

tap在一个对象上被调用,并且将始终返回该对象。

作为tap使用的简单示例

"foo".tap do |foo|
  bar(foo)
end

这仍会返回"foo"

在您的示例中,您有一个对象,并且您想要连续应用两个函数。

second_transform(first_transform(obj))

<小时/> 更新:

所以我想我会问为什么你想以这种方式进行连锁。

obj.do{|o| first_transform(o)}.do{|o| second_transform(o)}

这是否比

更清晰
second_transform(first_transform(obj))

让我们举一个例子,我经常使用

markdown(truncate(@post.content))

truncated_post = truncate(@post.content)
markdown(truncated_post)

我想这取决于你transform

的性质