Ruby Language
Dynamisk utvärdering
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