第24回 別のパッケージの関数を呼び出すもう1つの方法 bless

前回、パッケージによって名前空間を作り出し、

名前空間の名前::関数名

という書式で関数を呼び出せることを見ました。


実は、この書式ではなくても、他のパッケージの関数を呼び出す方法があります。
それが

bless

です。

bless

早速、例を見ていきたいと思います。

例:

use strict;

package Hoge;
sub h {
  print 'Hogeの関数', "\n";
}

package Foo;
sub f {
  print 'Fooの関数', "\n";
}

package main;
my $c;

$c = bless \$c, 'Hoge';  # bless に大注目
$c->h(); # 呼び出し!

my $d;
$d = bless \$d, 'Foo';   # bless に大注目
$d->f(); # 呼び出し!

結果:

Hogeの関数
Fooの関数

なにをしたか?

blessの第1引数に、スカラー変数へのリファレンスを与え、第2引数に、パッケージ名を与えた。


※ blessの第1引数はスカラーへのリファレンスではなくて、配列へのリファレンス、ハッシュへのリファレンスなど、リファレンスならなんでもよい。

なにが起こったか?

blessにリファレンスを与えたので魔法が起きた!


なにかとはなんだ?

blessが返す戻り値とは何か?


それは、第2引数で与えたパッケージにある関数を呼び出せるリファレンスだ。
そう。 blessに、リファレンスを与えると、そのリファレンスを「祝福」し、そのリファレンスでもって、パッケージの関数を呼び出せるようにしてくれるのである!!

つぎのソースをみてほしい

use strict;

package Hoge;
sub h {
  print 'Hogeの関数', "\n";
}

package main;
my $c = 5;  # 5を代入

my $d = bless \$c, 'Hoge';  # $cへのリファレンスをblessに与える

# blessによって$dは、Hogeの関数を呼べる
$d->h();

# では、$dはなんだ?
# $dはリファレンスなので、デリファレンスする
print "$$d", "\n";

結果:

Hogeの関数
5

な! な! なんと!!
print "$$d", "\n";
の部分で 5 と表示された!!!
5は$cに代入したものと同じである!!!

つまり

$cへのリファレンスをblessに与えた。
だから、$c(へのリファレンス)から'Hoge'パッケージの関数が呼べるのだ!
今回は、$c(へのリファレンス)を$dに代入した形になっている。

これが

これが、別のパッケージの関数を呼び出すもう1つの方法である。

しかし、

パッケージ名::関数名

と書くのと、

blessされた変数->関数名

と書くのでは、ビミョーに意味が違っている!
そしてこのビミョーに違っているところこそ!! Perlオブジェクト指向を書くときにとても大切なことである!!!

でも

今回は、ここまでです。

それでは、また〜

注意

blessを使った方のパッケージの関数呼び出しのやりかたは、
オブジェクト指向のやりかたにとどめて置くべきだろう。

普通に別パッケージの関数を呼ぶなら、

パッケージ名::関数名

の方がよい。

なぜなら、ビミョーに違っていると述べたが、

パッケージ名::関数名

blessされた変数->関数名

が、まったく同じものと勘違いした場合には、大きく違っていることに気づくからである。