common::sense
$ cpanm common::sense
これでインストールして1、use common::sense
すると、
use strict
やら、 use warnings
やら、use utf8
やら、いろいろと ON になる。
だけど、厳密には、 no strict 'refs'
だったり、 no warnings 'newline'
だったりカスタマイズしている2。
で、調べてメモったもの。
まず、import
import
が定義されているモジュールに関して。
$ cat F.pm
package F;
use strict ;
use warnings ;
sub import {
strict->import ;
warnings->import ;
}
1
$ ls
F.pm
$ perl -MF -le 'print $c'
Global symbol "$c" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
こんな感じでモジュール側から呼び出し側で自動的に ON にさせる事が出来る。
$^H
$ perldoc -m common::sense | grep '|='
$^H |= 0x1c820fc0;
common::sense
の import
の中では何やら、特殊変数に論理和カマしてる。
ここの $^H
の説明読んでも今一要領を得ない。
てんで、片っぱしからソースに当る。
$ perldoc -m strict | grep '$^H'
$^H |= $explicit_bitmask{$s};
$^H |= bits(@_ ? @_ : @default_bits);
$^H &= ~ bits(@_ ? @_ : @default_bits);
$ perldoc -m strict | grep -A 5 '%bitmask'
my %bitmask = (
refs => 0x00000002,
subs => 0x00000200,
vars => 0x00000400
);
my %explicit_bitmask = (
$ perldoc -m utf8 | grep '$^H'
$^H |= $utf8::hint_bits;
$^H &= ~$utf8::hint_bits;
$ perldoc -m utf8 | grep '$utf8::hint_bits'
$utf8::hint_bits = 0x00800000;
$^H |= $utf8::hint_bits;
$^H &= ~$utf8::hint_bits;
よーするに
$ cat F.pm
package F;
sub import {
$^H |= 0x00000002; # strict 'refs'
$^H |= 0x00000200; # 'subs'
$^H |= 0x00000400; # 'vars'
$^H |= 0x00800000; # utf8
}
1
% perl -MF -le 'print "あ"'
Wide character in print at -e line 1.
あ
こんな感じに制御している。で、論理和だから、A
は、
$ cat F.pm
package F;
sub import {
$^H |= 0x00800602; # use utf8, use strict;
}
1
とも書けると、、、
我ながらクドいが
フラグの追加(論理和)とフラグの除外(and not)で、上から順に追加、除外を行なった表。
追加フラグ | 動作 | 16進数 | 2進数 |
---|---|---|---|
無し | $^H | 00000000 | 000000000000000000000000000000 |
strict 'refs' | $^H |= 0x00000002 | 00000002 | 000000000000000000000000000010 |
strict 'subs' | $^H |= 0x00000200 | 00000202 | 000000000000000000001000000010 |
strict 'vars' | $^H |= 0x00000400 | 00000602 | 000000000000000000011000000010 |
utf8 | $^H |= 0x00800000 | 00800602 | 000000100000000000011000000010 |
feature: unicode_strings 以外 | $^H |= 0x1c000000 | 1c800602 | 011100100000000000011000000010 |
feature: unicode_strings | $^H |= 0x00000800 | 1c800e02 | 011100100000000000111000000010 |
除外フラグ | 動作 | 16進数 | 2進数 |
---|---|---|---|
feature: unicode_strings | $^H &= ~0x00000800 | 1c800602 | 011100100000000000011000000010 |
feature: unicode_strings 以外 | $^H &= ~0x1c000000 | 00800602 | 000000100000000000011000000010 |
utf8 | $^H &= ~0x00800000 | 00000602 | 000000000000000000011000000010 |
strict 'vars' | $^H &= ~0x00000400 | 00000202 | 000000000000000000001000000010 |
strict 'subs' | $^H &= ~0x00000200 | 00000002 | 000000000000000000000000000010 |
strict 'refs' | $^H &= ~0x00000002 | 00000000 | 000000000000000000000000000000 |
%^H
use feature
に関しては
- 上述
$^H
を ON にすると暗黙で全てが ON にされる。- 但し
unicode_strings
に関しては、上述の通り独自フラグ。
- 但し
-
$^H{KEY_WORD}
を一つでも定義する3と、個別に ON する形になる4
all
unicode_strings
を含めた feature
だけを ON にしたければ、
$ cat F.pm
package F;
sub import {
$^H |= 0x1c00800;
}
1
KEY_WORD に関しては、
$ perldoc -m feature | grep feature_
fc => 'feature_fc',
say => 'feature_say',
state => 'feature_state',
switch => 'feature_switch',
evalbytes => 'feature_evalbytes',
array_base => 'feature_arybase',
current_sub => 'feature___SUB__',
lexical_subs => 'feature_lexsubs',
unicode_eval => 'feature_unieval',
unicode_strings => 'feature_unicode',
(略)
${^WARNING_BITS}
warnings
の方は、別のフラグが用意されている模様。
ソースを見たが、フラグ制御が複雑4。
ALL
普通に use warnings
した時の挙動
$ cat F.pm
package F;
sub import {
${^WARNING_BITS} = "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55" ;
}
1
それから、 newline, redefine, once を抜いた例
$ cat F.pm
package F;
sub import {
my $All = "" ; vec($All, 0, 2) = 3 ;
${^WARNING_BITS} = "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55" ;
${^WARNING_BITS} &= ~("\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"|"\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"|$All) ; # newline
${^WARNING_BITS} &= ~("\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00"|"\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00"|$All) ; # redefine
${^WARNING_BITS} &= ~("\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"|"\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"|$All) ; # redefine
}
1
括弧内の論理和の左辺は、%Bits
の値。二番目の文字列は、%DeadBits
からの文字列。
$ perl -le 'sub h{ print q{test}} sub h{ print q{test2} }' -MF
$ perl -le 'sub h{ print q{test}} sub h{ print q{test2} }' -Mwarnings
Subroutine h redefined at -e line 1.
$ perl -le 'print substr $a, 10' -MF
Use of uninitialized value $a in substr at -e line 1.
substr outside of string at -e line 1.
Use of uninitialized value in print at -e line 1.
$ perl -le 'print substr $a, 10' -Mwarnings
Name "main::a" used only once: possible typo at -e line 1.
Use of uninitialized value $a in substr at -e line 1.
substr outside of string at -e line 1.
Use of uninitialized value in print at -e line 1.
ついでのメモ
common::sense
で OFF ってた奴で目に入ったの。
no strict 'refs'
シンボリックリファレンスを禁止しない、って奴。
全く使わないから、どうしても覚えない。
$ pbpaste
my $n = "f";
$$n = "foo"; # $f に "foo"
print ${$n} . "\n" ;
use strict
$ pbpaste | perl -Mstrict
Can't use string ("f") as a SCALAR ref while "strict refs" in use at - line 2.
no strict 'refs'
$ pbpaste | perl -Mstrict -M-strict=refs
foo
no warnings 'newline'
改行含んだモンを open しない。
$ pbpaste
my $f = "hoge\nfoo" ;
print -e $f ;
use warnings
$ pbpaste | perl -M warnings
Unsuccessful stat on filename containing newline at - line 2.
Use of uninitialized value in print at - line 2.
no warnings 'newline'
$ pbpaste | perl -M warnings -M-warnings=newline
Use of uninitialized value in print at - line 2.
ついでのメモ2
autodie
に関しては、Fatal
のソースに書いてある、
$^H |= 0x020000;
が、該当するのか? grep しただけだから、何とも、、、
$ find `perl -le 'print for @INC '` -name '*pm' -exec grep -Hn '$^H ' {} \; | perl -lne 's/^.*5\.18\.4//; print '