定義されているかどうかをチェッ
ク
defined 関数や defined-or 演算子などで定義さ
れているかどうかをチェックできます
my $str;
if ( not defined $str ) {
$str = 'default';
}
my $num;
$num // warn "num is undefined.";
$num //= 10;
6 / 21
Slide 7
Slide 7 text
undef関数
左辺値の値を未定義にする
引数がない場合、未定義値が返される
不定コンテキストで呼ぶと、一意な未定義値が返さ
れる
my $num = 2;
undef $num;
my $str = "HELL, WORLD";
$str = undef;
# 同じアドレスにある
if ( ¥undef == ¥undef ) {
say "undef is unique.";
}
7 / 21
そのまま使うとエラーになる場合
メソッドを呼びだそうとした場合
Scalar::Util::blessed などでチェックしましょう
my $obj;
$obj->can('some_method'); # Can't call method "can" on an undefined value
$obj->isa('SomeClass'); # Can't call method "isa" on an undefined value
if ( Scalar::Util::blessed $obj ) {
...
}
13 / 21
Slide 14
Slide 14 text
そのまま使うとエラーになる場合
デリファレンスしようとした場合
ちゃんと初期化や定義されているかをチェックしま
しょう
my $arrayref;
@$arrayref; # Can't use an undefined value as an ARRAY reference
$arrayref = [];
my $hashref;
%$hashref; # Can't use an undefined value as a HASH reference
$hashref = {};
14 / 21
Slide 15
Slide 15 text
ところでundefの仕組みや中身が気になりませんか?
15 / 21
Slide 16
Slide 16 text
少し探検してみます
16 / 21
Slide 17
Slide 17 text
Devel::Peekで覗いてみる
use Devel::Peek;
say Dump undef;
# SV = NULL(0x0) at 0x10eee1b48
# REFCNT = 2147483631
# FLAGS = (READONLY,PROTECT)
my $u;
say Dump $u;
# SV = NULL(0x0) at 0x7fdc1e8601b8
# REFCNT = 1
# FLAGS = ()
17 / 21
Slide 18
Slide 18 text
undefを再代入した場合
my $num = 10;
$num = undef;
# SV = IV(0x7f8b90858dd8) at 0x7f8b90858de8
# REFCNT = 1
# FLAGS = (IOK,pIOK)
# IV = 10
say Dump $num;
# SV = IV(0x7f8b90858dd8) at 0x7f8b90858de8
# REFCNT = 1
# FLAGS = ()
# IV = 10
18 / 21