2010-01-28 14 views
9

È possibile accedere al testo dopo __END__ in un file rubino diverso dallo script "principale"?Posso accedere ai DATI da uno script richiesto in Ruby?

Ad esempio:

# b.rb 
B_DATA = DATA.read 
__END__ 
bbb 

.

# a.rb 
require 'b' 
A_DATA = DATA.read 
puts 'A_DATA: ' + A_DATA 
puts 'B_DATA: ' + B_DATA 
__END__ 
aaa 

.

C:\Temp>ruby a.rb 
A_DATA: 
B_DATA: aaa 

Esiste un modo per arrivare al "BBB" da b.rb?

risposta

6

Sfortunatamente, la costante globale DATA viene impostata quando viene caricato lo script "principale". Alcune cose che potrebbero essere d'aiuto:

È possibile almeno A_DATA essere corretto. Basta invertire l'ordine delle prime due operazioni in a.rb:

# a.rb 
A_DATA = DATA.read 
require 'b' 
... 

È possibile ottenere il B_DATA essere corretto se si passa attraverso un po 'di manfrina:

# load_data_regardless_of_main_script.rb 
module LoadDataRegardlessOfMainScript 
    def self.from(file) 
    # the performance of this function could be 
    # greatly improved by using a StringIO buffer 
    # and only appending to it after seeing __END__. 
    File.read(file).sub(/\A.*\n__END__\n/m, '') 
    end 
end 

# b.rb: 
require 'load_data_regardless_of_main_script' 
B_DATA = LoadDataRegardlessOfMainScript.from(__FILE__) 
+0

Questa espressione funziona anche per ottenere le cose dopo __END__: s = ~/^ __ END __ \ n/&& $ ' –

+0

'File.read (__ FILE __) ...' dovrebbe essere 'File.read (file) ... 'nel metodo' from'. –

+0

buona presa, glenn. –

4

Implementare @ suggerimento di James da usare StringIO :

require 'stringio' 
module LoadDataRegardlessOfMainScript 
    def self.from(filename) 
    data = StringIO.new 
    File.open(filename) do |f| 
     begin 
     line = f.gets 
     end until line.match(/^__END__$/) 
     while line = f.gets 
     data << line 
     end 
    end 
    data.rewind 
    data 
    end 
end 

Poi b.rb diventa

require 'load_data_regardless_of_main_script' 
B_DATA = LoadDataRegardlessOfMainScript.from(__FILE__).read 
+0

+1 per essere meno pigro di me :) –

+0

Più come +1 per un ottimo esempio – RyanScottLewis

+0

+1 per un ottimo esempio! Un cambiamento che ho fatto è usare 'until line.nil? o line.match (/^__ END __ $ /) '. In questo modo il metodo può essere eseguito su qualsiasi file ruby ​​senza sapere in anticipo se ha una sezione 'DATA'. – Sharpie

Problemi correlati