DEV Community

Drew Bragg
Drew Bragg

Posted on

The Curious Case of the DATA Constant

If you're unfamiliar with Ruby's DATA constant don't feel too bad, it's an easy one to miss. Not only is it rare to see in the wild but out of the 9 Ruby books I own (and have actually read) only 2 of them even mention this global constant, "Programming Ruby" by Dave Thomas, commonly known as the pickaxe book, and "The Ruby Programming Language" by David Flanagan and Yukihiro Matsumoto (you know, the guy who created the language).

To understand the DATA constant we first must understand the __END__ token. If the Ruby interpreter finds an __END__ token it will stop running the program code. The first time I heard about this the presenter said that the interpreter will "ignore" anything after the token and demoed it by using it to "comment" out a chunk of code at the end of the file. This was a neat trick but unfortunately inaccurate and completely ignored the coolest part of the __END__ token.

I had all but forgotten about __END__ until @schwad brought it up at his awesome RubyConf talk (I'll post a link once the videos are publicly available). I wont spoil his talk but Nick gave me enough additional information to spark my curiosity and send me down a rabbit hole of Ruby Archaeology.

Turns out the ruby interpreter does just "ignore" anything after the token but will actually treat any after the __END__ token as data and will take the content and assign it to the DATA constant. Armed with this information, the DATA constant becomes a lot easier to understand. DATA is an IO steam. Just like opening a file and reading its contents, you can do the same thing with DATA.

So what does this look like in practice? Something like this:

# end_data_demo.rb
puts DATA.read.tr("\n", " ")

__END__
Look
at
this
data
Enter fullscreen mode Exit fullscreen mode

If you run ruby end_data_demo.rb in your terminal you'll get "Look at this data" returned.

Pretty cool, right? No? Well I think it is. Look, you can even store YAML in there:

My shitty code

Now you may be thinking, "Ok fine, that kinda cool, but why or when would I actually use this?". Well given the time of the year let me give you a more practical demo.

Many of you are doing Advent of Code. If you're doing it or have done it in Ruby you've probably done something like this to get your puzzles input:

input = File.readlines('.puzzle_input.txt')

# Your logic here
Enter fullscreen mode Exit fullscreen mode

this works but requires a separate file for you input. Here's how I'm doing AoC this year:

input = DATA.readlines

# My logic here

__END__
My
puzzle
input
Enter fullscreen mode Exit fullscreen mode

One day, one file.

DATA is a pretty cool trick but unfortunately isn't set in a multi-file application... BUT all is not lost. There are still some cool things we can do with __END__ stay tuned for the post where we'll abuse __END__ for fun and profit.

Discussion (0)