我们都知道,如果目标类由模块组成,您只需在新模块中调用super
即可。但如果它是一个普通的方法呢?
class Logger
def message(msg)
puts msg
end
end
说,Logger是一个我无法改变的类(例如它在宝石中)。 我希望Logger在每条消息之前添加一个“================”行。我如何以美丽的方式做到这一点?遗产?聚合?怎么样?
答案 0 :(得分:3)
您可以将原始方法保存为未绑定的方法对象,而不是将其保存在别名中。
然后,您可以将define_method
与块一起使用。该块将在闭包中捕获未绑定的method_object,允许您在新方法中使用它,而不会污染您的模块/类。
唯一的缺点是,您可能无法定义以这种方式产生或阻塞的方法:
module Mod
unbound_method = instance_method(:original_method)
define_method :original_method do |*args|
#do something before
#call the original method
unbound_method.bind(self).call(*args)
#do something after
end
end
答案 1 :(得分:2)
这可能不是你所说的“美”,但最简单的方法就是在你的代码中使用:
class Logger
alias message old_message
def message(msg)
puts "================"
old_message(msg)
end
end
答案 2 :(得分:2)
您可以从logger继承并使用命名空间来使用它:
class LinedLogger < Logger
def message(*)
puts "=" * 15
super
end
end
当你想要使用它时:
class Post
Logger = LinedLogger
end
仅在命名空间Post
内,您将获得LinedLogger
而不是Logger
。这是一种限制补丁的好方法。但它不会在全球范围内发挥作用。
答案 3 :(得分:2)
我会在你自己的实例中执行子类化(每个@ain的答案)或自定义模块包含:
module LoggerLiner
def message(*args)
puts "="*15
super
end
end
log = Logger.new(STDOUT)
log.extend(LoggerLiner)