package hello::start;
nanoaのチュートリアル,1行目に書いたのはpackage宣言です.関数ではなくて宣言.この宣言は何をするかというと「ここから書く部分がhello::startというシンボルテーブルに所属するよ」ということを宣言するために書かれています.シンボルテーブルは名前空間ともいいます
最初からなんですが,よくわからなかったら飛ばしてもよいと思います.nanoaの場合パスとこの宣言が一致している(startは省略時に使われる名前,だから/nanoa.cgi/hello/start でもアクセスできます)ので,このパス(/nanoa.cgi/hello/)のプログラムにはこうやって書くおまじないと思いましょう
package宣言の範囲
package hello::start;
この宣言だと,ここから書くことはhello::startというシンボルテーブルに所属するということを意味します.この宣言は同じファイルにある次のpackage宣言までか,ファイルの終わりまで有効です.ですのでhello/start.pmというファイルに書いた内容はすべてhello::startパッケージに所属します
次のpackage宣言が出てくるとそこからは別のパッケージになります.たとえばpackage hello::endとするとそこからはhello::endパッケージになります.ただ,このファイルにhello::endパッケージを書いても,nanoaはパスとファイルとパッケージが一致すること前提なので動作しません
package hello::start; #ここからhello::startパッケージ use strict; use warnings; use utf8; use base qw(NanoA); sub run { my $app = shift; return $app->render('hello/template/start', { user => $app->query->param('user'), }) } #ここまでhello::startパッケージ package hello::end; #ここからhello::endパッケージ use strict; use warnings; use utf8; use base qw(NanoA); sub run { my $app = shift; return $app->render('hello/template/end', { user => $app->query->param('user'), }) } 1; #ここまでhello::endパッケージ
hello/end?user=lapis25で呼び出してもnot foundになります
2回package宣言する
また,1つのパッケージに対してpackage宣言を2回行うこともできます
package hello::start; use strict; use warnings; use utf8; use base qw(NanoA); package hello::end; print 'end'; package hello::start; sub run { my $app = shift; return $app->render('hello/template/start', { user => $app->query->param('user'), }) } 1;
まったく意味はないですけど,こうやって書いてもふつうに動きます.もちろんprint 'end';は実行されません
暗黙的なpackage宣言
じゃあ,このpackage宣言がひとつも書かれなかったらどうなるの?チュートリアルのファイルはちょっと複雑なのでおいといて,たとえばpkg.cgiという名前で下のコードのように書いたらpackage pkgの前の部分は何なのでしょう?
#! /usr/bin/env perl #ここのパッケージは??? package pkg; #ここはhello::startパッケージ
最初のpackage宣言より前の部分は,mainパッケージに所属します.プログラムの先頭にはpackage mainという宣言がなされていると仮定してプログラムは動きます
#! /usr/bin/env perl #package main;と宣言されてると思いねぇ #ここのパッケージはmain package pkg; #ここはhello::startパッケージ
ちなみにpackage hello::start;の前の行のパッケージはなんなのでしょうか……?ここではひとまず置いておきます
完全な修飾
完全な修飾を使うことで他のパッケージに属する変数を呼び出すこともできます.pkgパッケージの変数$hogeを他のパッケージから呼び出すには,$pkg::hogeというように書くと呼び出せます
#! /usr/bin/env perl $hoge = "hoge in main package\n"; package pkg; $hoge = "hoge in pkg package\n"; package main; print $hoge; print $pkg::hoge;
このコードはこんな感じで表示されます
$ perl test.pl hoge in main package hoge in pkg package
ちなみに$::hogeというように空のパッケージ名を指定すると,mainパッケージを指定したことになります.パッケージには変数だけじゃなくてサブルーチンやハンドルなどにも所属していて,同じようにパッケージの外からアクセスできます