Các toán tử logic khác nhau không trả về một chuỗi rỗng, chúng trả về một giá trị sai hoặc đúng trong cả ba loại vô hướng đơn giản. Nó chỉ có vẻ như nó trả về một chuỗi rỗng vì print
buộc một bối cảnh chuỗi trên đối số của nó:
#!/usr/bin/perl
use strict;
use warnings;
use Devel::Peek;
my $t = 5 > 4;
my $f = 5 < 4;
Dump $t;
Dump $f;
Output:
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
Đối với những người không quen thuộc với Perl 5 internals, một PVNV
là một vô hướng cấu trúc chứa tất cả ba loại vô hướng đơn giản (số nguyên IV
, phao chính xác kép NV
và chuỗi PV
). Các cờ IOK
, NOK
và POK
có nghĩa là tất cả các giá trị số nguyên, đôi và chuỗi đều được đồng bộ hóa (đối với một số định nghĩa đồng bộ) để bất kỳ một trong số chúng có thể được sử dụng (tức là không cần chuyển đổi nếu bạn sử dụng nó dưới dạng số nguyên, gấp đôi hoặc chuỗi).
Tôi giả định chuỗi rỗng đã được chọn cho chuỗi sai vì nó
nhỏ hơn và
phù hợp hơn với ý tưởng về chuỗi sai hơn "0"
. Bỏ qua tuyên bố của tôi về nó nhỏ hơn, cả hai ""
và "1"
có cùng kích thước: mười sáu ký tự. Nó nói như vậy ngay trong bãi chứa. Perl 5 bổ sung thêm không gian cho các chuỗi để cho phép chúng phát triển nhanh chóng.
Ồ, và tôi ghét bạn. Trong nghiên cứu này tôi đã tìm thấy rằng tôi đã nói dối trong perlopquick
và bây giờ sẽ phải tìm một cách để sửa chữa nó. Nếu chỉ có bạn giống như tất cả những con cừu khác và chỉ chấp nhận sự kỳ lạ bề ngoài của Perl 5 là sự thật, tôi sẽ có ít việc phải làm hơn.
Câu trả lời cho các câu hỏi trong phần EDIT:
Làm thế nào sẽ sử dụng chuỗi đó là sự thật ("false" chẳng hạn) như một chuỗi đại diện của các giá trị sai thay đổi ý nghĩa của mã hiện tại?
duy nhất điều đặc biệt về khoảng PL_sv_yes và PL_sv_no (các giá trị giáo luật true và false trả về bởi toán tử so sánh) được rằng họ được chỉ đọc và được tạo ra bởi perl
không phải là chương trình đang chạy. Nếu bạn thay đổi chúng, nó không thay đổi kiểm tra sự thật, vì vậy một PL_sv_no được đặt là "false"
sẽ được coi là đúng. Bạn thậm chí có thể làm điều này cho mình (mã này ngừng hoạt động tại một số điểm giữa Perl 5.18 và sự Perl mới nhất) sử dụng các tính năng không có giấy tờ của 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";
}
đầu ra
opps
Điều này là do ngoại hình thử nghiệm truthiness tại chuỗi đầu tiên.
Chúng ta có thể nói rằng mã thay đổi ngữ nghĩa sau khi thay đổi như vậy ít mạnh mẽ/chính xác hơn so với nó có thể là?
Nó sẽ bị hỏng thẳng. Ngay cả khi bạn giới hạn bản thân để đặt nó thành một int 0 hoặc một chuỗi "0" (cả hai đều sai), nó sẽ phá vỡ một số mã hợp lệ.
Tôi đoán chuỗi bối cảnh rất phổ biến trong Perl rằng lựa chọn duy nhất dẫn đến ngữ nghĩa lành mạnh là nếu giá trị boolean duy trì giá trị của nó sau khi vòng vấp ngã đến và đi từ một chuỗi ...
Yes.
Bản sao có thể có của [Tại sao! 1 cho tôi không có gì trong Perl?] (Http://stackoverflow.com/questions/1134962/why-does-1-give-me-nothing-in-perl) – Thilo