Ruby Language
गतिशील मूल्यांकन
खोज…
वाक्य - विन्यास
- eval "स्रोत"
- eval "स्रोत", बाध्यकारी
- eval "स्रोत", proc
- बाइंडिंग। एकमात्र "सोर्स" # इवल के बराबर
eval "source", binding
पैरामीटर
पैरामीटर | विवरण |
---|---|
"source" | कोई भी रूबी स्रोत कोड |
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.instance_eval { self == object } # => true
रिसीवर को इसके एकमात्र तर्क के रूप में ब्लॉक में भी भेजा जाता है:
object.instance_eval { |argument| argument == object } # => true
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
एक बंधन के अंदर मूल्यांकन
रूबी बाध्यकारी नामक वस्तु के माध्यम से स्थानीय चर और 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
गतिशील रूप से स्ट्रिंग्स से विधियाँ बनाना
रूबी नई आवृत्ति विधियों को परिभाषित करने के लिए मॉड्यूल और कक्षाओं पर एक निजी विधि के रूप में define_method
प्रदान define_method
। हालांकि, विधि का 'निकाय' एक Proc
या अन्य मौजूदा विधि होना चाहिए।
कच्चे स्ट्रिंग डेटा से एक विधि बनाने का एक तरीका कोड से एक प्रोक बनाने के लिए eval
का उपयोग करना है:
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