これは良い考えではありません。
Perl は、use strict;
次のような問題を処理するためにの使用を開始しました。
$employee_name = "Bob";
print "The name of the employee is $employeeName\n";
変数名のタイプミスはよくある問題でした。を使用use strict;
すると、変数を宣言する必要があるため、このようなエラーはコンパイル時にキャッチできます。
ただし、ハッシュ キーとハッシュ参照により、この保護が解除されます。したがって:
my $employee[0] = {}
$employee[0]->{NAME} = "Bob";
print "The name of the employee is " . $employee[0]->{name} . "\n";
複雑なデータ構造について話し始めるときにオブジェクトを使用する理由の 1 つは、次のようなエラーを防ぐためです。
my $employee = Employee->new;
$employee->name("Bob");
print "The name of the employee is " . $employee->Name . "\n";
name
メソッド名がであり ではないため、このエラーはキャッチされますName
。
ユーザーが独自のメソッドを無作為に作成できるようにすると、オブジェクトを使用することで得られる保護が失われます。
my $employee = Employee->new;
$employee->name("Bob"); #Automatic Setter/Getter
print "The name of the employee is " . $employee->Name . "\n"; #Automatic Setter/Getter
自動セッターとゲッターが原因で、エラーをキャッチできません。これは、ユーザー名が間違っている場合でも、ユーザー名のメソッドが有効であるためです。
実際、オブジェクトがどのように構造化されているかを必ずしも認識しないように、オブジェクトをセットアップしました。foo
メソッドとで次のクラスを観察しますbar
。
sub new {
my $class = shift;
my $foo = shift;
my $bar = shift;
my $self = {};
bless $self, $class;
$self->foo($foo);
$self->bar($bar);
return $self;
}
sub foo {
my $self = shift;
my $foo = shift;
my $method_key = "FOO_FOO_FOO_BARRU";
if (defined $foo) {
$self->{$method_key} = $foo;
}
return $self->{$method_key};
}
sub bar {
my $self = shift;
my $bar = shift;
my $method_key = "BAR_BAR_BAR_BANNEL";
if (defined $bar) {
$self->{$method_key} = $bar;
}
return $self->{$method_key};
}
とのクラス値をコンストラクターに設定できfoo
ますbar
。ただし、私のコンストラクターは、これらの値がどのように格納されているかを知りません。オブジェクトを作成し、getter/setter メソッドに渡すだけです。また、私の 2 つのメソッドは、互いの値をどのように格納するかを知りません。そのため、メソッドのハッシュ キーにこのようなクレイジーな名前を付けることができます。これは、メソッド内でのみ使用でき、他の場所では使用できないためです。
代わりに、私のメソッドfoo
とbar
はセッターとゲッターの両方です。foo
またはの値を指定するbar
と、その値が設定されます。それ以外の場合は、単に現在の値を返します。
しかし、あなたはすでにこれらすべてを知っており、これを実行しなければならないと主張するでしょう。結構...
やりたいことを処理する 1 つの方法は、AUTOLOADサブルーチンを作成することです。AUTOLOAD サブルーチンは、その名前のメソッド サブルーチンが他にない場合に自動的に呼び出されます。に$AUTOLOAD
は、呼び出されたクラスとメソッドが含まれています。これを使用して、独自の値を設定できます。
これが私のテストプログラムです。と の 2 つの方法を使用bar
しfoo
ますが、好きな方法を使用しても問題なく動作します。
変更点の 1 つは、値のリストの代わりに、コンストラクターでパラメーター ハッシュを使用することです。これが現代的な方法と見なされることを除いて、実際の違いはありません.
また、メソッド名をすべて小文字に正規化していることにも注意してください。そのよう$object->Foo
に$object->foo
、 、$object-FOO
はすべて同じ方法です。このようにして、少なくとも大文字と小文字の間違いをなくします。
use strict;
use warnings;
use feature qw(say);
use Data::Dumper;
my $object = Foo->new({ -bar => "BAR_BAR",
-foo => "FOO_FOO",
}
);
say "Foo: " . $object->foo;
say "Bar: " . $object->bar;
$object->bar("barfu");
say "Bar: " . $object->bar;
say Dumper $object;
package Foo;
sub new {
my $class = shift;
my $param_ref = shift;
my $self = {};
bless $self, $class;
foreach my $key (keys %{$param_ref}) {
# May or may not be a leading dash or dashes: Remove them
(my $method = $key) =~ s/^-+//;
$self->{$method} = $param_ref->{$key};
}
return $self;
}
sub AUTOLOAD {
my $self = shift;
my $value = shift;
our $AUTOLOAD;
( my $method = lc $AUTOLOAD ) =~ s/.*:://;
if ($value) {
$self->{$method} = $value;
}
return $self->{$method};
}