Zuerst können Sie keine puti
implementieren und puti a_var
aufrufen, um den Ausgang als a_var = value of a_var
zu erhalten. Am Rumpf von puti
sieht Ruby nur die formalen Parameternamen puti
, es kann die tatsächlichen Parameternamen nicht ableiten. In einer anderen Sprache wie C/C++ können Sie Macro verwenden, um Ihre puti
zu implementieren. Das ist eine andere Geschichte.
Sie können jedoch put :a_var
mit Hilfe von Continuation implementieren. In einer anderen Frage "Can you eval code in the context of a caller in Ruby?", Sony Santos hat eine caller_binding Implementierung bereitgestellt, um die Bindung des Aufrufers (etwas wie die Perl-Aufruferfunktion) zu bekommen.
Die Implementierung sollte etwas geändert werden, da callcc
den Rückgabewert des Blocks bei seiner ersten Rückgabe zurückgibt. Sie erhalten also eine Instanz von Continuation
anstelle von nil
. Hier ist die aktualisierte Version:
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
Notierte die puti
soll nicht die letzte Anweisung des Programms sein, sonst wird das Ruby-Interpreter endet mit sofortiger Wirkung und die Trace-Funktion hat keine Chance zu laufen. Das ist der Punkt der letzten "Platzhalter" -Linie.
http://stackoverflow.com/questions/1356749 Dies ist näher an Ihre Anforderung. –