Suche…


Syntax

  • eval "Quelle"
  • eval "source", verbindlich
  • eval "source", proc
  • binding.eval "source" # gleich eval "source", binding

Parameter

Parameter Einzelheiten
"source" Beliebiger Ruby-Quellcode
binding Eine Instanz der Binding Klasse
proc Eine Instanz der Proc Klasse

Instanzbewertung

Die Methode instance_eval ist für alle Objekte verfügbar. Es wertet Code im Kontext des Empfängers aus:

object = Object.new

object.instance_eval do
  @variable = :value
end

object.instance_variable_get :@variable  # => :value

instance_eval setzt self für die Dauer des Codeblocks auf object :

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

Der Empfänger wird auch als einziges Argument an den Block übergeben:

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

Die instance_exec Methode unterscheidet sich in dieser Hinsicht: Sie übergibt stattdessen ihre Argumente an den Block.

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

Einen String auswerten

Jeder String kann zur Laufzeit ausgewertet werden.

class Example
  def self.foo
    :foo
  end
end

eval "Example.foo" #=> :foo

Auswerten innerhalb einer Bindung

Ruby verfolgt die Spuren von lokalen Variablen und self Variable über ein Objekt namens Bindung. Wir können die Bindung eines Bereichs mit der aufrufenden Kernel#binding und die Zeichenfolge innerhalb einer Bindung über Binding#eval auswerten.

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

Methoden dynamisch aus Strings erstellen

Ruby bietet define_method als private Methode für Module und Klassen zur Definition neuer Instanzmethoden. Der 'Rumpf' der Methode muss jedoch eine Proc oder eine andere vorhandene Methode sein.

Eine Methode zum Erstellen einer Methode aus Roh-String-Daten besteht darin, eval zum Erstellen eines Proc aus dem Code zu verwenden:

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow