3

次のコードがあります。

code = "def hi; \"hi!\"; end"
eval code

hi == "hi!" # true

method にアクセスできます。hiこれは、評価されたコードで定義されている場合、メイン オブジェクトのメソッドとして定義されているためです。

ただし、これは、評価されたコードが、その外部で定義したものにアクセスできることも意味します。

def hi; "hi!"; end
eval "hi == \"hi\"" # => true

評価されたコードを実行できる別の名前空間が必要です。どうすればいいですか?

名前空間のモジュールをいじってmodule_eval使用しようとしましたが、メソッドまたはクラスを定義して別の評価でアクセスすることはできません。

4

2 に答える 2

3

次のように、オブジェクト内のコードを評価できます。

  module DSL
    def helper_method_to_be_used_by_evaled_code
      # ...
    end

    # ...
  end

  container = Object.new
  container.extend(DSL)
  File.open(eval_file1, 'r') {|f| container.instance_eval(f.read, eval_file1)}
  File.open(eval_file2, 'r') {|f| container.instance_eval(f.read, eval_file2)}

これにより、評価間で定義を保持するかどうかを制御できcontainerます。インスタンスを再利用するか、破棄して新しいインスタンスを作成できます。これはメソッド定義と定数で機能し、ローカル変数はそのような呼び出し間で保持されません。

また、代わりにパターンObjectを見たい場合もあります。BlankStateblankslate」は一例です。

于 2012-08-26T17:27:10.433 に答える
0

モジュールを評価されたコードの一部にすることについて話しているようには見えないので、次のようなものは問題なく機能するはずです。

module EvalMethods
  class << self
    code = "def hi; \"hi!\"; end"
    eval code
  end
end

puts EvalMethods::hi == "hi!"
于 2012-08-26T17:00:55.950 に答える