Anda mungkin ingin memulai dengan buku saya Learning Perl . Lebih mudah daripada menebak apa yang harus dilakukan sampai Anda melakukannya dengan benar (monyet, mesin tik, dan Hamlet, dan semua itu). :)
brian d foy
Jawaban:
285
Dalam Perl, yang berikut ini bernilai false dalam kondisi:
0'0'undef''# Empty scalar()# Empty list('')
Sisanya benar. Tidak ada kata kunci untuk trueatau false.
@BlueWaldo: Anda juga dapat menggunakan cmp dan <=> saat membandingkan dan menetapkan hasil perbandingan ke skalar. $ var = $ var1 cmp $ var2; 'cmp' dan '<=>' (digunakan untuk perbandingan numerik) mengembalikan -1, 0, atau 1 jika argumen kiri kurang dari, sama dengan, atau lebih besar dari argumen kanan. Ini bukan boolean tetapi kadang-kadang Anda mungkin ingin tahu apakah satu argumen ir sama atau kurang dari atau lebih besar dari yang lain, bukan hanya sama atau tidak sama.
user118435
9
Masalah 1: Daftar kosong tidak salah, karena tidak mungkin untuk memeriksa apakah daftar itu benar atau salah. Daftar kosong dalam konteks skalar kembali undef.
ikegami
4
Masalah 2: ('')dan ''nilainya sama. Saya pikir Anda ingin menyiratkan daftar dengan elemen yang terdiri dari string kosong (walaupun parens tidak membuat daftar), tetapi seperti yang telah saya sebutkan, tidak mungkin untuk memeriksa apakah daftar itu benar atau salah.
ikegami
6
Masalah 3: Objek dengan operator boolean yang kelebihan beban juga bisa salah.
ikegami
15
@eternicode, Perl memang memiliki dua nilai spesifik yang digunakan ketika perlu mengembalikan benar dan salah, jadi tidak hanya memiliki boolean, ia memiliki true ( !0alias PL_sv_yes) dan false ( !1aka PL_sv_no). Atau apakah Anda mengatakan Perl seharusnya tidak berubah setiap kali sesuatu selain kedua nilai ini diuji kebenarannya? Itu akan sangat mengerikan. misalnya itu akan mencegah$x ||= $default;
ikegami
71
Definisi palsu paling lengkap dan ringkas yang pernah saya temui adalah:
Apa pun yang merangkai ke string kosong atau string 0itu salah. Yang lainnya benar.
Oleh karena itu, nilai-nilai berikut ini salah:
String kosong
Nilai numerik nol
Nilai yang tidak ditentukan
Objek dengan operator boolean yang kelebihan beban yang mengevaluasi salah satu di atas.
Variabel ajaib yang mengevaluasi salah satu di atas saat mengambil.
Perlu diingat bahwa daftar literal kosong mengevaluasi ke nilai yang tidak ditentukan dalam konteks skalar, jadi itu mengevaluasi ke sesuatu yang salah.
Catatan tentang "nol sejati"
Meskipun angka yang dirujuk 0salah, string yang numify ke nol belum tentu. Satu-satunya string palsu adalah 0dan string kosong. String lain, bahkan jika numify menjadi nol, adalah benar.
Berikut ini adalah string yang benar sebagai boolean dan nol sebagai angka:
Tanpa peringatan:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Dengan peringatan:
String apa pun yang Scalar::Util::looks_like_numbermengembalikan false. (mis. "abc")
jika saya mengerti Anda benar kata true di While angka-angka yang merangkai ke 0 benar harus salah atau (untuk mencegah kebingungan) mengevaluasi ke false .
user907860
1
Definisi "ringkas" Anda tidak konsisten dengan penjelasan yang lebih panjang. Pertimbangkan: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. Sekarang $valueakan dikencangkan menjadi "XXX" tetapi boolify menjadi false.
tobyink
1
@tobyink, Versi ringkasnya tidak sempurna, hanya yang terbaik yang saya temukan. Ini dimaksudkan untuk menjadi praktis, tidak mencakup semua. Perhatikan bahwa nilai yang dikembalikan oleh boolstring Anda menjadi 0. Selain itu, Anda tidak disarankan untuk membuat overload yang tidak konsisten, dan nilai yang Anda kembalikan dapat dianggap demikian. (mis. a &&dapat dioptimalkan menjadi ||, jadi jika ini tidak konsisten, Anda akan memiliki masalah.)
ikegami
Saya tidak yakin apakah 0x00dibahas di sini.
Zaid
@Zaid, Apakah maksud Anda nilai yang dikembalikan oleh kode 0x00(nilai numerik nol) atau string 0x00(yang looks_like_numbersalah)? Either way, itu sudah dibahas.
ikegami
59
Perl tidak memiliki tipe boolean asli, tetapi Anda dapat menggunakan perbandingan bilangan bulat atau string untuk mendapatkan perilaku yang sama. Contoh Alan adalah cara yang baik untuk melakukannya dengan menggunakan perbandingan bilangan bulat. Ini sebuah contoh
my $boolean =0;if( $boolean ){print"$boolean evaluates to true\n";} else {print"$boolean evaluates to false\n";}
Satu hal yang saya lakukan di beberapa program saya adalah menambahkan perilaku yang sama menggunakan konstanta:
Baris yang ditandai dalam "use constant" mendefinisikan konstanta bernama true yang selalu mengevaluasi ke 1, dan konstanta bernama false yang selalu dievaluasi oleh 0. Karena cara konstanta didefinisikan dalam Perl, baris kode berikut juga gagal:
true =0;
true = false;
Pesan kesalahan harus mengatakan sesuatu seperti "Tidak dapat mengubah konstan dalam tugas skalar."
Saya melihat bahwa di salah satu komentar Anda bertanya tentang membandingkan string. Anda harus tahu bahwa karena Perl menggabungkan string dan tipe numerik dalam variabel skalar, Anda memiliki sintaks berbeda untuk membandingkan string dan angka:
my $var1 ="5.0";my $var2 ="5";print"using operator eq\n";if( $var1 eq $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}print"using operator ==\n";if( $var1 == $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}
Perbedaan antara operator ini adalah sumber kebingungan yang sangat umum di Perl.
Menggunakan konstanta sebagai makro pria miskin dengan cara itu berbahaya. Contoh kode ini tidak setara: if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; }, yang mungkin tidak jelas bagi pengamat biasa. (Dan ya, contoh terakhir adalah gaya pemrograman yang buruk, tapi itu intinya).
Zano
16
Saya merekomendasikan use boolean;. Anda harus menginstal modul boolean dari cpan.
Dalam Perl, seperti dalam kehidupan, ada banyak kebenaran. Orang yang tidak berpengalaman suka menulis hal-hal konyol seperti if ($my_true_value == true). Berpura-pura bahwa ada Satu Kebenaran Sejati, dalam pengalaman saya, jalan menuju rasa sakit, dan kode yang tidak efisien.
tjd
2
Perl bersifat filosofis
ILMostro_7
13
Favorit saya selalu begitu
use constant FALSE =>1==0;use constant TRUE => not FALSE;
yang sepenuhnya independen dari representasi internal.
Jawaban yang buruk, tetapi sumber yang kuat dan memiliki reputasi baik di perlmonks.org. Alangkah baiknya memiliki beberapa konten nyata, bukan komentar dan tautan. : - /
ILMostro_7
0
gunakan awalan file berikut, ini akan menambah skrip perl Anda eTRUE dan eFALSE, itu sebenarnya akan REAL (!) benar dan salah (seperti java)
#!/usr/bin/perluse strict;use warnings;use constant {#real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
eTRUE => bless(do{\(my $o =1)},'JSON::PP::Boolean'),
eFALSE => bless(do{\(my $o =0)},'JSON::PP::Boolean')};
Sebenarnya, ada beberapa alasan mengapa Anda harus menggunakannya.
Alasan saya adalah bahwa bekerja dengan JSON, saya punya 0 dan 1 sebagai nilai untuk kunci, tetapi peretasan ini akan memastikan nilai yang benar disimpan di sepanjang skrip Anda.
Jawaban:
Dalam Perl, yang berikut ini bernilai false dalam kondisi:
Sisanya benar. Tidak ada kata kunci untuk
true
ataufalse
.sumber
undef
.('')
dan''
nilainya sama. Saya pikir Anda ingin menyiratkan daftar dengan elemen yang terdiri dari string kosong (walaupun parens tidak membuat daftar), tetapi seperti yang telah saya sebutkan, tidak mungkin untuk memeriksa apakah daftar itu benar atau salah.!0
aliasPL_sv_yes
) dan false (!1
akaPL_sv_no
). Atau apakah Anda mengatakan Perl seharusnya tidak berubah setiap kali sesuatu selain kedua nilai ini diuji kebenarannya? Itu akan sangat mengerikan. misalnya itu akan mencegah$x ||= $default;
Definisi palsu paling lengkap dan ringkas yang pernah saya temui adalah:
Oleh karena itu, nilai-nilai berikut ini salah:
Perlu diingat bahwa daftar literal kosong mengevaluasi ke nilai yang tidak ditentukan dalam konteks skalar, jadi itu mengevaluasi ke sesuatu yang salah.
Catatan tentang "nol sejati"
Meskipun angka yang dirujuk
0
salah, string yang numify ke nol belum tentu. Satu-satunya string palsu adalah0
dan string kosong. String lain, bahkan jika numify menjadi nol, adalah benar.Berikut ini adalah string yang benar sebagai boolean dan nol sebagai angka:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Scalar::Util::looks_like_number
mengembalikan false. (mis."abc"
)sumber
my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };
. Sekarang$value
akan dikencangkan menjadi "XXX" tetapi boolify menjadi false.bool
string Anda menjadi0
. Selain itu, Anda tidak disarankan untuk membuat overload yang tidak konsisten, dan nilai yang Anda kembalikan dapat dianggap demikian. (mis. a&&
dapat dioptimalkan menjadi||
, jadi jika ini tidak konsisten, Anda akan memiliki masalah.)0x00
dibahas di sini.0x00
(nilai numerik nol) atau string0x00
(yanglooks_like_number
salah)? Either way, itu sudah dibahas.Perl tidak memiliki tipe boolean asli, tetapi Anda dapat menggunakan perbandingan bilangan bulat atau string untuk mendapatkan perilaku yang sama. Contoh Alan adalah cara yang baik untuk melakukannya dengan menggunakan perbandingan bilangan bulat. Ini sebuah contoh
Satu hal yang saya lakukan di beberapa program saya adalah menambahkan perilaku yang sama menggunakan konstanta:
Baris yang ditandai dalam "use constant" mendefinisikan konstanta bernama true yang selalu mengevaluasi ke 1, dan konstanta bernama false yang selalu dievaluasi oleh 0. Karena cara konstanta didefinisikan dalam Perl, baris kode berikut juga gagal:
Pesan kesalahan harus mengatakan sesuatu seperti "Tidak dapat mengubah konstan dalam tugas skalar."
Saya melihat bahwa di salah satu komentar Anda bertanya tentang membandingkan string. Anda harus tahu bahwa karena Perl menggabungkan string dan tipe numerik dalam variabel skalar, Anda memiliki sintaks berbeda untuk membandingkan string dan angka:
Perbedaan antara operator ini adalah sumber kebingungan yang sangat umum di Perl.
sumber
use warnings;
bukannya#! perl -w
if ($exitstatus) { exit; }
vsif ($exitstatus == true) { exit; }
, yang mungkin tidak jelas bagi pengamat biasa. (Dan ya, contoh terakhir adalah gaya pemrograman yang buruk, tapi itu intinya).Saya merekomendasikan
use boolean;
. Anda harus menginstal modul boolean dari cpan.sumber
if ($my_true_value == true)
. Berpura-pura bahwa ada Satu Kebenaran Sejati, dalam pengalaman saya, jalan menuju rasa sakit, dan kode yang tidak efisien.Favorit saya selalu begitu
yang sepenuhnya independen dari representasi internal.
sumber
Saya menemukan tutorial yang memiliki penjelasan yang baik tentang Nilai-nilai apa yang benar dan salah di Perl . Ini menyatakan bahwa:
Nilai skalar berikut ini dianggap salah:
undef
- nilai yang tidak ditentukan0
angka 0, bahkan jika Anda menuliskannya sebagai 000 atau 0,0''
string kosong.'0'
string yang berisi 0 digit tunggal.Semua nilai skalar lainnya, termasuk yang berikut ini benar:
1
nomor bukan-0' '
string dengan spasi di dalamnya'00'
dua atau lebih 0 karakter dalam sebuah string"0\n"
a 0 diikuti oleh baris baru'true'
'false'
ya, bahkan string 'false' dinilai benar.Ada tutorial bagus lainnya yang menjelaskan tentang Perl benar dan salah .
sumber
Penjelasan indah yang diberikan oleh bobf untuk nilai Boolean: Benar atau Salah? Panduan Referensi Cepat
Tes kebenaran untuk nilai yang berbeda
sumber
gunakan awalan file berikut, ini akan menambah skrip perl Anda eTRUE dan eFALSE, itu sebenarnya akan REAL (!) benar dan salah (seperti java)
Sebenarnya, ada beberapa alasan mengapa Anda harus menggunakannya.
Alasan saya adalah bahwa bekerja dengan JSON, saya punya 0 dan 1 sebagai nilai untuk kunci, tetapi peretasan ini akan memastikan nilai yang benar disimpan di sepanjang skrip Anda.
sumber