Carina C. Zona bio photo

Carina C. Zona

Email Twitter LinkedIn

Ruby's DATA object makes it possible to do neat little tricks like storing templates and datafiles within the script that uses it.


#!/usr/bin/env ruby
DATA.class # File
DATA.read # 'now we have a DATA object'
...
__END__
now we have a DATA object

But accessing it from external files, including test suites, is a pain. Only the original file can see the DATA object. Ruby raises a NameError exception, complaining that the 'DATA' constant is undefined.

Working around this can be easy when you keep in mind that DATA is just another I/O object. So you can, for instance, create a substitute File object. And, like any other File object, if you're going to read it repeatedly you need to reset the pointer for each read.


if Module.const_defined?(:DATA)
SOURCE=DATA
POSITION=SOURCE.pos
else
SOURCE=File.new(__FILE__)
POSITION=File.read(SOURCE).match(/^__END__.*$/).offset(0)[1]+1
end

def data
SOURCE.pos=POSITION
SOURCE.read
end