Просто используйте массивы. Вы можете использовать метод Array
, чтобы гарантировать, что у вас всегда будет массив, даже если кто-то передает только одно значение:
def debug(&block)
Array(block[]).each do |var| puts "#{var} = #{eval var.to_s, block}" end
end
x, y = 3, 5
debug {:x} # => "x = 3"
debug {[:x, :y]} # => "x = 3" "y = 5"
Кстати: передача блока, поскольку привязка больше не работает в Ruby 1.9. (Несмотря на то, что в документации сказано, что работает .) Вы должны явно вызвать Proc#binding
, чтобы получить объект Binding
для этого Proc
:
def debug(&block)
Array(block.()).flatten.each do |var|
puts "#{var} = #{eval var.to_s, block.binding}"
end
end
К счастью, этот уже работает в Ruby 1.8, так что вы можете защитить свой код от использования в будущем.
Альтернативой было бы вообще отказаться от блока. Я имею в виду, что вы уже заставляете пользователя debug
использовать незнакомую идиому передачи аргументов в блоке, а не в скобках. Почему бы не заставить их просто пройти привязку вместо этого?
def debug(*vars, bnd)
vars.each do |var|
puts "#{var} = #{eval var.to_s, bnd}"
end
end
x, y = 3, 5
debug :x, binding # => "x = 3"
debug :x, :y, binding # => "x = 3" "y = 5"
Это обеспечивает дополнительную гибкость, позволяющую им фактически передавать другую привязку, чем привязка на месте вызова, например если они хотят отладить фрагмент кода в другом фрагменте приложения.
Кстати: вот немного веселья с самоанализом параметров Ruby 1.9.2 (Proc#parameters
):
def debug(&block)
block.parameters.map(&:last).each do |var|
puts "#{var} = #{eval var.to_s, block.binding}"
end
end
x, y = 3, 5
debug {|x|} # => "x = 3"
debug {|x, y|} # => "x = 3" "y = 5"