我刚刚读了一篇博客文章,注意到作者在一段代码片段中使用了tap
,如下所示:
user = User.new.tap do |u|
u.username = "foobar"
u.save!
end
我的问题是,使用tap
到底有什么好处?我就不能这样做:
user = User.new
user.username = "foobar"
user.save!
或者更好:
user = User.create! username: "foobar"
发布于 2013-07-06 00:50:41
当读者遇到以下情况:
user = User.new
user.username = "foobar"
user.save!
他们必须遵循所有这三行,然后识别出它只是创建了一个名为user
的实例。
如果是的话:
user = User.new.tap do |u|
u.username = "foobar"
u.save!
end
那么这一点就会立刻变得清晰起来。读取器不必读取块中的内容即可知道实例user
已创建。
发布于 2013-07-06 01:12:56
使用tap的另一种情况是在返回对象之前对其进行操作。
因此,不是这样:
def some_method
...
some_object.serialize
some_object
end
我们可以省去额外的一行:
def some_method
...
some_object.tap{ |o| o.serialize }
end
在某些情况下,该技术可以节省多行代码,并使代码更加紧凑。
发布于 2013-07-06 00:32:30
使用tap,就像博主所做的那样,只是一种方便的方法。在您的示例中,这可能有些过头了,但如果您想与用户一起做一大堆事情,tap可以提供一个看起来更整洁的界面。因此,在下面的示例中可能更好:
user = User.new.tap do |u|
u.build_profile
u.process_credit_card
u.ship_out_item
u.send_email_confirmation
u.blahblahyougetmypoint
end
使用上面的方法可以很容易地看到,所有这些方法都分组在一起,因为它们都引用相同的对象(本例中的用户)。另一种方法是:
user = User.new
user.build_profile
user.process_credit_card
user.ship_out_item
user.send_email_confirmation
user.blahblahyougetmypoint
再一次,这是有争议的--但是第二个版本看起来有点混乱,并且需要更多的人工解析才能看到所有的方法都是在同一个对象上调用的。
https://stackoverflow.com/questions/17493080
复制相似问题