このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
Perl のオブジェクトは、ただのリファレンスであり、
上級言語風に言うと、連想配列から継承したクラスなのだ。
(例外もあるが、大抵は連想配列を使っている)
そのため、インスタンスに対して、
ハッシュのリファレンスとしてアクセスできてしまうのだ。
Perl には、アクセス制限なんてものは一切ない。
その代わりにあるのは……紳士協定だ。(笑)
連想配列への直接アクセスは止めましょって協定ですな。
では、アクセサを定義してみよう。
========== Employee.pm ==========
package Employee;
use v5.6.1;
use strict;
use warnings;
BEGIN {
our $Version = '0.02';
}
sub new {
my ($package, %identity) = @_;
$package = (ref $package or $package or __PACKAGE__);
bless(\%identity, $package);
}
sub name {
return $_[0]->{'name'};
}
sub gender {
return $_[0]->{'gender'};
}
sub weight {
return $_[0]->{'weight'};
}
sub salary {
@_ == 2 ? $_[0]->{'salary'} = $_[1] : $_[0]->{'salary'};
}
1;
========== end of Employee.pm ==========
========== EmployeeTest.pl ==========
#!/usr/local/bin/perl
use strict;
use warnings;
use lib '.';
use Employee;
my $jack = Employee->new(
'name' => 'Jack',
'gender' => 'male',
'salary' => 160000,
'weight' => '65kg',
);
$\ = "\n";
print "Package: ", ref($jack);
print "Name: ", $jack->name;
print "Gender: ", $jack->gender;
print "Weight: ", $jack->weight;
print "Salary: ", $jack->salary;
$jack->salary(200000);
print "Salary: ", $jack->salary;
========== end of EmployeeTest.pl ==========
実行してみる。
$ ./EmployeeTest.pl
Package: Employee
Name: Jack
Gender: male
Weight: 65kg
Salary: 160000
Salary: 200000
基本的には代わらないが、
アクセサ経由での呼び出しだ。
getter は、引数が必要ないため、括弧を省略できる。
このため、これが非常にプロパティっぽく見えるのだ。
ただ、setter に関しては問題点もある。
Perl は素早くコードを書くため、
色々と省略することができる言語である。
その性質があるためか、アクセサに関しても、昔から、
setter/getter に同じメソッドを使う実装が多い。
salary はその例だ。
print $jack->salary;
$jack->salary(200000);
どうだろうか。違和感がないだろうか。