Perl-リファレンス

Perl参照は、スカラー、配列、またはハッシュなどの別の値の場所を保持するスカラーデータ型です。そのスカラーの性質により、参照はどこでも使用でき、スカラーを使用できます。

他のリストへの参照を含むリストを作成できます。リストには、ハッシュへの参照などを含めることができます。これは、ネストされたデータ構造がPerlで構築される方法です。

参照を作成する

次のようにバックスラッシュを前に付けることで、変数、サブルーチン、または値の参照を簡単に作成できます。

$scalarref = \$foo;
$arrayref  = \@ARGV;
$hashref   = \%ENV;
$coderef   = \&handler;
$globref   = \*foo;

バックスラッシュ演算子を使用してI / Oハンドル(filehandleまたはdirhandle)に参照を作成することはできませんが、匿名配列への参照は、次のように角括弧を使用して作成できます。

$arrayref = [1, 2, ['a', 'b', 'c']];

同様の方法で、次のように中括弧を使用して匿名ハッシュへの参照を作成できます。

$hashref = {
   'Adam'  => 'Eve',
   'Clyde' => 'Bonnie',
};

匿名サブルーチンへの参照は、次のようにサブ名なしでsubを使用して作成できます。

$coderef = sub { print "Boink!\n" };

間接参照

間接参照は、参照ポイントから場所への値を返します。参照を逆参照するには、参照がスカラー、配列、またはハッシュのいずれを指しているかに応じて、参照変数のプレフィックスとして$、@、または%を使用するだけです。以下は、概念を説明するための例です-

#!/usr/bin/perl

$var = 10;

# Now $r has reference to $var scalar.
$r = \$var;

# Print value available at the location stored in $r.
print "Value of $var is : ", $$r, "\n";

@var = (1, 2, 3);
# Now $r has reference to @var array.
$r = \@var;
# Print values available at the location stored in $r.
print "Value of @var is : ",  @$r, "\n";

%var = ('key1' => 10, 'key2' => 20);
# Now $r has reference to %var hash.
$r = \%var;
# Print values available at the location stored in $r.
print "Value of %var is : ", %$r, "\n";

上記のプログラムを実行すると、次の結果が得られます。

Value of 10 is : 10
Value of 1 2 3 is : 123
Value of %var is : key220key110

変数の型がわからない場合は、を使用してその型を簡単に知ることができます ref、引数が参照の場合、次の文字列のいずれかを返します。それ以外の場合はfalseを返します-

SCALAR
ARRAY
HASH
CODE
GLOB
REF

次の例を試してみましょう-

#!/usr/bin/perl

$var = 10;
$r = \$var;
print "Reference type in r : ", ref($r), "\n";

@var = (1, 2, 3);
$r = \@var;
print "Reference type in r : ", ref($r), "\n";

%var = ('key1' => 10, 'key2' => 20);
$r = \%var;
print "Reference type in r : ", ref($r), "\n";

上記のプログラムを実行すると、次の結果が得られます。

Reference type in r : SCALAR
Reference type in r : ARRAY
Reference type in r : HASH

循環参照

循環参照は、2つの参照に相互の参照が含まれている場合に発生します。参照を作成するときは注意する必要があります。そうしないと、循環参照によってメモリリークが発生する可能性があります。以下は例です-

#!/usr/bin/perl

 my $foo = 100;
 $foo = \$foo;
 
 print "Value of foo is : ", $$foo, "\n";

上記のプログラムを実行すると、次の結果が得られます。

Value of foo is : REF(0x9aae38)

関数への参照

これは、シグナルハンドラーを作成して、関数名の前に\&を付けて関数への参照を生成し、その参照を逆参照するには、アンパサンド&を使用して参照変数のプレフィックスを付ける必要がある場合に発生する可能性があります。以下は例です-

#!/usr/bin/perl

# Function definition
sub PrintHash {
   my (%hash) = @_;
   
   foreach $item (%hash) {
      print "Item : $item\n";
   }
}
%hash = ('name' => 'Tom', 'age' => 19);

# Create a reference to above function.
$cref = \&PrintHash;

# Function call using reference.
&$cref(%hash);

上記のプログラムを実行すると、次の結果が得られます。

Item : name
Item : Tom
Item : age
Item : 19