Pertanyaan Gotchas umum untuk Perl? [Tutup]


Pertanyaannya Fitur tersembunyi dari Perl menghasilkan setidaknya satu Respon yang bisa dianggap sebagai fitur atau salah-fitur. Tampaknya logis untuk menindaklanjuti dengan pertanyaan ini: apa kesalahan umum yang tidak jelas dalam Perl? Hal-hal yang sepertinya mereka harus bekerja, tetapi tidak.

Saya tidak akan memberikan panduan tentang bagaimana menyusun jawaban, atau apa yang "terlalu mudah" untuk dianggap sebagai sebuah cara, karena untuk itulah pemungutan suara.

Daftar Jawaban

Sintaksis

Semantik / Fitur Bahasa

Debugging

Praktik terbaik

Meta-Answers

Lihat juga: ASP.NET - Gotchas umum


74
2017-10-03 12:51


asal


Jawaban:


Fakta bahwa tanda kutip tunggal dapat digunakan untuk menggantikan :: in identifiers.

Mempertimbangkan:

use strict;
print "$foo";        #-- Won't compile under use strict
print "$foo's fun!"; #-- Compiles just fine, refers to $foo::s

Memimpin ke masalah berikut:

use strict;
my $name = "John";
print "$name's name is '$name'";
# prints:
#  name is 'John'

Cara yang disarankan untuk menghindari ini adalah dengan menggunakan tanda kurung di sekitar nama variabel Anda:

print "${name}'s name is '$name'";
# John's name is 'John'

Dan juga untuk use warnings, karena akan memberi tahu Anda tentang penggunaan variabel tidak terdefinisi $name::s


37
2017-10-03 14:25



Anda dapat mencetak ke file-file leksikal: bagus.

print $out "hello, world\n";

Anda kemudian menyadari itu mungkin bagus untuk memiliki hash file-file:

my %out;
open $out{ok},   '>', 'ok.txt' or die "Could not open ok.txt for output: $!";
open $out{fail}, '>', 'fail.txt' or die "Could not open fail.txt for output: $!";

Sejauh ini bagus. Sekarang coba gunakan mereka, dan cetak ke satu atau yang lain sesuai dengan kondisi:

my $where = (frobnitz() == 10) ? 'ok' : 'fail';

print $out{$where} "it worked!\n"; # it didn't: compile time error

Anda harus membungkus dereference hash di sepasang curlies:

print {$out{$where}} "it worked!\n"; # now it did

Ini benar-benar perilaku yang tidak intuitif. Jika Anda tidak mendengar tentang hal ini, atau membacanya di dokumentasi, saya ragu Anda dapat mengetahuinya sendiri.


28
2017-10-04 00:45



Ini adalah jawaban-meta. Banyak gotchas jahat yang tertangkap Perl :: Kritik, yang dapat Anda instal dan jalankan dari baris perintah dengan perlcritic perintah, atau (jika Anda senang mengirim kode Anda di Internet, dan tidak dapat menyesuaikan opsi Anda) melalui Perl :: Situs web Kritik.

Perl::Critic juga menyediakan referensi ke Damian Conways Perl Praktik Terbaik buku, termasuk nomor halaman. Jadi jika Anda terlalu malas untuk membaca seluruh buku, Perl::Critic masih bisa memberi tahu Anda bit Anda harus sedang membaca.


26
2017-10-03 15:11



Perl's DWIMmer berjuang dengan << (di sini-dokumen) notasi saat menggunakan print dengan file-file leksikal:

# here-doc
print $fh <<EOT;
foo
EOT

# here-doc, no interpolation
print $fh <<'EOT';
foo
EOT

# bitshift, syntax error
# Bareword "EOT" not allowed while "strict subs" in use
print $fh<<EOT;
foo
EOT

# bitshift, fatal error
# Argument "EOT" isn't numeric...
# Can't locate object method "foo" via package "EOT"...
print $fh<<'EOT';
foo
EOT

Solusinya adalah baik hati-hati untuk memasukkan spasi antara filehandle dan file << atau untuk menguraikan filehandle dengan membungkusnya {} kawat gigi:

print {$fh}<<EOT;
foo
EOT

18
2017-10-03 21:06



Itu perltrap halaman manual mencantumkan banyak perangkap bagi yang tidak waspada yang diatur menurut jenisnya.


17
2017-10-03 12:59



Menetapkan array ke skalar tidak masuk akal bagi saya. Sebagai contoh:

$foo = ( 'a', 'b', 'c' );

Menetapkan 'c' ke $ foo dan membuang sisa dari array. Yang ini lebih aneh:

@foo = ( 'a', 'b', 'c' );
$foo = @foo;

Ini sepertinya harus melakukan hal yang sama seperti contoh pertama, tetapi malah set $foo ke panjangnya dari @foo, jadi $foo == 3.


15
2017-10-03 12:55



Gotcha yang paling umum adalah memulai file Anda dengan sesuatu yang berbeda

use strict;
use diagnostics;

pjf menambahkan: Harap diperingatkan bahwa diagnosa memiliki penting berdampak pada kinerja. Ini memperlambat program start-up, karena perlu memuat perldiag.pod, dan sampai bleadperl pada beberapa minggu yang lalu, itu juga memperlambat dan memperberat regexps karena menggunakan $ &. Menggunakan peringatan dan berlari splain pada hasil direkomendasikan.


15
2017-10-03 12:58



Membingungkan referensi dan objek sebenarnya:

$a = [1,2,3,4];
print $a[0];

(Ini seharusnya salah satunya $a->[0] (terbaik), $$a[0], @{$a}[0] atau @$a[0])


15
2017-10-06 17:07



Deklarasi "saya" harus menggunakan tanda kurung di sekitar daftar variabel

use strict;
my $a = 1;
mysub();
print "a is $a\n";

sub {
    my $b, $a;   # Gotcha!
    $a = 2;
}

Ini mencetak a adalah 2 karena my deklarasi hanya berlaku untuk $b (penyebutan $a pada baris itu tidak melakukan apa-apa). Perhatikan bahwa ini terjadi tanpa peringatan bahkan ketika "penggunaan ketat" berlaku.

Menambahkan "penggunaan peringatan" (atau tanda -w) meningkatkan banyak hal dengan kata Perl Tanda kurung hilang di sekitar daftar "saya". Ini menunjukkan, seperti sudah banyak orang, mengapa pragma yang ketat dan penuh peringatan selalu merupakan ide yang baik.


14
2017-10-06 17:24



Penggunaan nilai terinisialisasi dalam penggabungan ...

Yang ini membuatku gila. Anda memiliki cetakan yang menyertakan sejumlah variabel, seperti:

print "$label: $field1, $field2, $field3\n";

Dan salah satu variabelnya adalah undef. Anda menganggap ini bug dalam program Anda - itulah mengapa Anda menggunakan pragma "ketat". Mungkin skema database Anda memungkinkan NULL dalam bidang yang tidak Anda harapkan, atau Anda lupa menginisialisasi variabel, dll. Tetapi semua pesan kesalahan memberitahu Anda bahwa nilai terinisialisasi terjadi selama penggabungan (.) operasi. Kalau saja itu memberitahu Anda nama variabel yang tidak diinisialisasi!

Karena Perl tidak ingin mencetak nama variabel dalam pesan kesalahan karena suatu alasan, Anda akhirnya melacaknya dengan mengatur breakpoint (untuk melihat variabel mana undef), atau menambahkan kode untuk memeriksa kondisinya. Sangat menjengkelkan ketika itu hanya terjadi satu kali dari ribuan dalam skrip CGI dan Anda tidak dapat membuat ulang dengan mudah.


14
2017-10-03 15:45