Блок Ruby для строки вместо выполнения
Возьмем этот пример:
write_as_string { puts 'x' }
Затем я хочу иметь возможность делать
def write_as_string(&block)
puts block.to_s
end
Когда я выполняю это, я хочу, чтобы результат был:
"puts 'x'"
Я хочу иметь возможность получить блок и получить фактический код для блока вместо его выполнения.
Мотивация: создавая DSL, я хочу, чтобы макет был преобразован в ряд других вызовов методов, скрытых от вызывающего кода - с использованием существующих объектов и методов без их исправления.
Любые идеи об этом были бы замечательными!
Спасибо
Бен
Ответы
Ответ 1
Если вы используете Ruby 1.9, вы можете использовать драгоценный камень sourcify. Он предоставляет ProС# to_source, который похож на ParseTree ProС# to_ruby.
При использовании sourcify, если у вас есть вложенные procs в исходном коде, вам может понадобиться помощь с параметром: attach_to:
## (Works in Ruby 1.8) Using ParseTree (with parse_tree_extensions)
block.to_ruby
## (Works in Ruby 1.9) Using sourcify
block.to_source
## Try this if you get Sourcify::NoMatchingProcError or Sourcify::MultipleMatchingProcsPerLineError
block.to_source :attached_to => :name_of_block_in_source_code
Я разместил о ParseTree и Ruby 1.9 в своем блоге компании.
Ответ 2
Дубликат: Печать исходного кода блока Ruby
sudo gem install ParseTree
sudo gem install ruby2ruby
затем
require 'rubygems'
require 'parse_tree'
require 'parse_tree_extensions'
require 'ruby2ruby'
def block_as_string &block
block.to_ruby
end
приводит к
irb(main):008:0> block_as_string {puts 'x'}
=> "proc { puts(\"x\") }"
Ответ 3
Вы хотите ruby2ruby gem, который делает это красиво. К сожалению, для анализа блока этот камень зависит от ParseTree, который не поддерживается в Ruby 1.9.