RubyのDATAという特殊なグローバル定数

Rubyにはスクリプト言語らしい機能が色々ある。::DATAを使うと、スクリプト本体の後ろにテキストデータを貼り付けておける。

def show_data
  puts "DATA: #{DATA.class}"
  DATA.each_line do |l|
    puts "line: #{l}"
  end
end

show_data

__END__
1
2
3
$ ruby data.rb
DATA: File
line: 1
line: 2
line: 3
$

DATAというのは、Fileオブジェクトで、ruby.c の load_file_internal という関数で初期化されている。

static VALUE
load_file_internal(VALUE arg)
{
      :
      :
      :
      :
      :
      :
    if (script && tree && rb_parser_end_seen_p(parser)) {
        /*
         * DATA is a File that contains the data section of the executed file.
         * To create a data section use <tt>__END__</tt>:
         *
         *   $ cat t.rb
         *   puts DATA.gets
         *   __END__
         *   hello world!
         *
         *   $ ruby t.rb
         *   hello world!
         */
        rb_define_global_const("DATA", f);
    }
    else if (f != rb_stdin) {
        rb_io_close(f);
    }
    return (VALUE)tree;
}

もしかして、これって sinatra のテンプレートでも使われてるのかな? と思って lib/sinatra/base.rb を見てみたら、

      # Load embeded templates from the file; uses the caller's __FILE__
      # when no file is specified.
      def inline_templates=(file=nil)
        file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file

        begin
          io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
          app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
        rescue Errno::ENOENT
          app, data = nil
        end

とあって、__END__を split してた。なんでだろう。