Skip to content

Perlの__DATA__

2022年4月13日

とある日のPerlスクリプト

このようなPerlスクリプトを見かけた

use strict;
use warnings;
use JSON::PP;

my @users;

while (my $line = <DATA>) {
  if ($line =~/^(@\w+)/) {
    push(@users, {id => $1, done => \0});
  }
}

print encode_json(\@users);


__DATA__

@e18....
 -
matac
e18....@ie.u-ryukyu.ac.jp
...

__DATA__というリテラルがあって、それ以降の文字列はコードではなくただのテキストのようだ。なんとなく読んでみると、これは__DATA__以降のテキストを1行ずつ読み込んで、正規表現でマッチした部分を使ってjsonを生成しているように思える。__DATA__以降は標準入力になるような感じだろうか。

DATAとは何か

perldocによるとこれはSpecial Literalsの一種である。Special Literalsには他に__FILE____LINE____PACKAGE____SUB__がある。これらを出力してみる。

use 5.16.0;
use strict;
use warnings;
use utf8;

sub matac {
    return __SUB__;
}

say __FILE__;
say __LINE__;
say __PACKAGE__;
say matac;
say <DATA>;

__DATA__
hoge
$perl test.pl
test.pl
12
main
CODE(0x123025570)
hoge

何に使うか

たしか、Pythonを授業で習ったときにもこういった特殊な変数みたいなのがあったはずだ。それは、以下のようなものだった。モジュールによって処理を切り分けたいときに使う。

if __name__ == "__main__":

__PACKAGE____LINE____FILE__もきっと同じような感じで使うのだろう。 __DATA__に関しては、実装と入力を一つのファイルにすることで、そのスクリプトの使い方を察しやすくするとか、標準入力に毎回コピペするの面倒な時に使えるかもしれない。スクリプトはそれ単体になってしまうと、スクリプトを読める人がいない限り使い方がわからなくなってしまう問題があるので、スクリプトの中にどのようなものを渡したら良いかが、置いてあるのは良いかもしれない。しかしながら、実際スクリプトを作るときはREADMEも一緒に置いておくのが正解だろう。