stash (スタッシュ)

パッケージのシンボルテーブル

stash (スタッシュ) とは、パッケージ(モジュール)で定義された変数や関数などのシンボルテーブルのことを指します。 もともとは Symbol Table Hash を由来とする造語のようです。 英単語の stash とは関係がないようです。 この stash によって名前空間を実現しています。

このシンボルテーブルは、パッケージごとにハッシュテーブルとして実装されています。 Perl では、このシンボルテーブル、つまり、stash を通してパッケージ内の変数や関数にアクセスすることになります。

次のコードは、変数 $name と関数 hello を外部から利用できるように定義したシンプルなパッケージです。 しかし、一つだけ内部だけで利用する変数 $age も定義されています。

our $name = 'Taro';
my $age = 43;

sub hello {
    print "Hello, ${name}\n";
}

このパッケージを読み込んで、変数 $name と関数 hello にアクセスするには、 名前空間を含んだ完全修飾名を使う必要があります。

require './MyPackage.pm';
print $MyPackage::name, "\n";    # Taro
&MyPackage::hello();             # Hello, Taro

このように完全修飾名でパッケージ内のリソースにアクセスできる仕組みを提供するのが stash (スタッシュ) です。

次のコードで、メインスクリプト側からパッケージ MyPackage の stash となるシンボルテーブルを垣間見ることができます。

use Data::Dumper;
print Dumper \%MyPackage::;

このコードは次のような結果を出力します。 ご覧の通り、外部からアクセスできるように定義した変数や関数だけが stash の対象となり、 内部変数 $age は stash には含まれていません。

$VAR1 = {
          'name' => *MyPackage::name,
          'hello' => *MyPackage::hello
        };

もちろん、メインスクリプトにも stash は用意されています。メインスクリプトの名前空間は main です。

use Data::Dumper;
print Dumper \%main::;

main の stash は次のようになります。ただし、実行環境によって大きく異なりますので注意してください。

$VAR1 = {
          '
           AST_FH' => *{'::
                           AST_FH'},
          'IO::' => *{'::IO::'},
          'INC' => *::INC,
          '/' => *{'::/'},
          'BEGIN' => *::BEGIN,
          'stderr' => *::stderr,
          'ARNING_BITS' => *{'::ARNING_BITS'},
          'Data::' => *{'::Data::'},
          'Carp::' => *{'::Carp::'},
          'ENV' => *::ENV,
          'stdin' => *::stdin,
          '' => *{'::'},
          '2' => *{'::2'},
          'DB::' => *{'::DB::'},
          'strict::' => *{'::strict::'},
          'DynaLoader::' => *{'::DynaLoader::'},
          '0' => *{'::0'},
          '@' => *{'::@'},
          '1' => *{'::1'},
          'Exporter::' => *{'::Exporter::'},
          'constant::' => *{'::constant::'},
          'E_COMPILE_RECURSION_LIMIT' => *{'::E_COMPILE_RECURSION_LIMIT'},
          'stdout' => *::stdout,
          'threads::' => *{'::threads::'},
          ',' => *{'::,'},
          '"' => *{'::"'},
          'STDERR' => *::STDERR,
          'UNIVERSAL::' => *{'::UNIVERSAL::'},
          '' => *{'::'},
          '!' => *{'::!'},
          ' => *{':'},
          'Dumper' => *::Dumper,
          'STDIN' => *::STDIN,
          'SIG' => *::SIG,
          'XSLoader::' => *{'::XSLoader::'},
          '' => *{'::'},
          'ARGV' => *::ARGV,
          'B::' => *{'::B::'},
          'STDOUT' => *::STDOUT,
          'Scalar::' => *{'::Scalar::'},
          'Regexp::' => *{'::Regexp::'},
          'bytes::' => *{'::bytes::'},
          'E_TRIE_MAXBUF' => *{'::E_TRIE_MAXBUF'},
          '' => *{'::'},
          'utf8::' => *{'::utf8::'},
          '_' => *::_,
          'PerlIO::' => *{'::PerlIO::'},
          'overload::' => *{'::overload::'},
          'warnings::' => *{'::warnings::'},
          'Internals::' => *{'::Internals::'},
          'overloading::' => *{'::overloading::'},
          'main::' => *{'::main::'},
          'version::' => *{'::version::'},
          ']' => *{'::]'},
          'CORE::' => *{'::CORE::'},
          '.' => *{'::.'},
          'mro::' => *{'::mro::'},
          're::' => *{'::re::'}
        };