我试图稍微干掉我的代码所以我正在编写一种方法来将某些方法推迟或委托给另一个对象,但前提是它存在。以下是基本想法:我Shipment < AbstractShipment
可能有Reroute < AbstractShipment
。 Shipment
或Reroute
可以Delivery
(或交付),但不能同时使用AbstractShipment
。
当我致电shipping.deliveries时,我希望它先检查是否有重新路由。如果没有,那么只需调用deliveries
的{{1}}方法;如果是这样,请将方法委托给重新路由。
我用下面的简单代码尝试了这个:
module Kernel
private
def this_method
caller[0] =~ /`([^']*)'/ and $1
end
end
class Shipment < AbstractShipment
...
def deferToReroute
if self.reroute.present?
self.reroute.send(this_method)
else
super
end
end
alias_method :isComplete?, :deferToReroute
alias_method :quantityReceived, :deferToReroute
alias_method :receiptDate, :deferToReroute
end
Kernel.this_method只是方便查找调用的方法。但是,调用super
会抛出
super: no superclass method `deferToReroute'
我搜索了一下,发现this link讨论了这是Ruby 1.8中的一个错误,但在1.9中修复了。不幸的是,我还不能将此代码升级到1.9,那么有没有人有任何解决方法的建议?
谢谢: - )
编辑:在看了一下我的代码后,我意识到我实际上并不需要为我所做的所有方法添加别名,实际上我只需要覆盖交付方法其他三个实际上称它为计算。但是,自从我之前遇到过这个问题后,我仍然想知道你们的想法。
答案 0 :(得分:2)
不是在这里使用alias_method,而是通过硬覆盖这些方法来提供更好的服务,例如:
class Shipment < AbstractShipment
def isComplete?
return super unless reroute
reroute.isComplete?
end
end
如果你发现你每班5-10次这样做,你可以这样做更好:
class Shipment < AbstractShipment
def self.deferred_to_reroute(*method_names)
method_names.each do |method_name|
eval "def #{method_name}; return super unless reroute; reroute.#{method_name}; end"
end
end
deferred_to_reroute :isComplete?, :quantityReceived, :receiptDate
end
使用直接评估提供good performance characteristics,并允许您为类定义中的内容提供简单的声明性语法。