我想编写一些在调用initialize方法后运行的ruby代码。此代码可以在类或模块中。我怎么写这个?
这是我想要的一个例子:
class Base
def after_init
puts "after init"
end
class A < Base # Option 1, use a class
end
class B < Base
def initialize
puts "in init"
end
end
module MyMod
def after_init
puts "after init"
end
end
class C
include Module
end
$> A.new
=> "after init"
$> B.new
=> "in init"
=> "after init"
$> C.new
=> "after init"
我绝对不想做的是明确调用super
。有没有办法做到这一点?我不在乎它是否使用了很多Ruby的反射能力。谢谢!
答案 0 :(得分:5)
class Base
def after_init
puts "Base#after_init"
end
def self.inherited(klass)
class << klass
alias_method :__new, :new
def new(*args)
e = __new(*args)
e.after_init
e
end
end
end
end
module MyMod
def after_init
puts "MyMod#after_init"
end
def self.included(klass)
class << klass
alias_method :__new, :new
def new(*args)
e = __new(*args)
e.after_init
e
end
end
end
end
class A < Base
end
class B < Base
def initialize
puts "B#initialize"
end
end
class C
include MyMod
def initialize
puts "C#initialize"
end
end
A.new
B.new
C.new
答案 1 :(得分:2)
这是一个可以继承的示例类:
class MyClass
class << self
alias_method :_new, :new
def new
_new.tap do |instance|
instance.send(:after_init)
end
end
end
private
def after_init
puts 'after_init'
end
end
我考虑过覆盖new
可能发生的一切,但这应该足以让你开始。
修改:作为模块:
module MyMixin
def self.included(base)
class << base
alias_method :_new, :new
define_method :new do
_new.tap do |instance|
instance.send(:after_init)
end
end
end
end
def after_init
puts 'hello'
end
end
class MyClass
include MyMixin
end