2010-01-28 16 views

Respuesta

6

Desafortunadamente, la constante global DATA se establece cuando se carga la secuencia de comandos "principal". Algunas cosas que pueden ayudar:

Usted puede al menos obtener A_DATA para ser correcto. Sólo invertir el orden de las dos primeras operaciones en a.rb:

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

se puede obtener el B_DATA ser correcto si vas a través de un poco de galimatías:

# 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

Esta expresión también funciona para obtener el material después de __END__: s = ~/^ __ END __ \ n/&& $ ' –

+0

'File.read (__ FILE __) ...' debe ser 'File.read (file) ... 'en el método' from'. –

+0

buena captura, Glenn. –

4

La implementación @ sugerencia de James usar 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 

Entonces se convierte en b.rb

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

+1 por ser menos perezoso que yo :) –

+0

Más como +1 para un gran ejemplo – RyanScottLewis

+0

+1 para un gran ejemplo también! Un cambio que hice fue usar 'hasta line.nil? o line.match (/^__ END __ $ /) '. De esta forma, el método puede ejecutarse contra cualquier archivo ruby ​​sin saber de antemano si tiene una sección 'DATA'. – Sharpie

Cuestiones relacionadas