In primo luogo, non è possibile implementare uno puti
e chiamare direttamente puti a_var
per ottenere l'output come a_var = value of a_var
. Nel corpo di puti
, Ruby vede solo i nomi dei parametri formali di puti
, non può dedurre i nomi dei parametri effettivi.
In un altro linguaggio come C/C++, è possibile utilizzare Macro per implementare il proprio puti
. Questa è un'altra storia.
Tuttavia, è possibile implementare put :a_var
, con l'aiuto di Continuation. In un'altra domanda "Can you eval code in the context of a caller in Ruby?", Sony Santos ha fornito un'implementazione caller_binding per ottenere l'associazione del chiamante (qualcosa come la funzione perl chiamante).
L'implementazione deve essere modificata un po ', perché callcc
restituisce il valore di ritorno del blocco al suo primo ritorno. Quindi otterrai un'istanza di Continuation
anziché nil
. Ecco la versione aggiornata:
require 'continuation' if RUBY_VERSION >= '1.9.0'
def caller_binding
cc = nil # must be present to work within lambda
count = 0 # counter of returns
set_trace_func lambda { |event, file, lineno, id, binding, klass|
# First return gets to the caller of this method
# (which already know its own binding).
# Second return gets to the caller of the caller.
# That's we want!
if count == 2
set_trace_func nil
# Will return the binding to the callcc below.
cc.call binding
elsif event == "return"
count += 1
end
}
# First time it'll set the cc and return nil to the caller.
# So it's important to the caller to return again
# if it gets nil, then we get the second return.
# Second time it'll return the binding.
return callcc { |cont| cc = cont; nil }
end
# Example of use:
def puti *vars
return unless bnd = caller_binding
vars.each do |s|
value = eval s.to_s, bnd
puts "#{s} = #{value.inspect}"
end
end
a = 1
b = 2
puti :a, :b
e = 1 # place holder...
# => a = 1
# b = 2
Annotare il puti
non dovrebbe essere l'ultima istruzione del programma, altrimenti l'interprete ruby terminerà immediatamente e la funzione di traccia non ha alcuna possibilità di correre. Questo è il punto dell'ultima linea "segnaposto".
fonte
2013-03-26 14:43:40
http://stackoverflow.com/questions/1356749 Questo è più vicino alle vostre esigenze. –