เห็นได้ชัดว่าuse strict
ควร (ต้อง) ใช้เมื่อคุณต้องการบังคับให้ perl เขียนโค้ดอย่างถูกต้องซึ่งอาจเป็นการบังคับให้มีการประกาศโดยมีความชัดเจนเกี่ยวกับสตริงและส่วนย่อยเช่น barewords หรือใช้การอ้างอิงด้วยความระมัดระวัง หมายเหตุ: หากมีข้อผิดพลาดให้ใช้อย่างเข้มงวดจะยกเลิกการดำเนินการหากใช้
แม้ว่าuse warnings;
จะช่วยให้คุณพบข้อผิดพลาดในการพิมพ์ในโปรแกรมเช่นคุณพลาดอัฒภาค แต่คุณใช้ "elseif" ไม่ใช่ "elsif" แต่คุณกำลังใช้ไวยากรณ์หรือฟังก์ชันที่เลิกใช้แล้วไม่ว่าจะอย่างนั้นก็ตาม หมายเหตุ: คำเตือนการใช้งานจะให้คำเตือนและดำเนินการต่อเช่นจะไม่ยกเลิกการดำเนินการ ..
อย่างไรก็ตามมันจะดีกว่าถ้าเราลงรายละเอียดซึ่งฉันระบุไว้ด้านล่าง
จากperl.com (รายการโปรด):
ใช้ 'vars' ที่เข้มงวด
ซึ่งหมายความว่าคุณต้องประกาศตัวแปรก่อนที่จะใช้เสมอ
หากคุณไม่ประกาศคุณอาจได้รับข้อความแสดงข้อผิดพลาดสำหรับตัวแปรที่ไม่ได้ประกาศ
สัญลักษณ์ส่วนกลาง "$ variablename" ต้องการชื่อแพ็กเกจที่ชัดเจนที่ scriptname.pl บรรทัดที่ 3
คำเตือนนี้หมายความว่า Perl ไม่ชัดเจนว่าขอบเขตของตัวแปรคืออะไร ดังนั้นคุณต้องมีความชัดเจนเกี่ยวกับตัวแปรของคุณซึ่งหมายถึงการประกาศตัวแปรเหล่านี้ด้วยmy
เพื่อให้ถูก จำกัด ไว้ที่บล็อกปัจจุบันหรืออ้างอิงถึงตัวแปรด้วยชื่อที่มีคุณสมบัติครบถ้วน (เช่น: $ MAIN :: variablename)
ดังนั้นข้อผิดพลาดเวลาคอมไพล์จะถูกทริกเกอร์หากคุณพยายามเข้าถึงตัวแปรที่ไม่ตรงตามเกณฑ์อย่างน้อยหนึ่งข้อต่อไปนี้:
กำหนดไว้ล่วงหน้าโดย Perl เองเช่น @ARGV,% ENV และตัวแปรเครื่องหมายวรรคตอนทั้งหมดเช่น $ หรือ $ _.
ประกาศด้วย (สำหรับทั่วโลก) หรือของฉัน (สำหรับคำศัพท์)
นำเข้าจากแพ็คเกจอื่น (การใช้ vars pragma ปลอมการนำเข้า แต่ใช้ของเราแทน)
มีคุณสมบัติครบถ้วนโดยใช้ชื่อแพ็กเกจและตัวคั่นแพ็กเกจ double-colon
ใช้ 'subs' ที่เข้มงวด
พิจารณาสองโปรแกรม
# prog 1
$a = test_value;
print "First program: ", $a, "\n";
sub test_value { return "test passed"; }
Output: First program's result: test_value
# prog 2
sub test_value { return "test passed"; }
$a = test_value;
print "Second program: ", $a, "\n";
Output: Second program's result: test passed
ในทั้งสองกรณีเรามีค่าย่อย test_value () และเราต้องการใส่ผลลัพธ์เป็น $ a และเมื่อเราเรียกใช้ทั้งสองโปรแกรมเราจะได้ผลลัพธ์ที่แตกต่างกันสองรายการ:
ในโปรแกรมแรก ณ จุดที่เราไปถึง$a = test_value;
Perl จะไม่ทราบถึง test_value () ย่อยใด ๆ และ test_value จะตีความเป็นสตริง 'test_value' ในโปรแกรมที่สองนิยามของ test_value () จะอยู่ก่อน$a = test_value;
บรรทัด Perl คิดว่า test_value เป็นการเรียกย่อย
ระยะทางเทคนิคสำหรับคำที่แยกได้เช่น test_value ที่อาจจะมีผู้ใต้บังคับบัญชาและอาจจะเป็นสตริงขึ้นอยู่กับบริบทโดยวิธีการที่เป็นbareword การจัดการBarewordsของ Perl อาจทำให้เกิดความสับสนและอาจทำให้เกิดข้อผิดพลาดในโปรแกรม
จุดบกพร่องคือสิ่งที่เราพบในโปรแกรมแรกของเราโปรดจำไว้ว่า Perl จะไม่รอคอยที่จะพบtest_value()
ดังนั้นเนื่องจากยังไม่เห็น test_value () จึงถือว่าคุณต้องการสตริง ดังนั้นถ้าคุณuse strict subs;
มันจะทำให้โปรแกรมนี้ตายด้วยข้อผิดพลาด:
ไม่อนุญาตให้ใช้ Bareword "test_value" ในขณะที่ใช้ "กลุ่มย่อยที่เข้มงวด" ที่ ./a6-strictsubs.pl บรรทัดที่ 3
วิธีแก้ไขข้อผิดพลาดนี้คือ
1. ใช้วงเล็บเพื่อให้ชัดเจนว่าคุณกำลังเรียกหน่วยย่อย หาก Perl เห็น $ a = test_value ();
2. ประกาศย่อยของคุณก่อนใช้งานครั้งแรก
use strict;
sub test_value; # Declares that there's a test_value() coming later ...
my $a = test_value; # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }
3. และหากคุณต้องการใช้เป็นสตริงให้อ้าง
ดังนั้นการเข้มงวดนี้ทำให้ Perl ถือว่า barewords ทั้งหมดเป็นข้อผิดพลาดทางไวยากรณ์ A * barewordเป็นชื่อเปลือยใด ๆ หรือระบุว่าไม่เคยมีใครตีความอื่น ๆ บังคับโดยบริบท (บริบทมักถูกบังคับโดยคีย์เวิร์ดหรือโทเค็นที่อยู่ใกล้เคียงหรือโดยการประกาศล่วงหน้าของคำที่เป็นปัญหา) * ดังนั้นหากคุณต้องการใช้เป็นสตริงให้อ้างถึงและหากคุณต้องการใช้เป็นการเรียกใช้ฟังก์ชันให้ระบุไว้ล่วงหน้า หรือใช้วงเล็บ
Barewords เป็นอันตรายเนื่องจากพฤติกรรมที่คาดเดาไม่ได้นี้ use strict; (or use strict 'subs';)
ทำให้สามารถคาดเดาได้เนื่องจากคำเปล่าที่อาจทำให้เกิดพฤติกรรมแปลก ๆ ในอนาคตจะทำให้โปรแกรมของคุณตายก่อนที่จะสร้างความหายนะ
มีสถานที่แห่งหนึ่งที่คุณสามารถใช้ barewords ได้แม้ว่าคุณจะเปิดการใช้งานแบบเข้มงวด: เมื่อคุณกำหนดแฮชคีย์
$hash{sample} = 6; # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );
Barewords ในแฮชคีย์ถูกตีความเป็นสตริงเสมอดังนั้นจึงไม่มีความคลุมเครือ
ใช้ 'refs' ที่เข้มงวด
สิ่งนี้จะสร้างข้อผิดพลาดขณะทำงานหากคุณใช้การอ้างอิงเชิงสัญลักษณ์ไม่ว่าจะโดยเจตนาหรืออย่างอื่น ค่าที่ไม่ได้มีการอ้างอิงที่ยากคือการได้รับการรักษาแล้วเป็นอ้างอิงสัญลักษณ์ นั่นคือการอ้างอิงถูกตีความเป็นสตริงที่แสดงชื่อของตัวแปรส่วนกลาง
use strict 'refs';
$ref = \$foo; # Store "real" (hard) reference.
print $$ref; # Dereferencing is ok.
$ref = "foo"; # Store name of global (package) variable.
print $$ref; # WRONG, run-time error under strict refs.
ใช้คำเตือน
pragma ที่กำหนดขอบเขตคำศัพท์นี้ช่วยให้สามารถควบคุมคำเตือนในตัวของ Perl ได้อย่างยืดหยุ่นทั้งที่ปล่อยออกมาโดยคอมไพเลอร์และจากระบบรันไทม์
จากperldiag
:
ดังนั้นข้อความเตือนส่วนใหญ่จากการจำแนกประเภทด้านล่างเช่น W, D & S สามารถควบคุมได้โดยใช้warnings
pragma
(W) คำเตือน (ทางเลือก)
(D) การเลิกใช้งาน (เปิดใช้งานโดยค่าเริ่มต้น)
(S) คำเตือนที่รุนแรง (เปิดใช้งานโดยค่าเริ่มต้น)
ฉันได้ระบุข้อความเตือนบางส่วนที่มักเกิดขึ้นด้านล่างตามการจำแนกประเภท สำหรับข้อมูลโดยละเอียดเกี่ยวกับพวกเขาและข้อความอื่น ๆ โปรดดูที่perldiag
(W) คำเตือน (ทางเลือก):
ไม่มีอาร์กิวเมนต์ใน% s ไม่มี
อาร์กิวเมนต์ถึง -% c
(คุณหมายถึง &% s แทนหรือไม่)
(คุณหมายถึง "local" แทน "ของเรา" หรือไม่)
(คุณหมายถึง $ หรือ @ แทน%?)
'% s 'ไม่ใช่รหัสอ้างอิง
length () ที่ใช้กับ% s
Misplaced _ in number
(D) การเลิกใช้งาน (เปิดใช้งานโดยค่าเริ่มต้น):
กำหนด (@array) เลิกใช้แล้ว
กำหนด (แฮช%) เลิกใช้แล้ว
เลิกใช้งานของฉัน () ในเงื่อนไขเท็จ
$ # ไม่ได้รับการสนับสนุนอีกต่อไป
(S) คำเตือนที่รุนแรง (เปิดใช้งานโดยค่าเริ่มต้น)
elseif ควรเป็น elsif
% s ที่พบในที่ที่คาดว่าจะมีตัวดำเนินการ
(ตัวดำเนินการหายไปก่อน% s?)
(ไม่มีเครื่องหมายอัฒภาคในบรรทัดก่อนหน้า?)
% s ไม่เคยแนะนำตัว
ดำเนินการหรืออัฒภาคที่ขาดหายไปก่อน% s
ปัญหาลำดับความสำคัญ: เปิด% s ควรเปิด (% s)
ต้นแบบไม่ตรงกัน:% s เทียบกับ% s
คำเตือน: การใช้ "% s" โดยไม่มีวงเล็บมีความคลุมเครือไม่
สามารถเปิด% s:% s
use loose;