有一个方法重新定义另一个类的方法

时间:2013-02-18 19:44:07

标签: ruby

我有一个带有简单方法定义的简单类

class Printer
  def print
    p '1'
  end
end

现在我介绍一个单独的脚本,通过添加一些额外的东西来重新定义打印方法

class Printer

  alias :old_print :print
  def print
    old_print
    p '2'
  end
end

我可以通过编程方式执行此操作吗?

module Test

  def self.redefine_print(arg)
    # redefine Printer's print method so that it will print all of the stuff it should
    # print, followed by the arg I specified
  end
end

示例交互可能看起来像

>>>a = Printer.new
>>>a.print
1
>>>Test.redefine_print("new stuff")
>>>a.print
1
new stuff
>>>Test.redefine_print("more")
>>>a.print
1
new stuff
more

如果现有实例受更改影响,则可以(因为将创建任何打印机实例,进行打印,然后立即处理)

1 个答案:

答案 0 :(得分:0)

您可以使用define_method或模块,但它有点过分(可能非常慢)。可以(并且更简单)使用类变量和类方法:

class Printer
  @@tokens = []

  def print
    @@tokens.each do |token|
      p token
    end
  end

  def self.add_token(token)
    @@tokens << token
  end
end

Printer.add_token("foo")

printer = Printer.new
printer.print
# foo

Printer.add_token("bar")
printer.print
#foo
#bar

要回答您的问题,可以使用class_evaldefine_method重新定义其他课程的方法:

class Printer
  def print
    p '1'
  end
end

module Test
  def self.redefine_print(arg)
    old_print = Printer.instance_method(:print)
    Printer.class_eval do
      define_method(:print) do
        old_print.bind(self).call
        p arg
      end
    end
  end
end

printer = Printer.new
printer.print
# 1

Test.redefine_print("new stuff")
printer.print
# 1
# new stuff

Test.redefine_print("more")
printer.print
# 1
# new stuff
# more