Sök…


Syntax

  • eval "källa"
  • eval "källa", bindande
  • eval "källa", proc
  • bindande.eval "källa" # lika med eval "source", binding

parametrar

Parameter detaljer
"source" Alla Ruby källkoder
binding En instans av Binding klass
proc En instans av Proc klassen

Instansutvärdering

Metoden instance_eval är tillgänglig på alla objekt. Den utvärderar koden i samband med mottagaren:

object = Object.new

object.instance_eval do
  @variable = :value
end

object.instance_variable_get :@variable  # => :value

instance_eval ställer in mig self som object under kodblocket:

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

Mottagaren överförs också till blocket som dess enda argument:

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

Metoden instance_exec skiljer sig i detta avseende: den överför sina argument till blocket istället.

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

Utvärdera en sträng

Alla String kan utvärderas vid körning.

class Example
  def self.foo
    :foo
  end
end

eval "Example.foo" #=> :foo

Utvärdera inuti ett bindande

Ruby håller reda på lokala variabler och self variabel via ett objekt kallas bindning. Vi kan få bindning av en omfattning med att ringa Kernel#binding och utvärdera sträng i en bindning 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

Dynamiskt skapande av metoder från strängar

Ruby erbjuder define_method som en privat metod för moduler och klasser för att definiera nya instansmetoder. Men metodens "kropp" måste vara en Proc eller en annan befintlig metod.

Ett sätt att skapa en metod från rå strängdata är att använda eval att skapa en Proc från koden:

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow