ourを使うためのメモ

ourを使うと、現在のパッケージと関連付けられた変数を作れるみたいなので、
どうやって使うのか調べてみた。

our – perldoc.jp

2013/09/15 追記
$a$bは特殊パッケージ変数だから違う変数名を使った方が良い、
との指摘を貰ったので、$a$fooに置き換えて書き直しました。(*1)
— ここまで追記 —

これだけだと分からないので、実際に手を動かしてみる。

まずは、このコードから。

use strict;
use warnings;
use v5.10;

my $foo = 'hello!';
sub hoge { say $foo; }

hoge();

これは、たぶん予想通り。
$ perl aaa.pl
hello!

これだとどうだろう?

use strict;
use warnings;
use v5.10;

sub hoge { say $foo; }
my $foo = 'hello!';

hoge();

これは、ダメ。
$ perl bbb.pl
Global symbol "$foo" requires explicit package name at bbb.pl line 5.
Execution of bbb.pl aborted due to compilation errors.

じゃぁ、これならどうだろう?

use strict;
use warnings;
use v5.10;

sub hoge { say $foo; }
$foo = 'hello!';

hoge();

これも、ダメ。
$ perl ccc.pl
Global symbol "$foo" requires explicit package name at ccc.pl line 5.
Global symbol "$foo" requires explicit package name at ccc.pl line 6.
Execution of ccc.pl aborted due to compilation errors.

あれ、ourの使いどころって?
という訳で、ourを付けてみる。

use strict;
use warnings;
use v5.10;

sub hoge { say $foo; }
our $foo = 'hello!';

hoge();

うーん、ダメ。
$ perl ddd.pl
Global symbol "$foo" requires explicit package name at ddd.pl line 5.
Execution of ddd.pl aborted due to compilation errors.

次は、先ほどのリンクにあったサンプルコードを真似てみる。

package Bar;
use strict;
use warnings;

$foo = 'hello!';

package main;
use strict;
use warnings;
use v5.10;

sub hoge { say $Bar::foo; }

hoge();

これは、ダメ。
$ perl eee.pl
Global symbol "$foo" requires explicit package name at eee.pl line 5.
BEGIN not safe after errors--compilation aborted at eee.pl line 8.

次は、ourを付けてみる。

package Bar;
use strict;
use warnings;

our $foo = 'hello!';

package main;
use strict;
use warnings;
use v5.10;

sub hoge { say $Bar::foo; }
sub huga { say $foo; }

hoge();
huga();

おお、$Bar::fooだけじゃなくて、$fooでも参照できる。
$ perl fff.pl
hello!
hello!

ところで、パッケージと関連付けられた変数を作れるってことは、
パッケージmainにおける$fooも作れるのかな?

package Bar;
use strict;
use warnings;

our $foo = 'hello!';

package main;
use strict;
use warnings;
use v5.10;

sub hoge { say $foo; }

hoge();
our $foo = 'bye!';
hoge();

say '$foo       = ', $foo;
say '$main::foo = ', $main::foo;
say '$Bar::foo  = ', $Bar::foo;

うーん、これは違う。
$ perl ggg.pl
hello!
hello!
$foo = bye!
$main::foo = bye!
$Bar::foo = hello!

これならどうかな?

package Bar;
use strict;
use warnings;

our $foo = 'hello!';

package main;
use strict;
use warnings;
use v5.10;

our $foo = 'bye!';
sub hoge { say $foo; }

hoge();

これだと、パッケージmainの$fooが使われる。
$ perl hhh.pl
bye!

という訳で、メモはここまで。

おしまい。

(*1) akiymさん++

Leave a Comment