ruby - 覆盖方法然后恢复

发布于 2024-11-02 16:53:50 字数 592 浏览 4 评论 0原文

我正在尝试找到一种方法,可以覆盖方法,执行某些操作,然后在不留下任何工件的情况下进行恢复。

我已经使用 mocha 实现了这个,但显然这不会在生产应用程序中运行。请注意,新方法有参数,而旧方法没有。

示例如下

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

I am trying to find a way that I can override a method, do something, and then revert without leaving any artifacts around.

I have implemented this using mocha but obviously this is not going to fly in a production app. Notice the new method has parameters and the old one does not.

Example as follows

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往事风中埋 2024-11-09 16:53:50
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
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
抱着落日 2024-11-09 16:53:50

另一种无需创建额外方法的方法是:

class Foo
  def bar
    :old_method
  end
end

Foo.new.bar # => :old_method

$old_method = Foo.new.method(:bar)

class Foo
  def bar
    :new_method
  end
end

Foo.new.bar # => :new_method

class Foo
  define_method($old_method.name, &$old_method)
end

Foo.new.bar # => :old_method

我认为这比使用别名方法更好。在 Ruby 中,方法也是对象。我只是在破坏对象(方法)与类的关联之前获取对象的引用。我添加相同的方法后。如果您使用 undef 关键字从类中删除该方法,它也有效。不好的一点是你必须有一个类的对象来获取方法的引用。

Another way to do that, without creating an extra method, is this:

class Foo
  def bar
    :old_method
  end
end

Foo.new.bar # => :old_method

$old_method = Foo.new.method(:bar)

class Foo
  def bar
    :new_method
  end
end

Foo.new.bar # => :new_method

class Foo
  define_method($old_method.name, &$old_method)
end

Foo.new.bar # => :old_method

I think that this is better than using an alias method. In Ruby methods are, also, objects. I just take the reference of the object before destructing the association of the object (the method) with the class. After I add the same method. It also works if you use the undef keyword to remove the method from the class. The bad point is that you have to have an object of the class to take the reference of the method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文