frei

旧「anney's room」からブログ「frei」だけ引っ越し&残しました

REFCNT = 2147483613。

今日も残業してたら、同僚さんから perl の質問が。

おそらく以前私が書いたコードが発端の話なんだろうなぁー。

で、プロトタイプを使わずに

サブルーチンの引き数が1つ足りない場合などに、

受け取ったつもりの値の中身はどうなるのか?てな質問だったのですがー。

つまり、こんなんです。

#!/usr/bin/perl -w

use strict;

use Devel::Peek;

&test();

exit;

sub test {

my $args = shift;

Dump($args);

&test2($args);

}

sub test2 {

my $args = shift;

Dump($args);

}

結果。

SV = NULL(0x0) at 0x928d1a4

REFCNT = 1

FLAGS = (PADBUSY,PADMY)

SV = NULL(0x0) at 0x928d2d0

REFCNT = 1

FLAGS = (PADBUSY,PADMY)

当然っちゃー当然ですが、NULL です。

でも、参照先は違ってるような。そっか。

ちなみに &test(1); にすると、結果はこう。

SV = IV(0x9f20ab4) at 0x9f291e8

REFCNT = 1

FLAGS = (PADBUSY,PADMY,IOK,pIOK)

IV = 1

SV = IV(0x9f20ab8) at 0x9f29314

REFCNT = 1

FLAGS = (PADBUSY,PADMY,IOK,pIOK)

IV = 1

納得です。

ついでに &test({}); にすると、こうなる。

SV = RV(0x8ff0698) at 0x8fea1dc

REFCNT = 1

FLAGS = (PADBUSY,PADMY,ROK)

RV = 0x8fc8c20

SV = PVHV(0x8fe0310) at 0x8fc8c20

REFCNT = 3

FLAGS = (SHAREKEYS)

IV = 0

NV = 0

ARRAY = 0x0

KEYS = 0

FILL = 0

MAX = 7

RITER = -1

EITER = 0x0

SV = RV(0x8ff069c) at 0x8fea308

REFCNT = 1

FLAGS = (PADBUSY,PADMY,ROK)

RV = 0x8fc8c20

SV = PVHV(0x8fe0310) at 0x8fc8c20

REFCNT = 4

FLAGS = (SHAREKEYS)

IV = 0

NV = 0

ARRAY = 0x8fdc098

KEYS = 0

FILL = 0

MAX = 7

RITER = -1

EITER = 0x0

なんだか、いろいろやってるなー。

いきなりハードルあげちゃった感があるので(笑)

シンプルに Dump({}) でどうでしょう?

SV = RV(0x82d4678) at 0x82acd40

REFCNT = 1

FLAGS = (TEMP,ROK)

RV = 0x82acc20

SV = PVHV(0x82c4310) at 0x82acc20

REFCNT = 2

FLAGS = (SHAREKEYS)

IV = 0

NV = 0

ARRAY = 0x0

KEYS = 0

FILL = 0

MAX = 7

RITER = -1

EITER = 0x0

なるー。RVでリファレンスで PVHV でハッシュですか。

ちなみに &test2($args); 呼び出し部分を

&test2(\$args); にすると、参照渡しになるので…

SV = IV(0x9af3ab4) at 0x9afc1e8

REFCNT = 1

FLAGS = (PADBUSY,PADMY,IOK,pIOK)

IV = 1

SV = RV(0x9b02698) at 0x9afc314

REFCNT = 1

FLAGS = (PADBUSY,PADMY,ROK)

RV = 0x9afc1e8

SV = IV(0x9af3ab4) at 0x9afc1e8

REFCNT = 3

FLAGS = (PADBUSY,PADMY,IOK,pIOK)

IV = 1

…てなもんで、RV になってる、と。

さらに、サブルーチン内で return undef; した場合

何が一体返るのか?というご質問をいただいたので調べてみる。

#!/usr/bin/perl -w

use strict;

use Devel::Peek;

Dump(&test());

exit;

sub test {

return undef;

}

SV = NULL(0x0) at 0x9dc5c20

REFCNT = 1

FLAGS = (TEMP)

ですよね、ですよね。なるなるー。

ついでに Dump(undef); ってやると

SV = NULL(0x0) at 0x8f216e4

REFCNT = 2147483613

FLAGS = (READONLY)

な、な、なんですか、このリファレンスカウントはぁぁぁー。

ちなみに 一度変数に my $a = undef; などと格納し、

それから Dump($a) やった場合は…

SV = NULL(0x0) at 0x84b7020

REFCNT = 1

FLAGS = (PADBUSY,PADMY)

…てな感じで、リファレンスカウントは1になる次第。

面白いなぁー。