OOP(2) メソッド

では実際にクラスを作る前に、メソッドの呼び出し方を勉強しておきます。
メソッドの呼び出し方には2種類あって

Doggy->eat("dogfood");
eat Doggy("dogfood");

は同じ意味です。これは Doggy クラスのクラスメソッドを呼び出す方法ですね。(後者はなんだか「Doggy を食べろ」と言っているみたいですね(^_^;))

$pochi->eat("dogfood");
eat $pochi("dogfood");

こちらは $pochi が bless されたオブジェクトの場合のインスタンスメソッドの呼び出し方です。
クラスメソッドもインスタンスメソッドも呼び出し方に違いはない事がわかります。前者はまず主語となるオブジェクト(クラス)を書き、矢印(->)を書き、動詞となるメソッドを書き、カッコで目的語である引数を渡しています。それに対して後者はまず動詞、次に主語、目的語と書いていますね。
ちなみに、前者(主語が先)の書き方は引数を与える場合カッコが必須ですが、後者(動詞が先)はカッコは必須ではありません。ただ、後者(動詞が先)の書き方は曖昧になりがちで優先順位を間違えやすいそうです。なるべく主語を先に書いた方がいいですね。他のオブジェクト指向プログラミング言語でも主語を先に書く事が多いと思います。
では、いよいよオブジェクトを作ってみます。

package Dog;
 
sub new {
	my ($klass, $name) = @_;
	bless { name => $name };
}
 
sub eat {
	my ($self, $food) = @_;
	print "$self->{name} is eating $food.\n";
}
 
package main;
$pochi = Dog->new("Pochi");  # ポチ誕生
$pochi->eat("dogfood");      # ドッグフードを食べる
$pochi->eat("bone");         # 骨を食べる
$pochi->eat("meat");         # 肉を食べる 

まず、Dog パッケージに入ってメソッドとなる2つの関数を定義しています。
new が Dog クラスのコンストラクタとなります。クラスメソッドとして呼ばれるので、第一引数にはクラス名が入っているはずです。第二引数以降が呼び出された時に渡された引数となります。ここでは Dog の名前($name)を渡してもらいます。
名前を記録した無名ハッシュへのリファレンスを bless します。この new 関数の返り値は bless したリファレンス(オブジェクト)となります。
eat は Dog クラスのインスタンスメソッドです。第一引数には bless したリファレンスが渡されるはずですので、$self として受けています。また、このメソッドの引数として食べ物($food)を受け取ります。そして、$self をデリファレンスしたハッシュからキー name の値と、$food を使ってメッセージを表示します。
main パッケージ(プログラム開始時のデフォルトパッケージ)に戻ってから、いよいよ Dog->new を呼び出してオブジェクト(?)を生成します。生成したオブジェクトリファレンスが返ってくるはずなので、$pochi で受けています。
あとは $pochi に対して eat を3回呼び出しています。
以下が実行結果です。

Pochi is eating dogfood.
Pochi is eating bone.
Pochi is eating meat.

やったやった。できました。ポチがエサを食べてくれました。(^_^)
では、今度は Dog クラスに好物を持たせてみます。

package Dog;
 
sub new {
	my ($klass, $name, $favfood) = @_;
	bless { name => $name, favfood => $favfood };
}
 
sub eat {
	my ($self, $food) = @_;
	print "$self->{name} is eating $food.\n";
	if ($food eq $self->{favfood}) {
		print "He looks so happy!\n";
	}
}
 
package main;
$pochi = Dog->new("Pochi", "bone");  # 骨好きのポチ誕生
$pochi->eat("dogfood");              # ドッグフードを食べる
$pochi->eat("bone");                 # 骨を食べる
$pochi->eat("meat");                 # 肉を食べる 

まず、コンストラクタ new に「好物」を渡すようにします。好物は favfood としてハッシュに保存します。
そして、eat の中で好物を食べた時は「とっても幸せそうです」というメッセージを表示するようにしました。(^_^)
実行結果です。

Pochi is eating dogfood.
Pochi is eating bone.
He looks so happy!
Pochi is eating meat.

骨を食べた時だけメッセージが表示されました。幸せそうです。(^_^)