なかなか興味深い。
モジュールを定義する時のルール
ファイルの拡張子は"pm"。
pmじゃないと、useしたときに見つからなくてエラーが出る。
Can't locate TestClass1.pm in @INC (@INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at main1.pl line 3. BEGIN failed--compilation aborted at main1.pl line 3.
最後で1を返さなければならない。
返さないと、こうなる。
TestClass1.pm did not return a true value at main1.pl line 3. BEGIN failed--compilation aborted at main1.pl line 3.
クラス定義
TestClass1.pm
#!/usr/bin/perl package TestClass1; use strict; sub new { my $class = shift; my $this = { x => 10, y => 20, }; bless $this, $class; } sub show { my $this = shift; print "X: $this->{x}\n"; print "Y: $this->{y}\n"; print "----------\n"; } sub addX { my $this = shift; my $add = shift; $this->{x} += $add; } 1;
main1.pl
#!/usr/bin/perl use TestClass1; # インスタンス化 my $obj1 = new TestClass1; #my $obj1 = TestClass1->new(); # これでもいい # メソッド実行 $obj1->show(); my $x = $obj1->addX(30); $obj1->show(); # sub内で最後に評価した値は勝手にreturnされる print "return x: $x\n"; # インスタンス変数にはpublicでアクセス出来る print "var x: $obj1->{x}\n";
実行結果
X: 10 Y: 20 ---------- X: 40 Y: 20 ---------- return x: 40 var x: 40
クラス変数を使う
TestClass2.pm
#!/usr/bin/perl package TestClass2; use strict; # パブリッククラス変数 our $x = 10; our $y = 20; sub new { my $class = shift; my $this = { }; bless $this, $class; } sub show { my $this = shift; print "X: $x\n"; print "Y: $y\n"; print "----------\n"; } sub addX { my $this = shift; my $add = shift; $x += $add; } 1;
main2.pl
#!/usr/bin/perl use TestClass2; my $obj2_1 = new TestClass2; my $obj2_2 = new TestClass2; # クラス変数を書き換え $obj2_1->addX(30); $obj2_1->show(); $obj2_2->show(); # クラス変数に直接アクセス print "class var x: $TestClass2::x\n";
実行結果
X: 40 Y: 20 ---------- X: 40 Y: 20 ---------- class var x: 40
勝手にシングルトン
TestClass3.pm
#!/usr/bin/perl package TestClass3; use strict; # プライベートクラス変数 my $ins; sub new { my $class = shift; my $this = { x => 10, y => 20, }; # まだ生成されていなかったら生成 unless ($ins) { $ins = bless $this, $class; } $ins; } sub show { my $this = shift; print "X: $this->{x}\n"; print "Y: $this->{y}\n"; print "----------\n"; } sub addX { my $this = shift; my $add = shift; $this->{x} += $add; } 1;
main3.pl
#!/usr/bin/perl use TestClass3; # 普通にインスタンス化したつもりがシングルトン my $obj3_1 = new TestClass3; my $obj3_2 = new TestClass3; $obj3_1->addX(30); $obj3_1->show(); $obj3_2->show();
実行結果
X: 40 Y: 20 ---------- X: 40 Y: 20 ----------
newとblessの挙動
TestClass4.pm
#!/usr/bin/perl package TestClass4; use strict; sub new { my $class = shift; print "new arg[0]: $class\n"; 'Hello!' } sub new1 { my $class = shift; print "new arg[0]: $class\n"; bless {}, $class; } sub new2 { my $class = shift; print "new arg[0]: $class\n"; bless {}, __PACKAGE__; } sub new3 { my $class = shift; print "new arg[0]: $class\n"; bless {}, 'TestClass999'; } sub show { my $this = shift; print "this: $this\n"; } 1;
main4.pl
#!/usr/bin/perl use TestClass4; my $obj1; $obj1 = new TestClass4; print "$obj1\n"; print "----------\n"; $obj1 = TestClass4->new(); print "$obj1\n"; print "----------\n"; $obj1 = TestClass4::new('TestClass4'); print "$obj1\n"; print "----------\n"; $obj1 = TestClass4->new1(); print "$obj1\n"; $obj1->show(); print "----------\n"; $obj1 = TestClass4->new2(); print "$obj1\n"; $obj1->show(); print "----------\n"; $obj1 = TestClass4->new3(); print "$obj1\n"; $obj1->show();
実行結果
クラスメソッドとして実行した場合は、第一引数はクラス名。
インスタンスメソッドとして実行した場合は、第一引数はクラスのインスタンス。
newでクラスのインスタンスを返さなくてもいい。
存在しないクラスのインスタンスの生成は出来るけど、メソッドがないから普通のHashと同じ。
new arg[0]: TestClass4 Hello! ---------- new arg[0]: TestClass4 Hello! ---------- new arg[0]: TestClass4 Hello! ---------- new arg[0]: TestClass4 TestClass4=HASH(0x9947c28) this: TestClass4=HASH(0x9947c28) ---------- new arg[0]: TestClass4 TestClass4=HASH(0x9947d0c) this: TestClass4=HASH(0x9947d0c) ---------- new arg[0]: TestClass4 TestClass999=HASH(0x9947d3c) Can't locate object method "show" via package "TestClass999" at main4.pl line 32.
クラスを継承する
TestClass5.pm
#!/usr/bin/perl package TestClass5; use strict; use TestClass1; @TestClass5::ISA = qw(TestClass1); sub new { my $class = shift; my $this = new TestClass1; bless $this; } sub show { my $this = shift; # 継承元のメソッドを呼び出す $this->SUPER::show(); print "++++++++++\n"; } 1;
main5.pl
#!/usr/bin/perl use TestClass5; # インスタンス化 my $obj5 = new TestClass5; #my $obj5 = TestClass1->new(); # これでもいい # メソッド実行 $obj5->show(); my $x = $obj5->addX(30); $obj5->show(); # sub内で最後に評価した値は勝手にreturnされる print "return x: $x\n"; # インスタンス変数にはpublicでアクセス出来る print "var x: $obj5->{x}\n";
実行結果
X: 10 Y: 20 ---------- ++++++++++ X: 40 Y: 20 ---------- ++++++++++ return x: 40 var x: 40