ventajas tutorial sirve rails que programar para documentacion desventajas descargar ruby

tutorial - ¿Puedes evaluar el código en el contexto de una persona que llama en Ruby?



ruby wikipedia (5)

Aquí hay un truco de sintaxis más fácil, usando un enlace de bloqueo pasado:

def loginfo &block what = yield.to_s evaled = eval(what, block.binding) Rails.logger.info "#{what} = #{evaled.inspect}" end

llamado así:

x = 1 loginfo{ :x }

se desconectará:

x = 1

Esencialmente me pregunto si se puede hacer lo siguiente en Ruby.

Así por ejemplo:

def bar(symbol) # magic code goes here, it outputs "a = 100" end def foo a = 100 bar(:a) end


No hay una forma integrada de obtener un enlace de llamantes en Ruby en 1.8.X o 1.9.X.

Puede utilizar https://github.com/banister/binding_of_caller para solucionar el problema.

En MRI 2.0 puede usar RubyVM :: DebugInspector, consulte: https://github.com/banister/binding_of_caller/blob/master/lib/binding_of_caller/mri2.rb

Muestra de trabajo en MRI 2.0:

require ''debug_inspector'' def bar(symbol) RubyVM::DebugInspector.open do |inspector| val = eval(symbol.to_s, inspector.frame_binding(2)) puts "#{symbol}: #{val}" end end def foo a = 100 bar(:a) end foo # a: 100


Revisa el artículo de Encuadernaciones Variables en Ruby

class Reference def initialize(var_name, vars) @getter = eval "lambda { #{var_name} }", vars @setter = eval "lambda { |v| #{var_name} = v }", vars end def value @getter.call end def value=(new_value) @setter.call(new_value) end end def ref(&block) Reference.new(block.call, block.binding) end def bar(ref) # magic code goes here, it outputs "a = 100" p ref.value end def foo a = 100 bar(ref{:a}) end foo


Solo para tu información, aquí hay una "manera pirata". Esta es mi (re) implementación del conocido ppp.rb:

#!/usr/bin/ruby # # better ppp.rb # require ''continuation'' if RUBY_VERSION >= ''1.9.0'' def ppp(*sym) cc = nil ok = false set_trace_func lambda {|event, file, lineno, id, binding, klass| if ok set_trace_func nil cc.call(binding) else ok = event == "return" end } return unless bb = callcc{|c| cc = c; nil } sym.map{|s| v = eval(s.to_s, bb); puts "#{s.inspect} = #{v}"; v } end a = 1 s = "hello" ppp :a, :s exit 0

Esto falla actualmente con 1.9. [012] Debido a un error en el set_trace_func de ruby.


Tienes que pasar el contexto de foo a la bar :

def foo a = 100 bar(:a, binding) end def bar(sym, b) puts "#{sym} is #{eval(sym.to_s, b)}" end