3

可能重复:
红宝石中是否有“管道”等价物?

我正在查看tapRuby 中的方法 - 但不幸的是,从传递的块返回的对象没有传递。我使用什么方法来传递对象?

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

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)}

为什么对象不那么容易?

4

3 回答 3

3
class Object
  def as
    yield self
  end
end

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

于 2013-01-08T11:35:10.513 回答
-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 }

以我的拙见,它甚至读起来更好;)

于 2013-01-08T11:39:14.473 回答
-1

简单的答案是tap没有做你认为它做的事情。

tap在一个对象上调用并且总是返回同一个对象。

作为taps 使用的简单示例

"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

于 2013-01-08T11:42:00.683 回答