Ruby方法链中替换指定方法为自定义块的实现问询
在Ruby中保持链式调用的同时替换中间方法为自定义逻辑
要实现你想要的效果,Ruby的then(或yield_self)方法是完美的解决方案——它能让你在链式调用中插入自定义块,同时保持代码的流畅性,完全契合你的需求。
直接解决方案
把原来的y = x.a.b.c.d.e.f改成这样:
y = x.a.b.then { |temp| # temp就是x.a.b的返回值 # 在这里写你的自定义计算逻辑,最后返回temp1 # 比如:temp1 = temp.some_custom_process; temp1 }.d.e.f
举个具体实例
假设我们有一组链式调用的类结构:
class User def profile; Profile.new; end end class Profile def address; Address.new; end # 原来的c方法:返回默认经纬度对象 def coordinates; Coordinates.new(100, 30); end end class Coordinates def normalize; NormalizedCoords.new; end def format; "100.0, 30.0"; end end class NormalizedCoords def format; "标准化:100.0, 30.0"; end end
原来的调用是user.profile.coordinates.normalize.format,现在如果要把coordinates替换成自定义计算(比如根据地址生成专属经纬度),用then就可以这样写:
user = User.new y = user.profile.address.then do |addr| # 自定义逻辑:根据地址属性生成自定义的Coordinates实例 Coordinates.new(addr.city_longitude, addr.city_latitude) end.normalize.format
关键细节说明
then方法会把前一个链式调用的结果(也就是x.a.b的返回值)作为参数传给块,你可以在块里对这个值做任何处理。- 块必须返回你想要继续链式调用的对象(也就是你的
temp1),这样后面的.d.e.f才能正确调用在这个对象上。 - 如果你的Ruby版本低于2.6(
then是2.6版本引入的),可以用yield_self,它和then功能完全一致,写法是:y = x.a.b.yield_self { |temp| 你的自定义逻辑 }.d.e.f
为什么不用tap?
tap方法虽然也能插入块,但它会返回原对象,而不是块的返回值——这不符合你的需求,因为你需要用temp1继续链式调用,而不是原来的temp。所以tap适合做一些不改变链式对象的副作用操作(比如打印日志),但不适合这里的场景。
内容的提问来源于stack exchange,提问作者user1934428
相关产品推荐
相关产品推荐

