our


前回のlocal妥協に伴い、いろいろ調べていくうちにlocalより先にourやったほうがわかりやすいんじゃないかと思ったので先にourから。

our


http://d.hatena.ne.jp/perlcodesample/20080311/1205249391

### パッケージ変数の宣言
# ・パッケージ変数の宣言は、our で行う。
# ・パッケージ変数の宣言により、
# 1. パッケージ変数が生成され、
# 2. 完全修飾名を、修飾されない変数名で参照できる。
# ( $SomePackgae::var を $var で参照できるということ。)

パッケージ変数


http://d.hatena.ne.jp/perlcodesample/20080308/1204953841

# パッケージ変数
# ・パッケージ変数とは、名前空間に属するグローバル変数である。
# ・つまり、パッケージ変数は、修飾名(パッケージ名)を持ち、
# ソースコードのどの位置からでも参照できるということです。

名前空間


http://d.hatena.ne.jp/perlcodesample/20080615/1213501216

Perlでは、すべてのサブルーチンは、名前空間に属します。Perlでは、名前空間のことをパッケージと呼びます。

パッケージ


http://www.geocities.jp/ky_webid/perl5/036.html

明示的にパッケージを使わなくとも、暗黙のうちに main という名前のパッケージが使われています。通常、これを意識する必要はありませんが、明示的に書くこともできます。

mainパッケージ


http://d.hatena.ne.jp/perlcodesample/20080313/1205429891

mainパッケージ

* パッケージの宣言が行われない場合、ourで宣言されたパッケージ変数は、mainパッケージに属する。

Perlの変数の種類

* Perlには、グローバル変数は、存在せず、パッケージ変数とレキシカル変数しか存在しない。
* グローバル変数のように見えるものは、実は、mainパッケージに属している。

ourへ戻る

#!/usr/bin/perl
use strict;
use warnings;
 
our $global = "abc";
 
print "$global\n";
 
# scope1
{
	print "in scope1 = $global\n";
}
 
print "$main::global\n";

C:\MyWorks\Perl\our>perl our1.pl
abc
in scope1 = abc
abc


おさらいすると

  • パッケージを省略した場合はデフォルトでmainパッケージになる
  • ここでの$globalはmainパッケージのグローバル変数
  • パッケージの中にいるときは修飾名なしでアクセスできる


ということでいいのかな。

パッケージを指定してやってみる。

#!/usr/bin/perl
use strict;
use warnings;
 
package pkg;
my $pkgmy = 10;
 
print "pkg:: $pkgmy\n";
 
our $pkgmy;
 
package main;
 
print "main->pkg:: $pkg::pkgmy\n";

Use of uninitialized value in concatenation (.) or string at our2.pl line 14.
pkg:: 10
main->pkg::


初期化されてないときた。

pkg:: 10
main->pkg:: 10

というのを想定していたがならなかった。なぜか。
単純にmyとourを理解していなかった。

myはスコープ内でローカルという意味で、パッケージの下に書いたとしてもこの場合はファイルスコープのmy、つまりmainパッケージのmyということ。
で、ourはmyをパッケージ変数に変換してくれると勝手に勘違いしていた。

というわけでやり直し。

#!/usr/bin/perl
use strict;
use warnings;
 
package pkg;
our $pkgour = 10;
 
print "pkg:: $pkgour\n";
 
package main;
 
print "main->pkg:: $pkg::pkgour\n";

C:\MyWorks\Perl\our>perl our3.pl
pkg:: 10
main->pkg:: 10


まあこんなコード書いても何が便利なのかわからないけど、おそらくクラスのプロパティとかで使うのかなあというわけで書いてみたが

package pkg;
{
	our $pkgour 10;
}
print "main->pkgour:: $pkg::pkgour\n";


こんなの書いたら豪快にエラーがきた。
JavaScriptだとこれでいけるのにPerlはダメらしい。

{
	package pkg;
	our $pkgour 10;
}
print "main->pkgour:: $pkg::pkgour\n";


こう書くといける。
となると疑問があって、メソッドなんか書く場合

http://d.hatena.ne.jp/perlcodesample/20080612/1213415372

  • サブルーチンは、スコープの影響を受けません。
  • 一見すると、fucnは、スコープの外では、見えないものと思ってしまいがちですが、そうなりません。
  • サブルーチンの定義は、コンパイル時に、シンボルテーブルというものに登録されます。シンボルテーブルは、プログラムのどこからでも参照することができるため、サブルーチンも、プログラムのどこからでも参照できます。( スコープの影響を受けないということ )


と書いてるところをみると、1つのファイルスコープ内でパッケージに属するメソッドって書けないようにみえるがパッケージの場合は特別なんだろうか。

というわけでやってみる。

#!/usr/bin/perl
use strict;
use warnings;
 
{
	package pkg;
	our $pkgour = 10;
	my $pkgmy = 20;
 
	sub pkgsub
	{
		print "$pkgmy\n";
	}
}
 
print "main->pkgour:: $pkg::pkgour\n";
pkgsub();

C:\MyWorks\Perl\our>perl our4.pl
Undefined subroutine &main::pkgsub called at our4.pl line 17.
main->pkgour:: 10


ちゃんとエラーでた。

#!/usr/bin/perl
use strict;
use warnings;
 
{
	package pkg;
	our $pkgour = 10;
	my $pkgmy = 20;
 
	sub pkgsub
	{
		print "$pkgmy\n";
	}
}
 
print "main->pkgour:: $pkg::pkgour\n";
pkg->pkgsub();

C:\MyWorks\Perl\our>perl our4.pl
main->pkgour:: 10
20


というわけで

http://d.hatena.ne.jp/yupug/20070222/1172172836

最初はこれ読んでまったく理解できなかったが概ね理解できた、と思う。