수색…


통사론

  • eval "source"
  • eval "source", 바인딩
  • eval "source", proc
  • binding.eval "source"# eval "source", binding 동일 함 eval "source", binding

매개 변수

매개 변수 세부
"source" 모든 Ruby 소스 코드
binding Binding 클래스의 인스턴스
proc Proc 클래스의 인스턴스

인스턴스 평가

instance_eval 메소드는 모든 오브젝트에서 사용 가능합니다. 그것은 수신기의 맥락에서 코드를 평가합니다 :

object = Object.new

object.instance_eval do
  @variable = :value
end

object.instance_variable_get :@variable  # => :value

instance_eval 은 코드 블록이 지속되는 동안 selfobject 로 설정합니다.

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

바인딩 내부에서 평가하기

Ruby는 바인딩이라는 객체를 통해 로컬 변수와 self 변수를 추적합니다. Kernel#binding 을 호출하여 범위의 바인딩을 가져올 수 있으며 Binding#eval 통해 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

동적으로 문자열에서 메서드 만들기

Ruby는 define_method 를 새로운 인스턴스 메소드를 정의하기위한 모듈과 클래스에 대한 private 메소드로 제공합니다. 그러나 메서드의 '본문'은 Proc 또는 다른 기존 메서드 여야합니다.

원시 문자열 데이터에서 메서드를 만드는 한 가지 방법은 eval 을 사용하여 코드에서 Proc를 만드는 것입니다.

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
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow