2010-01-17 7 views
17

Tome este ejemplo:bloque de Ruby a cadena en lugar de ejecutar

write_as_string { puts 'x' } 

entonces yo quiero ser capaz de hacer

def write_as_string(&block) 
    puts block.to_s 
end 

Cuando ejecuto esto, quiero que la salida sea:

"puts 'x'" 

Quiero ser capaz de recibir el bloque y obtener el código real para el bloque en lugar de ejecutarlo.

Motivación: Al crear una DSL, quiero que la simulación se convierta en una serie de otras llamadas al método, ocultas al código de llamada, utilizando los objetos y métodos existentes sin que el mono las parchee.

¡Cualquier idea sobre esto sería genial!

Gracias

Ben

Respuesta

1

desea que el ruby2ruby gem, lo que lo hace muy bien. Desafortunadamente, para analizar un bloque, esta gema depende de ParseTree, que es unsupported in Ruby 1.9.

+0

Eso parece genial. Pero dado el siguiente ejemplo, necesito de alguna manera obtener el bloque definido como una cadena. ¿Cómo podría hacer esto? rubí = "def \ n pone 'A' \ nend \ n \ NDEF b \ na \ nend" parser = RubyParser.new ruby2ruby = Ruby2Ruby.new sexp = parser.process (rubí) O tener Me perdí algo? –

+0

si no le preocupa la compatibilidad con 1.9, recomendaré la respuesta de @ mletterle. – austinfromboston

3

duplicado: Printing the source code of a Ruby block

sudo gem install ParseTree 
sudo gem install ruby2ruby 

continuación

require 'rubygems' 
require 'parse_tree' 
require 'parse_tree_extensions' 
require 'ruby2ruby' 

def block_as_string &block 
    block.to_ruby 
end 

resultados en

irb(main):008:0> block_as_string {puts 'x'} 
=> "proc { puts(\"x\") }" 
18

Si estás en Ruby 1.9, puede utilizar la gema sourcify. Proporciona ProC# to_source, que es como ProC# to_ruby de ParseTree.

Al utilizar sourcify, si ha anidado procsos en el código fuente, puede que tenga que ayudar a que junto con la: attached_to opción:

## (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 

he publicado acerca ParseTree and Ruby 1.9 en el blog de mi empresa.

+0

Tuve suerte con la gema source_method para Ruby 2.1.2 (que pry incluye como una dependencia, por lo que ya estaba disponible en nuestra infraestructura de prueba donde la necesitaba). Tengo una respuesta detallada aquí: http://stackoverflow.com/questions/1675053/printing-the-source-code-of-a-ruby-block/36654421#36654421 – Nick

Cuestiones relacionadas