Подтвердить что ты не робот

Блок Ruby для строки вместо выполнения

Возьмем этот пример:

write_as_string { puts 'x' }

Затем я хочу иметь возможность делать

def write_as_string(&block)
  puts block.to_s
end

Когда я выполняю это, я хочу, чтобы результат был:

"puts 'x'"

Я хочу иметь возможность получить блок и получить фактический код для блока вместо его выполнения.

Мотивация: создавая DSL, я хочу, чтобы макет был преобразован в ряд других вызовов методов, скрытых от вызывающего кода - с использованием существующих объектов и методов без их исправления.

Любые идеи об этом были бы замечательными!

Спасибо

Бен

4b9b3361

Ответ 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\") }"