ruby - переопределить метод и затем вернуться
Я пытаюсь найти способ, которым я могу переопределить метод, сделать что-то, а затем вернуться, не оставляя никаких артефактов.
Я реализовал это с помощью мокко, но, очевидно, это не будет летать в производственном приложении. Обратите внимание, что новый метод имеет параметры, а старый - нет.
Пример следующим образом
require 'rubygems'
require 'mocha'
class Example
def to_something
self.stubs(:attribs => other(1))
r = attribs_caller
self.unstub(:attribs)
r
end
def other(int)
{"other" => int }
end
def attribs_caller
attribs
end
def attribs
{"this" => 1 }
end
end
a1 = Example.new
puts a1.attribs_caller #=> this1
puts a1.to_something #=> other1
puts a1.attribs_caller #=> this1
2 ответа
Другой способ сделать это, не создавая дополнительный метод, заключается в следующем:
class Foo
def bar
:old_method
end
end
Foo.new.foo # => :old_method
$old_method = Foo.new.method(:bar)
class Foo
def bar
:new_method
end
end
Foo.new.foo # => :new_method
class Foo
define_method($old_method.name, &$old_method)
end
Foo.new.foo # => :old_method
Я думаю, что это лучше, чем использование метода псевдонимов. В Ruby методы тоже являются объектами. Я просто беру ссылку на объект, прежде чем разрушить ассоциацию объекта (метода) с классом. После того, как я добавлю тот же метод. Это также работает, если вы используете undef
Ключевое слово для удаления метода из класса. Плохо то, что вам нужен объект класса, чтобы получить ссылку на метод.
class String
alias orig_reverse reverse
def reverse(n)
'fooled you. '*n
end
end
puts "ab".reverse(2)
#=> fooled you fooled you
# clean up:
class String
alias reverse orig_reverse
remove_method(:orig_reverse)
end
puts "ab".reverse #=> ba