Slide 1

Slide 1 text

undef 1 / 21

Slide 2

Slide 2 text

undefについて話します by liiu Gotanda.pm #18 (六本木編) 2 / 21

Slide 3

Slide 3 text

自己紹介 liiu / @_ybrliiu MobileFactory 18新卒 学生の頃からPerl書いてました プログラミング / 歴史 / (F|T)PS 3 / 21

Slide 4

Slide 4 text

本当はTest2関連のことを話したいなーと思っていました が、 Test2関連は難しそうな感じになったので急遽LT内容の 初期値だったundefについて話すことにします。 ※Perlが好きな皆さんならご存知のことも多いとは思い ますが、ご了承ください。 4 / 21

Slide 5

Slide 5 text

undef Perlにおける未定義 「未定義値」と値の一種としても扱う場合と、「未定 義な状態」を指す場合があるといえそう https://qiita.com/xtetsuji/items/e584b819d3cd1604a91f#%E6%9C%AA%E5%A コンテキストに応じてふるまいを変える 5 / 21

Slide 6

Slide 6 text

定義されているかどうかをチェッ ク 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

Slide 8

Slide 8 text

数値として解釈する 数値コンテキストで解釈すると、0として扱われま す。 say 10 * undef() + 20; # 20 8 / 21

Slide 9

Slide 9 text

文字列として解釈する 文字列コンテキストで解釈すると、空文字列''とし て扱われます。 say 'My name is ' . undef() . 'human.'; # My name is human. 9 / 21

Slide 10

Slide 10 text

真偽値として解釈する 真偽値コンテキストとして扱うと、偽値として扱われ ます。 my $u; unless ( $u ) { say "this is undefined value"; } # this is undefined value 10 / 21

Slide 11

Slide 11 text

リファレンスとして使う 未定義な変数をリファレンスとして参照したり代入する と、自動的にリファレンスとして扱えるように変化します。 use Data::Dumper; my $arrayref; $arrayref->[5] = 0; say Dumper $arrayref; # $VAR1 = [ # undef, # undef, # undef, # undef, # undef, # 0 # ]; 11 / 21

Slide 12

Slide 12 text

これが全部リファレンスになるってすごいですよね my $something; $something->[1]{key}[2][0]{hoge} = -1; say Dumper $something; # $VAR1 = [ # undef, # { # 'key' => [ # undef, # undef, # [ # { # 'hoge' => -1 # } # ] # ] # } # ]; 12 / 21

Slide 13

Slide 13 text

そのまま使うとエラーになる場合 メソッドを呼びだそうとした場合 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

Slide 19

Slide 19 text

19 / 21

Slide 20

Slide 20 text

SV構造体の型はNULLに変化したりせず、IVのまま。 整数として有効な値であることを示す IOK,pIOK が消え ている perl的には未定義な状態というのはSVボディが有効で ない場合と、 NULL型である場合があるみたい? 20 / 21

Slide 21

Slide 21 text

以上で発表は終わります。 Perlの内部に詳しい方がいらっしゃればぜひご教授くだ さい。 また突っ込みどころなどあれば大歓迎です。 ご清聴ありがとうございました。 21 / 21