0

単純なメソッド定義を持つ単純なクラスがあります

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

既存のインスタンスが変更の影響を受けても問題ありません (Printer のインスタンスが作成され、印刷が実行され、すぐに破棄されるため)

4

1 に答える 1

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

ただし、質問に答えるために、andを使用して他のクラスのメソッドを再定義することができclass_evalますdefine_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
于 2013-02-18T20:01:18.510 に答える