サーチ…


構文

  • eval "source"
  • eval "source"、バインディング
  • eval "source"、proc
  • binding.eval「ソース」に等しい# eval "source", binding

パラメーター

パラメータ詳細
"source" 任意のRubyソースコード
binding Bindingクラスのインスタンス
proc Procクラスのインスタンス

インスタンス評価

instance_evalメソッドは、すべてのオブジェクトで使用できます。レシーバのコンテキストでコードを評価します。

object = Object.new

object.instance_eval do
  @variable = :value
end

object.instance_variable_get :@variable  # => :value

instance_evalは、コードブロックの持続時間中、 selfからobject設定しobject

object.instance_eval { self == object }  # => true

レシーバは、唯一の引数としてブロックに渡されます。

object.instance_eval { |argument| argument == object }  # => true

この点でinstance_execメソッドは異なりinstance_exec 。代わりに、引数をブロックに渡します。

object.instance_exec :@variable do |name|
  instance_variable_get name  # => :value
end

文字列の評価

実行時に任意のStringを評価できます。

class Example
  def self.foo
    :foo
  end
end

eval "Example.foo" #=> :foo

バインディング内の評価

Rubyは、バインディングと呼ばれるオブジェクトを介してローカル変数とself変数を追跡します。 Kernel#bindingを呼び出してスコープのバインディングを取得し、バインディング内の文字列をBinding#eval経由で評価することができます。

b = proc do
  local_variable = :local
  binding
end.call

b.eval "local_variable" #=> :local

def fake_class_eval klass, source = nil, &block
  class_binding = klass.send :eval, "binding"

  if block
    class_binding.local_variable_set :_fake_class_eval_block, block
    class_binding.eval "_fake_class_eval_block.call"
  else
    class_binding.eval source
  end
end

class Example
end

fake_class_eval Example, <<-BLOCK
  def self.foo
    :foo
  end
BLOCK

fake_class_eval Example do
  def bar
    :bar
  end
end

Example.foo #=> :foo
Example.new.bar #=> :bar

文字列からメソッドを動的に作成する

Rubyはdefine_methodを、新しいインスタンスメソッドを定義するためのモジュールとクラスのプライベートメソッドとして提供しています。しかし、メソッドの '本体'は、 Procまたは別の既存のメソッドでなければなりません。

生の文字列データからメソッドを作成する1つの方法は、 evalを使用してコードからProcを作成することです。

xml = <<ENDXML
<methods>
  <method name="go">puts "I'm going!"</method>
  <method name="stop">7*6</method>
</methods>
ENDXML

class Foo
  def self.add_method(name,code)
    body = eval( "Proc.new{ #{code} }" )
    define_method(name,body)
  end
end

require 'nokogiri' # gem install nokogiri
doc = Nokogiri.XML(xml)
doc.xpath('//method').each do |meth|
  Foo.add_method( meth['name'], meth.text )
end

f = Foo.new
p Foo.instance_methods(false)  #=> [:go, :stop]
p f.public_methods(false)      #=> [:go, :stop]
f.go                           #=> "I'm going!"
p f.stop                       #=> 42


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow