كيف يمكن للمرء - دون الميراث - تجاوز أسلوب فئة واستدعاء الأصلي من داخل الأسلوب الجديد؟
-
08-07-2019 - |
سؤال
ولقد وجدت مصدر واحد التي Time.strftime
تجاهلت بنجاح مثل هذا:
class Time
alias :old_strftime :strftime
def strftime
#do something
old_strftime
end
end
والمشكلة هي، strftime
هو أسلوب مثيل. ولست بحاجة لتجاوز Time.now
- طريقة الطبقة - في مثل هذا بعيدا أن أي المتصل يحصل لي طريقة جديدة، في حين أن الأسلوب الجديد لا يزال باستدعاء أسلوب .now
الأصلي. لقد ألقيت نظرة على alias_method
وقد التقى مع أي نجاح.
المحلول
وهذا من الصعب نوعا ما للحصول على رأسك حول بعض الأحيان، ولكن تحتاج لفتح "eigenclass" وهو المفرد المرتبطة كائن فئة محددة. بناء الجملة من أجل هذه هي الدرجة << النفس تفعل ... نهاية.
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
نصائح أخرى
وأساليب وطرق الدرجة فقط. أنا أوصي ضد هذا، ولكن لديك خياران أي ما يعادل:
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
وإذا كانت تحتاج إلى تجاوز ذلك لأغراض الاختبار (السبب أريد عادة لتجاوز Time.now)، روبي ساخرا / والأطر الإستئصال القيام بذلك نيابة عنك بسهولة. على سبيل المثال، مع RSpec (الذي يستخدم flexmock):
Time.stub!(:now).and_return(Time.mktime(1970,1,1))
وبالمناسبة، أنا أوصي تجنب الحاجة إلى كعب من Time.now بإعطاء الفصول الدراسية ساعة يمكن تجاوز:
class Foo
def initialize(clock=Time)
@clock = clock
end
def do_something
time = @clock.now
# ...
end
end
ولقد تم في محاولة لمعرفة كيفية تجاوز أسلوب مثيل استخدام وحدات.
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