IV, NV ãªã©ã B ã¢ã¸ã¥ã¼ã«ã§èª¿ã¹ã
makamaka ããã YAPC Asia 2010 ã«ã¦çºè¡¨ãã XSからPPへ - YAPC::Asia Tokyo 2010 ã«æ¢ã«æ¸ãã¦ãããã ãã©ãåå¿é²ãå ¼ãã¦ã
JSON ã«ããéã«éããåºã¦ãã訳ã§ããã¾ãã¯è«ãã証æ ã
$ perl -MJSON -e 'warn encode_json(+{ foo => 1, bar => "1", baz => 0 + "1" })' {"bar":"1","baz":1,"foo":1} at -e line 1.
ããã㯠IV ãªã®ã PV ãªã®ãã°ã£ã¡ãå¤å®ãã¦ããã訳ã§ãããAPI ãªããã®ã¦ã¼ã¹ã±ã¼ã¹ã ã¨ãã®è¾ºããå³å¯ã«ãããã°ãªããªãã®ã§ããã®è¾ºãã®å¶å¾¡ã¯ã¡ããã¨ãããªãã¨ãããã®ã§ãã
ãã®åã« Devel::Peek ã§ä¸ãè¦ã¦ã¿ãã¨ã
$ perl -MDevel::Peek -e 'my $i = "1"; Dump($i);' SV = PV(0x10041040) at 0x10043be0 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) PV = 0x10042020 "1"\0 CUR = 1 LEN = 4 $ perl -MDevel::Peek -e 'my $i = 1; Dump($i);' SV = IV(0x10043be0) at 0x10043be0 REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 1 $ perl -MDevel::Peek -e 'my $i = "1"; $i = 0 + $i; Dump($i);' SV = PVIV(0x10062010) at 0x10043be0 REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 1 PV = 0x10042020 "1"\0 CUR = 1 LEN = 4
ã¨ãªããä¸åº¦ PV ã¨ãã¦åæåãããå¤æ°ã IV ã«å¤æãã㨠PVIV ã«ãªãã¨ã*1
B ã¢ã¸ã¥ã¼ã«ã§ B::SVp_IOK ã¨ã使ããã£ã¦ã©ãã«ãæ¸ãã¦ãªãæ°ããããã ãã©æ°ã®ããã ããããã¨ãããã sv.h ã§å®ç¾©ããã¦ããå®æ°ã®ãã¡ãã®è¾ºãã¯ä½¿ããã¿ããã§ãã
B ã¢ã¸ã¥ã¼ã«ã® svref_2object() ã«ãã£ã¦ B::SV ãªãã¸ã§ã¯ãã«ãã¤ã¤ããã®ãªãã¸ã§ã¯ãã¡ã½ããã§ãã FLAGS ãç¨ããã°ã©ããã flag ãç«ã£ã¦ããåããã¾ãã
å³ã¡ãããªæãã§ãã§ãã¯åºæ¥ã¾ããã¨ã
#!/usr/bin/perl use strict; use warnings; use B; use Test::More; sub iv_ok { my $sv = shift; return ( B::svref_2object( \$sv )->FLAGS & B::SVp_IOK ) ? 1 : 0; } sub nv_ok { my $sv = shift; return ( B::svref_2object( \$sv )->FLAGS & B::SVp_NOK ) ? 1 : 0; } subtest 'IV' => sub { my $sv1 = 1; is( iv_ok($sv1), 1, 'IV' ); is( nv_ok($sv1), 0, 'not NV' ); my $sv2 = "1"; is( iv_ok($sv2), 0, 'not IV' ); is( nv_ok($sv2), 0, 'not NV' ); $sv2 = 0 + $sv2; is( iv_ok($sv2), 1, 'IV' ); is( nv_ok($sv2), 0, 'not NV' ); done_testing; }; subtest 'NV' => sub { my $sv1 = 1.0; is( iv_ok($sv1), 0, 'not IV' ); is( nv_ok($sv1), 1, 'NV' ); my $sv2 = "1.0"; is( iv_ok($sv2), 0, 'not IV' ); is( nv_ok($sv2), 0, 'not NV' ); $sv2 = 0 + $sv2; is( iv_ok($sv2), 0, 'not IV' ); is( nv_ok($sv2), 1, 'NV' ); done_testing; }; done_testing;
*1:å¤åãã®è¾ºã㯠lestrrat ããã®æ¬ã®8ç« è¾ºãã«ãã£ã¨æ¸ãã¦ããã¯ã