Is it possible to access the text after __END__
in a ruby file other than the "main" script?
For example:
# 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
Is there any way to get at the "bbb" from b.rb?
Unfortunately, the DATA
global constant is set when the "main" script is loaded. A few things that might help:
You can at least get A_DATA
to be correct. Just reverse the order of the first two operations in a.rb
:
# a.rb
A_DATA = DATA.read
require 'b'
...
You can get the B_DATA
to be correct if you go through a bit of rigamarole:
# 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__)
Implementing @James's suggestion to use 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
Then b.rb becomes
require 'load_data_regardless_of_main_script'
B_DATA = LoadDataRegardlessOfMainScript.from(__FILE__).read
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With