问题
I found one source which successfully overrode Time.strftime like this:
class Time
alias :old_strftime :strftime
def strftime
#do something
old_strftime
end
end
The trouble is, strftime is an instance method. I need to override Time.now - a class method - in such away that any caller gets my new method, while the new method still calls the original .now method. I've looked at alias_method and have met with no success.
回答1:
This is kinda hard to get your head around sometimes, but you need to open the "eigenclass" which is the singleton associated with a specific class object. the syntax for this is class << self do...end.
class Time
alias :old_strftime :strftime
def strftime
puts "got here"
old_strftime
end
end
class Time
class << self
alias :old_now :now
def now
puts "got here too"
old_now
end
end
end
t = Time.now
puts t.strftime
回答2:
Class methods are just methods. I highly recommend against this, but you have two equivalent choices:
class Time
class << self
alias_method :old_time_now, :now
def now
my_now = old_time_now
# new code
my_now
end
end
end
class << Time
alias_method :old_time_now, :now
def now
my_now = old_time_now
# new code
my_now
end
end
回答3:
If the you need to override it for testing purposes (the reason I normally want to override Time.now), Ruby mocking/stubbing frameworks will do this for you easily. For instance, with RSpec (which uses flexmock):
Time.stub!(:now).and_return(Time.mktime(1970,1,1))
By the way, I highly recommend avoiding the need to stub out Time.now by giving your classes an overrideable clock:
class Foo
def initialize(clock=Time)
@clock = clock
end
def do_something
time = @clock.now
# ...
end
end
回答4:
I've been trying to figure out how to override an instance method using modules.
module Mo
def self.included(base)
base.instance_eval do
alias :old_time_now :now
def now
my_now = old_time_now
puts 'overrided now'
# new code
my_now
end
end
end
end
Time.send(:include, Mo) unless Time.include?(Mo)
> Time.now
overrided now
=> Mon Aug 02 23:12:31 -0500 2010
来源:https://stackoverflow.com/questions/288020/how-does-one-without-inheritance-override-a-class-method-and-call-the-origin