首先,您不能執行puti
並直接調用puti a_var
以獲得輸出爲a_var = value of a_var
。在puti
的主體上,Ruby只看到puti
的形式參數名稱,它不能推斷出實際的參數名稱。
在其他語言如C/C++中,您可以使用Macro來實現您的puti
。這是另一個故事。
但是,可以實現put :a_var
,與Continuation幫助。在另一個問題「Can you eval code in the context of a caller in Ruby?」中,Sony Santos提供了一個caller_binding實現來獲取調用者的綁定(類似於perl調用者函數)。
實施應該改變一下,因爲callcc
返回在其第一次返回塊的返回值。所以你會得到Continuation
的實例,而不是nil
。以下是更新版本:
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
注puti
不應該是你的程序的最後陳述,否則Ruby解釋器將立即終止與跟蹤功能就沒有機會跑。所以這就是最後一個「佔位符」線的重點。
http://stackoverflow.com/questions/1356749這更接近您的要求。 – 2013-03-26 13:52:43