リファレンス変数のデータ型を調べる(ref)
rhythmfactoryのページ(https://rfs.jp/sb/perl/05/ref.html)を見ていて、全てのデータ型を表示してみようと思ったので作ってみました。
use Data::Dumper;
# 数値(SCALAR)
my $value = 100; # 非リファレンス
my $value_ref = \$value; # リファレンス
# 文字列(SCALAR)
my $string = 'abcd'; # 非リファレンス
my $string_ref = \$string; # リファレンス
# 連想配列(HASH)
my %hash = { 'A' => 1 }; # 非リファレンス
my $hash_ref = \%hash; # リファレンス
my $hash_ref2 = { 'A' => 1 }; # これもリファレンス
# 配列(ARRAY)
my @array = ( 0, 1, 2 ); # 非リファレンス
my $array_ref = \@array; # リファレンス
my $array_ref2 = [ 0, 1, 2 ]; # これもリファレンス
# コード(CODE)
# 関数を定義
sub func {
my $a = 1;
my $b = 3;
my $c = $a + $b;
return $c;
}
my $code_ref = sub { 1 }; # リファレンス
my $code_ref2 = \&func(); # 非リファレンス (*1: 関数の返り値をリファレンスとして渡しているため)
my $code_ref3 = \&func; # リファレンス
# オブジェクト
my $class = shift;
my $o = { };
bless( $o, $class );
my $ref_o = \$o; # オブジェクトのリファレンスを作成
# 配列に全てのデータ型を定義
my @ary = (
# 数値(SCALAR)
100, # ''
$value, # ''
$value_ref, # 'SCALAR'
# 文字列(SCALAR)
"aaaa", # ''
$string, # ''
$string_ref, # 'SCALAR'
# 連想配列(HASH)
{ 'A' => 1 }, # 'HASH'
$hash_ref, # 'HASH'
$hash_ref2, # 'HASH'
# 配列(ARRAY)
[ 0, 1, 2 ], # 'ARRAY'
$array_ref, # 'ARRAY'
$array_ref2, # 'ARRAY'
# コード(CODE)
sub { 1 }, # 'CODE'
$code_ref, # 'CODE'
$code_ref2, # 'SCALAR' (*1)
$code_ref3, # 'CODE'
# オブジェクト
$o, # '(__PACKAGE__)'
$ref_o, # 'REF'
# GLOB(ってなんだろう?)
*ref_o, # ''
\*ref_o, # 'GLOB'
);
# 出力
map {
print "\n----------------\n";
# my $type = ( ref($_) eq '' ) ? ref(\$_) : ref($_);
my $type = ref($_);
printf "[%s] = [%s]", $_, $type;
print "\n".Dumper($_);
} @ary;
結果
----------------
[100] = []
$VAR1 = 100;
----------------
[100] = []
$VAR1 = 100;
----------------
[SCALAR(0xd758a0)] = [SCALAR]
$VAR1 = \100;
----------------
[aaaa] = []
$VAR1 = 'aaaa';
----------------
[abcd] = []
$VAR1 = 'abcd';
----------------
[SCALAR(0xd75de0)] = [SCALAR]
$VAR1 = \'abcd';
----------------
[HASH(0xd75360)] = [HASH]
$VAR1 = {
'A' => 1
};
----------------
[HASH(0xd75ba0)] = [HASH]
$VAR1 = {
'HASH(0xe9b7d0)' => undef
};
----------------
[HASH(0xe9b8d8)] = [HASH]
$VAR1 = {
'A' => 1
};
----------------
[ARRAY(0xd75720)] = [ARRAY]
$VAR1 = [
0,
1,
2
];
----------------
[ARRAY(0x29f0f88)] = [ARRAY]
$VAR1 = [
0,
1,
2
];
----------------
[ARRAY(0xd751e0)] = [ARRAY]
$VAR1 = [
0,
1,
2
];
----------------
[CODE(0xd81410)] = [CODE]
$VAR1 = sub { "DUMMY" };
----------------
[CODE(0x29e8f68)] = [CODE]
$VAR1 = sub { "DUMMY" };
----------------
[SCALAR(0xd752b8)] = [SCALAR]
$VAR1 = \4;
----------------
[CODE(0x29f0e20)] = [CODE]
$VAR1 = sub { "DUMMY" };
----------------
[main=HASH(0xd752d0)] = [main]
$VAR1 = bless( {}, 'main' );
----------------
[REF(0xdd0908)] = [REF]
$VAR1 = \bless( {}, 'main' );
----------------
[*main::ref_o] = []
$VAR1 = *::ref_o;
----------------
[GLOB(0xd81488)] = [GLOB]
$VAR1 = \*::ref_o;
通常定義する文字や数値はスカラ変数ですが、リファレンスではないので
my $str = 'aaa';
printf "ref=(%s)", ref($str);
のようにref()関数を呼び出すと
ref=()
のようにヌルが返りますが、
my $str = 'aaa';
printf "ref=(%s)", ref(\$str); # ←$の前に\をつけるとリファレンスになる
変数の先頭に\マークを付けることで、リファレンスとして得ると
ref=(SCALAR)
のようにSCALARが返ります。
ちなみに、配列の@、連想配列(ハッシュ)の%も同じくヌルが返ります。
配列
my @array = ( 0, 1, 2 );
の場合は、
my $array_ref1 = \@array;
my $array_ref2 = [ 0, 1, 2 ];
連想配列
my %hash = { 'One' => 1, 'Two' => 2 };
の場合は、
my $hash_ref1 = \%hash;
my $hash_ref2 = { 'One' => 1, 'Two' => 2 };
のようにするとリファレンスとして得ることができます。
コード(CODE)では、sub()で関数を定義したものをリファレンスとして取得する場合、
my $code_ref = \&func;
とすると関数そのものをリファレンスとして取得できるので
[CODE(0x2a66f40)] = [CODE]
$VAR1 = sub { "DUMMY" };
のように(CODE)が返りますが、
my $code_ref2 = \&func();
とすると関数の返り値をリファレンスとして取得するので
[SCALAR(0x25353d8)] = [SCALAR]
$VAR1 = \4;
のように(SCALAR)が返るので注意する必要があります。