2010-01-17 22 views
17

Weźmy ten przykład:Ruby blok ciąg zamiast wykonania

write_as_string { puts 'x' } 

Następnie chcę, aby móc zrobić

def write_as_string(&block) 
    puts block.to_s 
end 

Kiedy wykonać to, chcę wyjście będzie:

"puts 'x'" 

Chcę być w stanie odebrać blok i uzyskać rzeczywisty kod bloku zamiast go wykonywać.

Motywacja: Tworzenie DSL, chcę, aby próbę można było przekonwertować na wiele innych wywołań metod, ukrytych przed wywołującym kodem - przy użyciu istniejących obiektów i metod bez ich łatania przez małpy.

Wszelkie pomysły na ten temat będą świetne!

Dzięki

Ben

Odpowiedz

1

Chcesz ruby2ruby gem, który robi to dobrze. Niestety, analiza bloku zależy od ParseTree, czyli od unsupported in Ruby 1.9.

+0

To wydaje się fajne. Ale biorąc pod uwagę następujący przykład, potrzebuję jakoś uzyskać zdefiniowany blok jako ciąg znaków. Jak mogłem to zrobić? rubin = "def \ n Umieszcza 'A' \ Nend \ n \ ndef b \ nA \ Nend" parser = RubyParser.new ruby2ruby = Ruby2Ruby.new s-wyrażenie = parser.process (rubinowy) albo mieć Coś przeoczyłem? –

+0

jeśli nie zależy Ci na kompatybilności z 1.9, polecam odpowiedź @ mletterle. – austinfromboston

3

Duplikat: Printing the source code of a Ruby block

sudo gem install ParseTree 
sudo gem install ruby2ruby 

następnie

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

def block_as_string &block 
    block.to_ruby 
end 

skutkuje

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

Jeśli jesteś na Ruby 1.9, można użyć sourcify gem. Dostarcza ProC# to_source, który jest podobny do ProC# to_ruby ParseTree.

Podczas korzystania sourcify, jeśli procs zagnieżdżone w kodzie źródłowym, może trzeba pomóc go razem z: attached_to opcję:

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

napisałem o ParseTree and Ruby 1.9 w blogu mojej firmy.

+0

Miałem szczęście z gem gem source_method dla Ruby 2.1.2 (którego wersja zawiera jako zależność, więc była już dostępna w naszej infrastrukturze testowej, gdzie go potrzebowałem). Mam szczegółową odpowiedź tutaj: http://stackoverflow.com/questions/1675053/printing-the-source-code-of-a-ruby-block/36654421#36654421 – Nick

Powiązane problemy