さまざまな論理演算子は空の文字列を返すのではなく、3 つの単純なスカラー型すべてで false または true の値を返します。print
引数に文字列コンテキストを強制するため、空の文字列を返すように見えます。
#!/usr/bin/perl
use strict;
use warnings;
use Devel::Peek;
my $t = 5 > 4;
my $f = 5 < 4;
Dump $t;
Dump $f;
出力:
SV = PVNV(0x100802c20) at 0x100827348
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 1
NV = 1
PV = 0x100201e60 "1"\0
CUR = 1
LEN = 16
SV = PVNV(0x100802c40) at 0x100827360
REFCNT = 1
FLAGS = (PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x100208ca0 ""\0
CUR = 0
LEN = 16
Perl 5 の内部構造に慣れていない方のために説明すると、 aPVNV
は 3 つの単純なスカラー型 (integer IV
、倍精度 float NV
、string PV
) をすべて保持するスカラー構造体です。フラグIOK
、NOK
、およびPOK
は、integer、double、および string の値がすべて同期していることを意味するため (同期の定義によって)、それらのいずれかを使用できます (つまり、整数として使用する場合は変換を行う必要はありません)。 、double、または文字列)。
空の文字列が偽の文字列として選択されたのは、"0"
. 小さいという私の声明は無視してください。両方とも""
同じ"1"
サイズです: 16 文字です。ダンプでそう言っています。Perl 5 では、文字列が急速に大きくなるように、文字列に余分なスペースを追加します。
ああ、私はあなたが嫌いです。これを調査したところ、嘘をついたことperlopquick
がわかり、修正する方法を見つける必要があります。あなたが他のすべての羊と同じように、Perl 5 の表面の奇妙さを事実として受け入れていれば、私がやるべきことはもっと少なくなったでしょう。
編集セクションの質問への回答:
false 値の文字列表現として true (たとえば "false") の文字列を使用すると、既存のコードの意味がどのように変わるでしょうか?
PL_sv_yes と PL_sv_no (比較演算子によって返される正規の true 値と false 値) に関する唯一の特別な点は、それらが読み取り専用であり、perl
実行中のプログラムによって作成されないことです。これらを変更しても真偽判定は変わらないため、PL_sv_no を設定する"false"
と true として扱われます。ドキュメント化されていない次の機能を使用して、自分でこれを行うこともできます (このコードは、Perl 5.18 と最新の Perl の間のある時点で機能しなくなります) perl
。
#!/usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw/dualvar/;
BEGIN {
# use the undocumented SvREADONLY function from Internals to
# modify a reference to PL_sv_no's readonly flag
# note the use of & to make the compiler not use SvREADONLY's
# prototype, yet another reason prototypes are bad and shouldn't
# be used
&Internals::SvREADONLY(\!!0, 0);
# set PL_sv_no to a dualvar containing 0 and "false"
${\!!0} = dualvar 0, "false";
}
if (5 < 4) {
print "oops\n";
}
出力
opps
これは、真実性テストが最初に文字列を調べるためです。
そのような変更の後にセマンティクスを変更するコードは、以前よりも堅牢性/正確性が低下していると言えますか?
真っ直ぐ壊れます。int 0 または文字列 "0" (どちらも false) に設定するように制限しても、一部の有効なコードが壊れます。
文字列コンテキストは Perl で非常に普及しているため、正気のセマンティクスにつながる唯一のオプションは、ブール値が文字列との間のラウンドトリップ後にその値を保持する場合です...
はい。