リファレンス変数のデータ型を調べる(ref)


リファレンス変数のデータ型を調べる(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)が返るので注意する必要があります。

Task Runner