Zoeken…


Syntaxis

  • eval "bron"
  • eval "bron", bindend
  • eval "source", proc
  • binding.eval "source" # gelijk aan eval "source", binding

parameters

Parameter Details
"source" Elke Ruby-broncode
binding Een exemplaar van Binding class
proc Een exemplaar van Proc klasse

Exemplaarevaluatie

De methode instance_eval is beschikbaar op alle objecten. Het evalueert code in de context van de ontvanger:

object = Object.new

object.instance_eval do
  @variable = :value
end

object.instance_variable_get :@variable  # => :value

instance_eval stelt self om object te object voor de duur van het codeblok:

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

De ontvanger wordt ook doorgegeven aan het blok als het enige argument:

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

De methode instance_exec verschilt in dit opzicht: in plaats daarvan worden de argumenten doorgegeven aan het blok.

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

Een string evalueren

Elke String kan tijdens runtime worden geëvalueerd.

class Example
  def self.foo
    :foo
  end
end

eval "Example.foo" #=> :foo

Evalueren in een binding

Robijn houdt lokale variabelen en self variabel via een object genoemd binding. We kunnen binding van een scope krijgen door Kernel#binding aan te roepen en string binnen een binding te evalueren via 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

Dynamisch methoden maken van tekenreeksen

Ruby biedt define_method als een define_method voor modules en klassen voor het definiëren van nieuwe instantiemethoden. De 'body' van de methode moet echter een Proc of een andere bestaande methode zijn.

Een manier om een methode te maken op basis van onbewerkte tekenreeksgegevens is door eval te gebruiken om een Proc van de code te maken:

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow