我正在查看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)}
为什么对象不那么容易?
答案 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