Ruby 模块包装一个类方法?
有没有可能做到这一点,而不必在课程末尾包含模块,只需在顶部包含模块Ruby 模块包装一个类方法?,ruby,module,wrapper,Ruby,Module,Wrapper,有没有可能做到这一点,而不必在课程末尾包含模块,只需在顶部包含模块 module VerboseJob def self.included(job_class) class << job_class alias_method :original_perform, :perform def perform(*args) JobLogger.verbose { original_perform(*args) } end
module VerboseJob
def self.included(job_class)
class << job_class
alias_method :original_perform, :perform
def perform(*args)
JobLogger.verbose { original_perform(*args) }
end
end
end
end
class HelloJob
include VerboseJob
def self.perform(arg1, arg2)
puts "Job invoked with #{arg1} and #{arg2}"
end
end
模块详细作业
def包括在内(作业级)
类这里是一种相当迂回/刻薄的方法,我通过将包装器方法的定义推迟到最初的方法被定义之后提出:
module A
def self.included(base)
base.class_eval do
def self.singleton_method_added(name)
@@ran||=false
if name==:perform && !@@ran
@@ran=true
class<<self
alias_method :original_perform, :perform
def perform(*args)
puts "Hello"
original_perform(*args)
end
end
end
end
end
end
end
class B
include A
def self.perform
puts "Foobar"
end
end
B.perform
模块A
def自带(基本)
基本类\u评估do
添加了自定义单例方法(名称)
@@ran | |=错误
如果name==:执行&@@跑
@@然=真
类假设您希望在运行执行
之前定义所有类,您可能希望使用:
将块转换为Proc对象(并因此在点处绑定它)
并在程序退出时将其注册以执行。如果
注册了多个处理程序,它们以相反的顺序执行
注册登记
产生:
再见残酷的世界
您可能还想看看单元测试框架(如Test::unit或MiniTest)是如何处理任务运行延迟的。为什么不使用添加的方法来包装执行。。呃。。添加?:)我不确定我是否理解你的意思,我不是这样做的吗?我接受了你的答案(结合这个),并得出了更简洁的答案(无论在哪里执行include
)。请随意编辑您的答案。我还是会接受的:)@Tapio:对不起,我误解了你的代码。在我看来,这并没有那么粗俗。@d11wtq太棒了,那更干净了!我不确定我是否理解这与我的问题有什么关系,这是关于从包含的模块中“包装”类/实例方法的问题?@d11wtq:我正在尝试以最合适的方式解决您遇到的问题。看见
module VerboseJob
module ClassMethods
def wrap_perform!
class << self
def perform_with_verbose(*args)
JobLogger.verbose { perform_without_verbose(*args) }
end
alias_method_chain :perform, :verbose \
unless instance_method(:perform) == instance_method(:perform_with_verbose)
end
end
def singleton_method_added(name)
wrap_perform! if name == :perform
end
end
def self.included(job_class)
job_class.extend ClassMethods
job_class.wrap_perform! if job_class.respond_to?(:perform)
end
end
def do_at_exit(str1)
at_exit { print str1 }
end
at_exit { puts "cruel world" }
do_at_exit("goodbye ")
exit