tags:

views:

375

answers:

2

I'm using this Ruby trick with __END__ and DATA to put some data inside my program file:

class Foo
  def initialize()
    puts DATA.read.inspect
  end
end
puts DATA.read.inspect
Foo.new
__END__
test

This generates the following output:

"test"
""

I had assumed DATA would be the same globally, but inside the class it has no content. How would I get access to the data after __END__ inside a class (apart from the obvious and ugly solution using global variables)?

ADDED: I see how reading DATA twice gives me nothing the second time. I could use rewind to get back to the start, but read then gives me the entire source code of my program. Is there an easier way to get to just the part after __END__ on subsequent uses of DATA, or would I be better of reading it once and storing it somewhere else for future use?

+5  A: 

DATA is the same. You would get the same output if instead of doing Foo.new you would do DATA.read a second time.

This is because after the first read DATA (which is an IO) has reached the end of the stream, so any further reads will return an empty string, unless you append additional data to DATA or rewind DATA to the beginning of the stream.

Edit: To seek back to the point right after the __END__ you have to read DATA.pos before performing any reading on DATA and then restore pos to that value after reading. The easiest solution is probably just doing FOO = DATA.read at the beginning of the script and then using FOO.

sepp2k
+1  A: 

rewind DATA first, because it's a stream.

class Foo
  def initialize()
    DATA.rewind
    puts DATA.read.inspect
  end
end
puts DATA.read.inspect
Foo.new
__END__
test
ChaosR
This seems to give me the entire contents of the file, not just the part after `__END__`.
avdgaag