3

これに似た、クラスのいくつかのメソッドを動的に定義する宝石を使用しています。

class << self
  some_strings.each do |string|
    eval <<-RUBY
      def #{string}
      ....
      end
    RUBY
  end
end

これらの動的に定義されたメソッドで発生した例外には、役に立たないバックトレースがあります。(eval):2実際の行番号ではなく、次のようなものになります。

次の行に沿ってこのコードを変更したいと思います。

eval <<-RUBY, nil, __FILE__, __LINE__ + 1

...より良いバックトレースを得るために。

ただし、 and とは異なりclass_evalinstance_evalplain oldevalにはオプションのbindingパラメーターがあり、上に示したように、それに渡すのが良い考えかどうかはわかりませんnil

それは機能しているようで、eval のドキュメントには、バインディングはオプションであると書かれています:

If binding is given, which must be a Binding object, the evaluation is 
performed in its context.

それでも、バインディングと動的評価についてまだよく理解していないので、役立つ説明が欲しいです。

class << selfブロック内のコードを動的に評価し、有用なバックトレースを確保する正しい方法は何ですか?

4

1 に答える 1

1

バインディングはあなたが探している解決策ではありません。なぜなら、それらはすべてのコンテキストを変更するだけでありeval、それはすでにあなたが望むコンテキストにあるからです。

evalより良い方法は、文字列をできるだけ避けることです。Rubyには、ごくまれなケースを除いて、文字列の評価を回避できるメタプログラミングヘルパーメソッドが多数あります。

あなたの特定の例では、それは役に立つように見えるModule#define_methodObject#define_singleton_method、役に立つかもしれません。

于 2012-08-21T04:30:35.223 に答える