คุณสมบัติที่ซ่อนของ Perl?


143

อะไรคือคุณสมบัติภาษาที่มีประโยชน์จริงๆ แต่ลึกลับใน Perl ที่คุณสามารถใช้เพื่อทำงานที่เป็นประโยชน์ได้จริง?

แนวทาง:

  • พยายาม จำกัด คำตอบสำหรับแกน Perl ไม่ใช่ CPAN
  • โปรดยกตัวอย่างและคำอธิบายสั้น ๆ

คุณสมบัติที่ซ่อนอยู่ยังพบในคุณสมบัติที่ซ่อนอยู่ของภาษาอื่น:

(ทั้งหมดนี้มาจากคำตอบของ Corion )

    • อุปกรณ์ของดัฟฟ์
    • พกพาและมาตรฐาน
  • ค#
    • คำพูดสำหรับรายการและสตริงที่คั่นด้วยช่องว่าง
    • เนมสเปซที่ใช้นามแฝงได้
  • ชวา
    • Initalizers คงที่
  • JavaScript
    • ฟังก์ชั่นเป็นพลเมืองชั้นหนึ่ง
    • บล็อกขอบเขตและการปิด
    • วิธีการเรียกและ accessors ทางอ้อมผ่านตัวแปร
  • ทับทิม
    • การกำหนดวิธีการผ่านรหัส
  • PHP
    • เอกสารออนไลน์ที่แพร่หลาย
    • วิธีเวทย์มนตร์
    • การอ้างอิงสัญลักษณ์
  • หลาม
    • การสลับค่าหนึ่งบรรทัด
    • ความสามารถในการแทนที่ฟังก์ชั่นหลักด้วยฟังก์ชันของคุณเอง

คุณสมบัติที่ซ่อนอื่น ๆ :

ผู้ประกอบการ:

โครงสร้างการอ้างอิง:

ไวยากรณ์และชื่อ:

โมดูลตัวเลือก Pragmas และตัวเลือกบรรทัดคำสั่ง:

ตัวแปร:

ลูปและการควบคุมการไหล:

นิพจน์ทั่วไป:

คุณสมบัติอื่น ๆ :

เทคนิคอื่น ๆ และคำตอบเมตา:


ดูสิ่งนี้ด้วย:


คุณลักษณะส่วนใหญ่เหล่านี้มีการใช้งานในชีวิตประจำวันบางอย่างเกิดขึ้นในสคริปต์ Perl ส่วนใหญ่และส่วนใหญ่อยู่ภายใต้ "อื่น ๆ " ยังคงมีต้นกำเนิดมาจากภาษาอื่น ๆ การเรียก "ซ่อน" เหล่านี้เปลี่ยนเจตนาของคำถาม
reinierpost

คำตอบ:


54

ตัวดำเนินการ flip-flop มีประโยชน์สำหรับการข้ามการวนซ้ำครั้งแรกเมื่อวนรอบระเบียน (โดยทั่วไปคือบรรทัด) ที่ส่งคืนโดยตัวจัดการไฟล์โดยไม่ใช้ตัวแปรแฟล็ก:

while(<$fh>)
{
  next if 1..1; # skip first record
  ...
}

เรียกใช้perldoc perlopและค้นหา "flip-flop" เพื่อดูข้อมูลและตัวอย่างเพิ่มเติม


จริง ๆ แล้วนำมาจาก Awk ซึ่งคุณสามารถทำฟลิปฟล็อประหว่างสองแพทเทิร์นได้โดยการเขียน pattern1, pattern2
Bruno De Fraine

15
หากต้องการชี้แจงให้ชัดเจน "ที่ซ่อนอยู่" ของสิ่งนี้คือถ้าตัวถูกดำเนินการใด ๆ กับสเกลาร์ '.. ' เป็นค่าคงที่ค่าจะถูกเปรียบเทียบโดยนัยกับหมายเลขบรรทัดอินพุต ($.)
Michael Carman

47

มีคุณสมบัติที่ไม่ชัดเจนมากมายใน Perl

ตัวอย่างเช่นคุณรู้หรือไม่ว่าอาจมีช่องว่างหลังจาก sigil

 $ perl -wle 'my $x = 3; print $ x'
 3

หรือว่าคุณสามารถให้ชื่อที่เป็นตัวเลขย่อยได้ถ้าคุณใช้การอ้างอิงเชิงสัญลักษณ์?

$ perl -lwe '*4 = sub { print "yes" }; 4->()' 
yes

นอกจากนี้ยังมีตัวดำเนินการเสมือน "bool" ซึ่งส่งคืน 1 สำหรับนิพจน์จริงและสตริงว่างสำหรับเท็จ:

$ perl -wle 'print !!4'
1
$ perl -wle 'print !!"0 but true"'
1
$ perl -wle 'print !!0'
(empty line)

สิ่งที่น่าสนใจอื่น ๆ : use overloadคุณสามารถโหลดตัวอักษรและตัวเลขของสตริงได้มากเกินไป (เช่นทำให้ BigInts หรืออะไรก็ตาม)

หลายสิ่งเหล่านี้มีการบันทึกไว้ที่ใดที่หนึ่งจริง ๆ หรือทำตามเหตุผลจากคุณสมบัติที่เป็นเอกสาร แต่อย่างไรก็ตามบางอย่างก็ไม่เป็นที่รู้จัก

อัปเดต : อีกอันหนึ่งที่ดี ด้านล่างโครงสร้างการq{...}อ้างอิงถูกกล่าวถึง แต่คุณรู้หรือไม่ว่าคุณสามารถใช้ตัวอักษรเป็นตัวคั่นได้

$ perl -Mstrict  -wle 'print q bJet another perl hacker.b'
Jet another perl hacker.

ในทำนองเดียวกันคุณสามารถเขียนนิพจน์ปกติ:

m xabcx
# same as m/abc/

2
“ คุณรู้หรือไม่ว่าอาจมีช่องว่างหลังจาก sigil” ฉันงุนงงอย่างเต็มที่ ว้าว.
อริสโตเติล Pagaltzis

1
เย็น! !! $ undef_var ไม่ได้สร้างคำเตือน
Axeman

4
ฉันคิดว่าตัวอย่างของคุณในการใช้ตัวอักษรเพื่อกำหนดขอบเขตควรเป็น " Just another perl hacker" แทนที่จะเป็น "Jet another perl hacker" = P
Chris Lutz

ส่วนที่แย่ที่สุดคือคุณสามารถใช้สิ่งอื่นเป็นตัวคั่นได้เช่นกัน แม้จะปิดวงเล็บ ข้อมูลต่อไปนี้ถูกต้อง: s} regex} replace} xsmg; q] สตริงตัวอักษร];
Ryan C. Thompson

46

เพิ่มการรองรับไฟล์บีบอัดผ่านmagic ARGV :

s{ 
    ^            # make sure to get whole filename
    ( 
      [^'] +     # at least one non-quote
      \.         # extension dot
      (?:        # now either suffix
          gz
        | Z 
       )
    )
    \z           # through the end
}{gzcat '$1' |}xs for @ARGV;

(อัญประกาศประมาณ $ _ จำเป็นเพื่อจัดการชื่อไฟล์ด้วยเชลล์เมตาอักขระใน)

ตอนนี้<>คุณสมบัติจะขยาย@ARGVไฟล์ที่ลงท้ายด้วย ".gz" หรือ ".Z":

while (<>) {
    print;
}

2
ฉันไม่คิดว่าคุณจะต้องหลบหนีจาก|การแทนที่
คริสลัทซ์

ฉันกำลังจ้องมองที่นี้และฉันไม่สามารถหาวิธีการทำงาน จุดใดที่zcat |แยกวิเคราะห์เป็นคำสั่งเพื่อไพพ์ผ่าน?
อีเธอร์

1
@Ether => การตรวจสอบไพพ์เป็นคุณลักษณะของอาร์กิวเมนต์สองตัวที่เปิดอยู่ซึ่งตัวดำเนินการเพชรใช้ในการเปิดแต่ละไฟล์ใน@ARGV
Eric Strom

40

หนึ่งในคุณสมบัติที่ฉันโปรดปรานใน Perl คือการใช้ตัว||ดำเนินการบูลีนเพื่อเลือกระหว่างชุดตัวเลือก

 $x = $a || $b;

 # $x = $a, if $a is true.
 # $x = $b, otherwise

นี่หมายความว่าเราสามารถเขียน:

 $x = $a || $b || $c || 0;

จะใช้มูลค่าที่แท้จริงเป็นครั้งแรกจาก$a, $bและ$cหรือค่าเริ่มต้นของ0อย่างอื่น

ใน Perl 5.10 ยังมี//โอเปอเรเตอร์ซึ่งจะส่งคืนทางด้านซ้ายถ้ากำหนดไว้และทางขวามือเป็นอย่างอื่น ที่เลือกต่อไปนี้เป็นครั้งแรกที่กำหนดค่าจาก$a, $b, $cหรือ0อย่างอื่น

$ x = $ a // $ b // $ c // 0;

สิ่งเหล่านี้สามารถใช้กับแบบฟอร์มระยะสั้นซึ่งมีประโยชน์มากสำหรับการให้ค่าเริ่มต้น:

$ x || = 0; # ถ้า $ x เป็นเท็จตอนนี้จะมีค่าเป็น 0

$ x // = 0; # ถ้า $ x ไม่ได้ถูกกำหนดตอนนี้ก็จะมีค่าเป็นศูนย์

ไชโย,

พอล


4
นี่เป็นสำนวนสามัญที่แทบจะไม่ถือว่าเป็น "คุณสมบัติ" ที่ซ่อนอยู่
Michael Carman

3
ความอัปยศเครื่องพิมพ์สวยคิด // เป็นความเห็น :)
จอห์นเฟอร์กูสัน

2
คำถามมี "คุณสมบัติการใช้งาน" เพื่อใช้ตัวดำเนินการใหม่เหล่านี้หรือว่าพวกเขาเปิดใช้งานเริ่มต้นหรือไม่ ฉันยังคงใช้คุณสมบัติของ Perl 5.10
JJ

6
// โดยค่าเริ่มต้นนั้นไม่มีการปรับแต่งพิเศษใด ๆ นอกจากนี้คุณยังสามารถใส่กลับเข้าไปใน 5.8.x ด้วย dor-patch ... ดูไดเร็กทอรีผู้เขียน / id / H / HM / HMBRAND / บนกระจก CPAN ใด ๆ FreeBSD 6.x หรือมากกว่านั้นทำเพื่อคุณในแพ็คเกจของพวกเขา
dland

2
เมื่อ | | หรือ // รวมกับ do {} คุณสามารถแค็ปซูลการมอบหมายที่ซับซ้อนมากขึ้นเช่น $ x = $ a || ทำ {my $ z; 3 หรือ 4 บรรทัดของการสืบทอด $ z};
RET

39

ตัวดำเนินการ ++ และไม่รวม - ไม่เพียงทำงานกับตัวเลข แต่ยังรวมถึงสายอักขระด้วย

my $_ = "a"
print -$_

พิมพ์-a

print ++$_

พิมพ์b

$_ = 'z'
print ++$_

พิมพ์aa


3
ในการอ้างอิง perlvar: "ตัวดำเนินการลดค่าอัตโนมัติไม่ใช่เวทมนต์" ดังนั้นจึงใช้--ไม่ได้กับสตริง
moritz

"aa" ดูเหมือนจะไม่เป็นองค์ประกอบตามธรรมชาติ "z" ฉันคาดว่าค่า ascii ที่สูงที่สุดถัดไปซึ่งก็คือ "{"
อีเธอร์

4
อย่าถามโปรแกรมเมอร์ว่าเกิดอะไรขึ้นหลังจาก "z"; ถามมนุษย์ คุณลักษณะนี้ยอดเยี่ยมสำหรับการกำหนดหมายเลขรายการในรายการแบบยาว
Barry Brown

17
เมื่อใหม่กับ Perl ฉันใช้คุณลักษณะนี้กับพฤติกรรม z กับ aa แล้วแสดงให้เพื่อนร่วมงานที่หัวเราะและฉันและพูดว่า "ให้ฉันแสดงบางสิ่งให้คุณ" ฉันร้องไห้เล็กน้อย แต่ได้เรียนรู้บางสิ่ง
Copas

2
@Ether - หากคุณต้องการให้ใช้ตัวเลขและแปลงให้เป็น ASCII ord()อัตโนมัติ หรือเขียนชั้นเรียนขนาดเล็กและโอเวอร์โหลดโอเปอเรเตอร์เพื่อทำเพื่อคุณ
คริสลัทซ์

36

เนื่องจาก Perl มีชิ้นส่วน "ความลับ" เกือบทั้งหมดจากรายการอื่น ๆ ฉันจะบอกคุณสิ่งหนึ่งที่ Perl ไม่สามารถ:

สิ่งหนึ่งที่ Perl ไม่สามารถทำได้คือมี URL ที่ไม่เจาะจงในโค้ดของคุณเนื่องจาก//โอเปอเรเตอร์นั้นใช้สำหรับการแสดงผลปกติ

ในกรณีที่มันไม่ชัดเจนกับคุณในสิ่งที่คุณสมบัติ Perl เสนอนี่คือรายการที่เลือกของรายการอาจจะไม่ชัดเจนโดยสิ้นเชิง:

อุปกรณ์ของ Duff - ใน Perl

ความสะดวกในการพกพาและความเป็นมาตรฐาน - อาจมีคอมพิวเตอร์ที่ใช้ Perl มากกว่าคอมไพเลอร์ C

คลาสการจัดการไฟล์ / พา ธ - ไฟล์ :: Find ใช้งานได้กับระบบปฏิบัติการมากกว่า. Net

คำพูดสำหรับรายการ และสตริงที่คั่นด้วยช่องว่าง - Perl ช่วยให้คุณสามารถเลือกคำพูดที่เกือบจะสุ่มสำหรับรายการและตัวคั่นสตริงของคุณ

เนมสเปซที่มีนามแฝง - Perl มีการมอบหมายผ่าน glob:

*My::Namespace:: = \%Your::Namespace

initializers คงที่ - Perl สามารถเรียกใช้รหัสในเกือบทุกขั้นตอนของการรวบรวมและ instantiation วัตถุทุกจากBEGIN(รหัสแจง) ไปCHECK(หลังจากแยกรหัส) ไปimport(ที่นำเข้าโมดูล) ไปnew(วัตถุ instantiation) ไปDESTROY(ทำลายวัตถุ) ไปEND(โปรแกรมออก)

ฟังก์ชั่นเป็นพลเมืองชั้นหนึ่ง - เหมือนกับใน Perl

ขอบเขตบล็อกและการปิด - Perl มีทั้ง

การเรียกใช้เมธอดและตัวเข้าถึงโดยอ้อมผ่านตัวแปร - Perl ก็ทำเช่นนั้นเช่นกัน:

my $method = 'foo';
my $obj = My::Class->new();
$obj->$method( 'baz' ); # calls $obj->foo( 'baz' )

การกำหนดเมธอดผ่านโค้ด - Perl อนุญาตให้ทำได้เช่นกัน:

*foo = sub { print "Hello world" };

เอกสารออนไลน์ที่แพร่หลาย - เอกสารPerl นั้นออนไลน์และมีแนวโน้มที่ระบบของคุณด้วย

วิธีเวทย์มนตร์ที่ถูกเรียกเมื่อใดก็ตามที่คุณเรียกใช้ฟังก์ชั่น "nonexisting" - Perl ใช้ในฟังก์ชัน AUTOLOAD

การอ้างอิงสัญลักษณ์ - คุณควรหลีกเลี่ยงสิ่งเหล่านี้ พวกเขาจะกินลูกของคุณ แต่แน่นอน Perl ช่วยให้คุณสามารถให้ลูกของคุณกับปีศาจกระหายเลือด

การสลับค่าหนึ่งบรรทัด - Perl อนุญาตให้กำหนดรายการ

ความสามารถในการแทนที่ฟังก์ชั่นหลักด้วยฟังก์ชันของคุณเอง

use subs 'unlink'; 
sub unlink { print 'No.' }

หรือ

BEGIN{
    *CORE::GLOBAL::unlink = sub {print 'no'}
};

unlink($_) for @ARGV

ฉันเป็นแฟนของเอกสารของ Perl เมื่อเทียบกับภาษาอื่น ๆ แต่ฉันก็ยังคิดว่าสำหรับ Regexes และการอ้างอิงมันอาจมีเหตุผลมากมาย เช่นไพรเมอร์ที่ดีที่สุดสำหรับ regexes ไม่ใช่ Perlre แต่ Perlop
John Ferguson

9
"สิ่งหนึ่งที่ Perl ไม่สามารถทำได้คือมี URL ที่ไม่เจาะจงในโค้ดของคุณเนื่องจากตัวดำเนินการ // ใช้สำหรับนิพจน์ทั่วไป" - นี่เป็นเรื่องไร้สาระที่สุด

ขอบคุณสำหรับข้อมูลเชิงลึกของคุณฉันได้ดูวิธีที่จะมี http: // ... URL เปลือยในโค้ด Perl โดยไม่ต้องใช้ตัวกรองแหล่งที่มาและไม่พบวิธีคุณอาจแสดงว่าเป็นไปได้หรือไม่ // ใช้สำหรับนิพจน์ทั่วไปในเวอร์ชัน Perl สูงสุด 5.8.x ใน 5.10 จะมีการกำหนดใหม่สำหรับการกำหนดหรือการกำหนด
Corion

8
ทำไม / คุณต้องการ URL เปลือยในรหัสของคุณที่ไหน? ฉันไม่สามารถคิดถึงตัวอย่างได้
castaway

18
ไม่มีใครต้องการมันเป็นเพียง Java meme " foo.com " เป็นป้ายกำกับ http: และ "foo.com" ในความคิดเห็น บางคนพบว่าสิ่งนี้น่าสนใจเพราะ ... พวกเขาเป็นใบ้
jrockway

35

การปรับปรุงอัตโนมัติ AFAIK ไม่มีภาษาอื่น ๆ ที่มีมัน


ฉันไม่รู้ว่า Python และอื่น ๆ ไม่สนับสนุนสิ่งนี้
skiphoppy

@davidnicol: จริงเหรอ? คุณสามารถให้ลิงค์หรือไม่ การค้นหาด่วนของฉันใน google ไม่ได้ส่งคืนสิ่งใด สำหรับผู้ที่ไม่ทราบว่า ECMAscript เป็นชื่อที่ถูกต้องสำหรับ Javascript en.wikipedia.org/wiki/ECMAScript
JJ

1
และมีความเป็นโมดูลที่จะปิดการใช้งาน autovivication
Alexandr Ciornii

1
@Gregg Lind - เนื่องจาก Python สร้างตัวแปรโดยอัตโนมัติเมื่อใดก็ตามที่คุณกำหนดให้กับพวกเขาเป็นครั้งแรกการปรับปรุงอัตโนมัติจะสร้างปัญหามหึมาจากการพิมพ์ผิดครั้งเดียว
คริสลัทซ์

3
@tchrist - a = [[x * y สำหรับ y ใน xrange (1,11)] สำหรับ x ใน xrange (1,11)]
Omnifarious

31

มันง่ายที่จะพูดสตริงแปลก ๆ เกือบทุกชนิดใน Perl

my $url = q{http://my.url.com/any/arbitrary/path/in/the/url.html};

ในความเป็นจริงกลไกการอ้างอิงต่างๆใน Perl นั้นน่าสนใจทีเดียว กลไกการอ้างอิงแบบ regex เหมือน Perl อนุญาตให้คุณพูดอะไรก็ได้โดยระบุตัวคั่น คุณสามารถใช้อักขระพิเศษเกือบทุกตัวเช่น #, / หรือตัวอักษรเปิด / ปิดเช่น (), [] หรือ {} ตัวอย่าง:

my $var  = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);

กลไกการอ้างอิง:

q: คำพูดตามตัวอักษร; เฉพาะอักขระที่ต้องหลบหนีคือตัวละครสุดท้าย qq: คำพูดที่ตีความ; ประมวลผลตัวแปรและอักขระยกเว้น ยอดเยี่ยมสำหรับสตริงที่คุณต้องอ้างถึง:

my $var4 = qq{This "$mechanism" is broken.  Please inform "$user" at "$email" about it.};

qx: ทำงานเหมือน qq แต่จากนั้นเรียกใช้งานมันเป็นคำสั่งระบบไม่ใช่แบบโต้ตอบ ส่งคืนข้อความทั้งหมดที่สร้างจากมาตรฐาน (การเปลี่ยนเส้นทางหากได้รับการสนับสนุนในระบบปฏิบัติการก็จะออกมา) นอกจากนี้ยังมีเครื่องหมายคำพูดย้อนกลับ (อักขระ `)

my $output  = qx{type "$path"};      # get just the output
my $moreout = qx{type "$path" 2>&1}; # get stuff on stderr too

qr: การตีความเช่น qq แต่จากนั้นรวบรวมเป็นนิพจน์ปกติ ทำงานร่วมกับตัวเลือกต่าง ๆ ใน regex เช่นกัน ตอนนี้คุณสามารถส่ง regex ไปรอบ ๆ เป็นตัวแปร:

sub MyRegexCheck {
    my ($string, $regex) = @_;
    if ($string)
    {
       return ($string =~ $regex);
    }
    return; # returns 'null' or 'empty' in every context
}

my $regex = qr{http://[\w]\.com/([\w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);

qw: โอเปอเรเตอร์การเสนอราคาที่มีประโยชน์มาก เปลี่ยนชุดคำที่คั่นด้วยช่องว่างที่ยกมาเป็นรายการ เหมาะสำหรับการกรอกข้อมูลในการทดสอบหน่วย


   my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
   my @badwords = qw(WORD1 word2 word3 word4);
   my @numbers = qw(one two three four 5 six seven); # works with numbers too
   my @list = ('string with space', qw(eight nine), "a $var"); # works in other lists
   my $arrayref = [ qw(and it works in arrays too) ]; 

พวกเขายอดเยี่ยมที่จะใช้พวกเขาเมื่อใดก็ตามที่ทำให้สิ่งต่าง ๆ ชัดเจนขึ้น สำหรับ qx, qq และ q ฉันมักจะใช้ตัวดำเนินการ {} นิสัยที่พบบ่อยที่สุดของคนที่ใช้ qw มักจะเป็นตัวดำเนินการ () แต่บางครั้งคุณก็เห็น qw //


1
บางครั้งฉันใช้ qw "" เพื่อให้ปากกาเน้นข้อความเน้นไวยากรณ์จะเน้นอย่างถูกต้อง
Brad Gilbert

ได้ผลสำหรับฉันใน SlickEdit :)
Robert P

1
@fengshaun, บรรณาธิการฉันมักใช้ทำไฮไลต์เหล่านี้ได้อย่างถูกต้อง ฉันอ้างถึงส่วนหนึ่งของปากกาเน้นข้อความไวยากรณ์ใน StackOverflow
Brad Gilbert

@Brad Gilbert: Stack ล้นไม่สามารถ (ดี (ไม่ได้) แยก Perl มูลค่าหมอบ diddly ☹
tchrist

my $moreout = qx{type "$path" 2>&1};... ฉันไม่รู้ว่าคุณสามารถทำได้! [TM]
dland

27

ไม่ซ่อนจริงๆ แต่ส่วนมากทุกวันโปรแกรมเมอร์ Perl ไม่ทราบเกี่ยวกับCPAN โดยเฉพาะอย่างยิ่งนี้ใช้กับผู้ที่ไม่ได้โปรแกรมเมอร์เต็มเวลาหรือไม่เขียนโปรแกรมในแบบเต็มเวลา Perl


27

สามารถใช้คำสั่ง "for" ในลักษณะเดียวกับ "with" ใน Pascal:

for ($item)
{
    s/&‎nbsp;/ /g;
    s/<.*?>/ /g;
    $_ = join(" ", split(" ", $_));
}

คุณสามารถใช้ลำดับของการดำเนินการ s /// ฯลฯ กับตัวแปรเดียวกันโดยไม่ต้องทำซ้ำชื่อตัวแปร

หมายเหตุ: พื้นที่ที่ไม่ทำลายด้านบน (& nbsp;) ได้ซ่อน Unicode ไว้ในนั้นเพื่อหลีกเลี่ยง Markdown อย่าคัดลอกวาง :)


และ "map" ก็ทำแบบเดียวกันเช่นกัน ... map {.... } $ item; ข้อดีอย่างหนึ่งของการใช้ "for" over "map" ก็คือคุณสามารถใช้ถัดไปเพื่อแยกออก
draegtun

2
นอกจากนี้ยังมีรายการที่มีการจัดการที่ระบุไว้ก่อนที่รหัสทำการจัดการที่นำไปสู่การอ่านที่ดีขึ้น
Robert P

@ RobertP: ค่อนข้างถูกต้อง topicalizer มีประโยชน์ในวาทกรรม
tchrist

26

ผู้ดำเนินการคำพูดเป็นหนึ่งในสิ่งที่ฉันโปรดปราน เปรียบเทียบ:

my @list = ('abc', 'def', 'ghi', 'jkl');

และ

my @list = qw(abc def ghi jkl);

เสียงรบกวนน้อยลงง่ายขึ้นในสายตา อีกสิ่งที่ดีมากเกี่ยวกับ Perl ที่พลาดไปเมื่อเขียน SQL ก็คือเครื่องหมายจุลภาคต่อท้ายนั้นถูกกฎหมาย:

print 1, 2, 3, ;

ดูเหมือนแปลก แต่ไม่ใช่ถ้าคุณเยื้องรหัสด้วยวิธีอื่น:

print
    results_of_foo(),
    results_of_xyzzy(),
    results_of_quux(),
    ;

การเพิ่มอาร์กิวเมนต์เพิ่มเติมให้กับการเรียกใช้ฟังก์ชั่นไม่จำเป็นต้องให้คุณคลานไปรอบ ๆ ด้วยเครื่องหมายจุลภาคในบรรทัดก่อนหน้าหรือต่อท้ายบรรทัด การเปลี่ยนแปลงบรรทัดเดียวไม่มีผลกระทบกับบรรทัดโดยรอบ

สิ่งนี้ทำให้การทำงานกับฟังก์ชัน Variadic เป็นที่พอใจ นี่อาจเป็นหนึ่งในคุณสมบัติที่ไม่ได้รับการจัดอันดับมากที่สุดของ Perl


2
กรณีมุมที่น่าสนใจของไวยากรณ์ของ Perl คือสิ่งต่อไปนี้ถูกต้อง: สำหรับ $ _ qw (รายการของสิ่งต่าง ๆ ) {... }
ephemient

1
คุณสามารถใช้ไวยากรณ์ glob แบบผิด ๆ เพื่ออ้างอิงคำศัพท์ได้ตราบใดที่คุณไม่ได้ใช้อักขระพิเศษเช่น *? ดังนั้นคุณสามารถเขียนfor (<a list of stuff>) { ... }
อริ

1
@ephemient: เกือบ ใช้งานได้กับคำศัพท์: สำหรับ $ x qw (abc) {... } ตัวอย่างเช่น: สำหรับ $ _ qw (abc) {print} # พิมพ์ไม่มีอะไรเลย
dland

เหตุใดจึงเพิ่มคำศัพท์พิเศษนี้เมื่อคุณสามารถเพลิดเพลินกับค่าเริ่มต้นที่เป็นที่ชื่นชอบของ Perl ได้ สำหรับ (qw / abcd /) {พิมพ์; }
fengshaun

2
@ephemient, @fengshaun, @moritz, @dland: นั่นเป็น“คงที่” ในblead ; ดูกระทู้ p5p นี้
tchrist

26

ความสามารถในการแยกวิเคราะห์ข้อมูลวางโดยตรงในบล็อกข้อมูล ไม่จำเป็นต้องบันทึกลงในไฟล์ทดสอบที่จะเปิดในโปรแกรมหรือที่คล้ายกัน ตัวอย่างเช่น:

my @lines = <DATA>;
for (@lines) {
    print if /bad/;
}

__DATA__
some good data
some bad data
more good data 
more good data 

และมีประโยชน์มากในการทดสอบเล็กน้อย!
fengshaun

@peter mortensen คุณจะมีหลายบล็อกได้อย่างไร และคุณจะจบบล็อกได้อย่างไร
คางคก

@Toad: เป็นคำตอบของ allan (ดูรายการการแก้ไข) เป็นการดีกว่าที่จะจัดการกับผู้ใช้รายนั้น หรือในขณะที่ผู้ใช้นั้นออกจาก Stack Overflow อาจจะไม่มีใครพูดถึงเรื่องนั้นโดยเฉพาะ (เพื่อให้ผู้เชี่ยวชาญ Perl จริงสามารถยืดออกได้ในภายหลัง)
Peter Mortensen

3
@Hai: ไม่ไม่น่าเกลียด - ในความเป็นจริงมันตรงกันข้ามกับความน่าเกลียด: มันสะอาด svelte เรียบง่ายและสวยงาม; เป็นคำที่วิเศษและภาษาที่ไม่มี PITA @peter mortensen, @toad: หนึ่งคำตอบสำหรับวิธีการมีหลายบล็อคข้อมูลในโปรแกรมเดียวกันคือการใช้โมดูลInline :: Filesนอก CPAN
tchrist

Inline ::มีการใช้งานไฟล์โดยใช้ตัวกรองแหล่งที่มา นอกจากนี้ยังมีData :: Sectionที่ให้หลาย ๆ บล็อคอินไลน์และไม่ใช้ตัวกรองแหล่งที่มา
Prakash K

24

ใหม่การปฏิบัติการบล็อก

ฉันว่าความสามารถในการขยายภาษาการสร้างการดำเนินการบล็อกหลอกเป็นหนึ่ง

  1. คุณประกาศต้นแบบสำหรับย่อยที่ระบุว่าใช้การอ้างอิงรหัสก่อน:

    sub do_stuff_with_a_hash (&\%) {
        my ( $block_of_code, $hash_ref ) = @_;
        while ( my ( $k, $v ) = each %$hash_ref ) { 
            $block_of_code->( $k, $v );
        }
    }
  2. จากนั้นคุณสามารถเรียกมันในร่างกายเช่นนั้น

    use Data::Dumper;
    
    do_stuff_with_a_hash {
        local $Data::Dumper::Terse = 1;
        my ( $k, $v ) = @_;
        say qq(Hey, the key   is "$k"!);
        say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
    
    } %stuff_for
    ;

( Data::Dumper::Dumperเป็นอัญมณีกึ่งซ่อนเร้นอีกตัว) สังเกตว่าคุณไม่จำเป็นต้องใช้subคำสำคัญหน้าบล็อกหรือเครื่องหมายจุลภาคก่อนแฮช มันจบลงด้วยการมองเช่น:map { } @list

ตัวกรองแหล่งที่มา

นอกจากนี้ยังมีตัวกรองแหล่งที่มา ที่ไหน Perl จะส่งรหัสให้คุณเพื่อให้คุณสามารถจัดการกับมัน ทั้งการดำเนินการนี้และการดำเนินการบล็อกนั้นเป็นสิ่งที่ไม่ควรลองทำที่บ้าน

ฉันได้ทำสิ่งที่เรียบร้อยด้วยตัวกรองซอร์สเช่นการสร้างภาษาที่ง่ายมากในการตรวจสอบเวลาทำให้ Perl one-liners สั้น ๆ สำหรับการตัดสินใจ:

perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';

Lib::TL จะสแกนทั้ง "ตัวแปร" และค่าคงที่สร้างและแทนที่ตามต้องการ

ตัวกรองแหล่งที่มาอีกครั้งอาจยุ่ง แต่มีประสิทธิภาพ แต่พวกเขาสามารถแก้ไขข้อผิดพลาดบางอย่างที่ร้ายแรง - และแม้แต่คำเตือนก็สามารถพิมพ์ด้วยหมายเลขบรรทัดผิด ฉันหยุดใช้สวิตช์ของเดเมียนเพราะดีบักเกอร์จะสูญเสียความสามารถในการบอกฉันว่าฉันอยู่ที่ไหน แต่ฉันพบว่าคุณสามารถลดความเสียหายโดยการแก้ไขส่วนเล็ก ๆ ของรหัสทำให้พวกเขาอยู่ในบรรทัดเดียวกัน

สัญญาณตะขอ

มันมักจะทำพอ แต่ก็ไม่ชัดเจน นี่คือตัวจัดการความตายที่ลูกหมูอยู่ข้างหลังตัวเก่า

my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}       
    = sub { say q(Hey! I'm DYIN' over here!); goto &$old_die_handler; }
    ;

นั่นหมายความว่าเมื่อใดก็ตามที่บางโมดูลอื่น ๆ ในรหัสที่ต้องการที่จะตายพวกเขาต้องมาให้คุณ (ยกเว้นกรณีที่คนอื่นไม่ได้เขียนทับทำลายบน$SIG{__DIE__}) และคุณจะได้รับแจ้งว่ามีบางสิ่งที่ผิดพลาด

แน่นอนว่ามีสิ่งต่างๆมากพอที่คุณจะสามารถใช้END { }บล็อกได้หากสิ่งที่คุณต้องการทำคือทำความสะอาด

overload::constant

คุณสามารถตรวจสอบตัวอักษรบางประเภทในแพ็คเกจที่รวมถึงโมดูลของคุณ ตัวอย่างเช่นหากคุณใช้สิ่งนี้ในimportส่วนย่อยของคุณ:

overload::constant 
    integer => sub { 
        my $lit = shift;
        return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit 
    };

มันจะหมายความว่าทุกจำนวนเต็มมากกว่า 2 พันล้านในแพ็คเกจการโทรจะถูกเปลี่ยนเป็นMath::BigIntวัตถุ (ดูเกินพิกัด :: ค่าคงที่ )

ตัวอักษรจำนวนเต็มของกลุ่ม

ในขณะที่เราอยู่ที่นั้น Perl ช่วยให้คุณสามารถแบ่งตัวเลขขนาดใหญ่ออกเป็นกลุ่มตัวเลขสามหลักและยังคงได้จำนวนเต็มแยกออกจากมัน หมายเหตุ2_000_000_000ด้านบนสำหรับ 2 พันล้าน


5
เมื่อใช้ตัวจัดการ $ SIG { DIE } ขอแนะนำอย่างยิ่งให้คุณตรวจสอบ $ ^ S เพื่อดูว่าโปรแกรมของคุณกำลังจะตายจริงหรือเพียงแค่โยนข้อยกเว้นที่จะถูกจับได้ โดยปกติแล้วคุณไม่ต้องการยุ่งกับสิ่งหลัง
pjf

บล็อกใหม่นั้นให้คำแนะนำอย่างมาก! ฉันคิดว่ามันเป็นความหมายของภาษา! ขอบคุณมาก.
ZeroCool

การใช้ตัวกรองแหล่งข้อมูลอย่างเป็นทางการคือ NiceSlice ของ pdl ( pdl.perl.org/?docs=NiceSlice&title=PDL::NiceSlice ) ดังนั้นจึงไม่จำเป็นต้องใช้->sliceเมธอดทุกครั้งที่จำเป็น
Joel Berger

24

ไบนารี "x" เป็นตัวดำเนินการซ้ำซ้อน :

print '-' x 80;     # print row of dashes

นอกจากนี้ยังทำงานกับรายการ:

print for (1, 4, 9) x 3; # print 149149149

นี่คือเหตุผลหนึ่งว่าทำไม Perl ได้รับความนิยมอย่างมากจากแฮกเกอร์ Perl - e 'พิมพ์ 0x000 x 25';
JJ

4
สิ่งที่ฉันโปรดปรานในการใช้นี้คือการสร้างตัวยึดตำแหน่งสำหรับส่วนสุดท้ายของคำสั่ง SQL INSERT: @p = ('?') x $ n; $ p = เข้าร่วม (",", @p); $ sql = "ใส่ ... ค่า ($ p)";
skiphoppy

24

การตรวจสอบมัวหมอง เมื่อเปิดใช้งานการตรวจสอบมลทิน Perl จะตาย (หรือเตือนด้วย-t) หากคุณพยายามส่งข้อมูลที่ปนเปื้อน (การพูดอย่างคร่าวๆข้อมูลจากนอกโปรแกรม) ไปยังฟังก์ชันที่ไม่ปลอดภัย (การเปิดไฟล์เรียกใช้คำสั่งภายนอกเป็นต้น) มันจะมีประโยชน์มากเมื่อเขียนสคริปต์ setuid หรือ CGIs หรือสิ่งใดก็ตามที่สคริปต์มีสิทธิ์มากกว่าผู้ที่ป้อนข้อมูล

Magic goto goto &subโทรหางที่ดีที่สุด

ตัวดีบัก

use strictuse warningsและ สิ่งเหล่านี้สามารถช่วยคุณประหยัดจากการพิมพ์ผิด ๆ


1
เหตุใดภาษาอื่นจึงไม่มีคุณสมบัตินี้ คุณลักษณะนี้ใช้ทำให้สคริปต์เว็บ perl มีความปลอดภัยมากขึ้น
Matthew Lock

22

ขึ้นอยู่กับวิธีการ"-n"และ"-p"สวิตช์ถูกนำไปใช้ใน Perl 5 คุณสามารถเขียนโปรแกรมที่ดูเหมือนไม่ถูกต้องซึ่งรวมถึง}{:

ls |perl -lne 'print $_; }{ print "$. Files"'

ซึ่งถูกแปลงภายในเป็นรหัสนี้:

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}

@ มาร์ตินเคลย์ตัน: ทำไมถึงเรียกมันว่า?
tchrist

@ คริสเตียน - เพราะมันดูเหมือนว่าคนสองคนถูจมูก ในโปรไฟล์ถ้าคุณเห็นสิ่งที่ฉันหมายถึง
martin Clayton

18

เริ่มต้นให้ง่ายกับผู้ประกอบการยานอวกาศ

$a = 5 <=> 7;  # $a is set to -1
$a = 7 <=> 5;  # $a is set to 1
$a = 6 <=> 6;  # $a is set to 0

1
@Leon: C / C ++ ไม่ได้ส่งคืนค่า 3 ค่าสำหรับตัวเลข หากหน่วยความจำทำหน้าที่ฟังก์ชั่น String comapre เป็นเพียงค่า 3 คืนที่ฉันรู้ในภาษา STL ทั้งหมด AFAIK Python ไม่มีการเปรียบเทียบตัวเลขที่ส่งคืน 3 Java ไม่มีตัวเลขเฉพาะ 3 ผลตอบแทนเปรียบเทียบอย่างใดอย่างหนึ่ง
JJ

7
เป็นมูลค่าการกล่าวถึงสิ่งที่มีประโยชน์มากเกี่ยวกับตัวดำเนินการเปรียบเทียบ -1/0/1 เนื่องจากทุกคนอาจไม่ทราบ: คุณสามารถโยงพวกเขาเข้าด้วยกันกับผู้ดำเนินการเพื่อทำหลัก / รอง / ฯลฯ ทุกประเภท ดังนั้น($a->lname cmp $b->lname) || ($a->fname cmp $b->fname)เรียงลำดับคนโดยชื่อสุดท้ายของพวกเขา แต่ถ้าคนสองคนที่มีนามสกุลเดียวกันแล้วพวกเขาก็จะได้รับการสั่งซื้อโดยใช้ชื่อแรกของพวกเขา
ฮอบส์

@JJ Python มีการเปรียบเทียบ 3 ค่า: cmp () >>> print (cmp (5,7), cmp (6,6), cmp (7,5)) (-1, 0, 1)
bukzor

18

นี่คือคำตอบเมตา แต่ที่เก็บถาวรเคล็ดลับ Perl มีเคล็ดลับที่น่าสนใจทุกประเภทที่สามารถทำได้ด้วย Perl การเก็บถาวรของเคล็ดลับก่อนหน้านี้เป็นแบบออนไลน์สำหรับการเรียกดูและสามารถสมัครผ่านทางรายชื่อผู้รับจดหมายหรือฟีด atom

บางเคล็ดลับที่ชื่นชอบรวมถึงการสร้าง executables กับ PAR , ใช้ autodie จะโยนข้อยกเว้นโดยอัตโนมัติและการใช้งานของสวิทช์และสมาร์ทการแข่งขันสร้างใน Perl 5.10

การเปิดเผยข้อมูล:ฉันเป็นหนึ่งในผู้แต่งและผู้ดูแลรักษาเคล็ดลับ Perl ดังนั้นฉันจึงคิดว่าสูงมาก ;)


2
อาจเป็นหนึ่งในภาษาที่ดีที่สุดที่มีเอกสารและตั้งรูปแบบสำหรับเครื่องมือในการค้นหาเอกสาร รายการในคำถามนี้อาจไม่จำเป็นสำหรับภาษาอื่น
Axeman

1
autodie ดูดีมาก
j_random_hacker

18

map - ไม่เพียงเพราะมันทำให้โค้ดของเราแสดงออกมากขึ้น แต่เพราะมันทำให้ฉันรู้สึกอยากอ่านเพิ่มเติมเล็กน้อยเกี่ยวกับ "การเขียนโปรแกรมเชิงปฏิบัติการ"


15

ประโยคต่อไปบนลูป มันจะถูกดำเนินการที่ด้านล่างของทุกวงแม้กระทั่งผู้ที่อยู่ถัดไป

while( <> ){
  print "top of loop\n";
  chomp;

  next if /next/i;
  last if /last/i;

  print "bottom of loop\n";
}continue{
  print "continue\n";
}

15

คะแนนของฉันจะเป็นของกลุ่ม (? {}) และ (?? {}) ในการแสดงออกปกติของ Perl ตัวแรกรันโค้ด Perl โดยไม่สนใจค่าส่งคืนส่วนที่สองเรียกใช้โค้ดโดยใช้ค่าส่งคืนเป็นนิพจน์ทั่วไป


perl คิดค้นส่วนขยาย regexp มากมายที่โปรแกรมอื่น ๆ ตอนนี้มักใช้ pcre (perl Compatible regex) แทนภาษา regex ดั้งเดิม
วินาที

อ่านประกาศเล็กน้อยที่นี่perldoc.perl.org/… :-D
JJ

Perl จริงๆมี (เท่าที่ฉันรู้) นำไปสู่แพ็คเมื่อมันมาถึง regexps
Brad Gilbert

เท่าที่ฉันทราบนี้ยังคงอยู่ในช่วงทดลองและอาจไม่ทำงานในลักษณะเดียวกันในอนาคตของ Perls ไม่ได้บอกว่ามันไม่ได้มีประโยชน์ แต่เล็กน้อยปลอดภัยและเช่นเดียวกับรุ่น useable สามารถพบได้ใน s /// ของคำสั่ง / E ธง: s/(pattern)/reverse($1);/ge;# patternsหลีทั้งหมด
Chris Lutz

@Chris Lutz, @Leon Timmerman: โปรดทราบว่าตอนนี้ทั้งสองโครงสร้างได้รับการสร้างใหม่แล้ว นอกจากนี้โปรดทราบว่าไม่จำเป็นต้องใช้รูปแบบที่สองเพื่อสร้างรูปแบบแบบเรียกซ้ำอีกต่อไปตอนนี้เราสามารถเรียกคืนกลุ่มการดักจับได้แล้ว @Brad Gilbert: ถูกต้องแม้ว่า PCRE จะทำงานได้ดีในการติดตามเรา อีกด้านหนึ่งของความเป็นเลิศของ regex ที่ Perl ไม่มีการทักท้วงอย่างสมบูรณ์คือการเข้าถึงคุณสมบัติ Unicode ดูการกระจาย unitrio ของฉันuninames, unicharsและโดยเฉพาะอย่างยิ่งunipropsที่จะเห็นเพียงส่วนหนึ่งของสิ่งที่ผมหมายถึง
tchrist

13
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

ผู้ยึด \ G มันร้อน


3
... และมันแสดงตำแหน่งของการสิ้นสุดของการแข่งขันก่อนหน้า
Dave Sherohman

1
แต่คุณต้องเรียก regex ของคุณในบริบทสเกลาร์
davidnicol

@davidnicol: โค้ดด้านบนใช้ได้ คุณสามารถอธิบายสิ่งที่คุณหมายถึง?
JJ

13

m//ผู้ประกอบการที่มีบางกรณีพิเศษปิดบัง:

  • ถ้าคุณใช้ ?resetเป็นตัวคั่นเพียงครั้งเดียวตรงจนกว่าคุณจะเรียก
  • ถ้าคุณใช้ 'เป็นตัวคั่นรูปแบบจะไม่ถูกสอดแทรก
  • หากรูปแบบว่างเปล่ามันจะใช้รูปแบบจากการแข่งขันที่ประสบความสำเร็จครั้งล่าสุด

2
เหล่านี้เป็นเหมือน gotchas ที่ซ่อนอยู่มากกว่าคุณสมบัติที่ซ่อนอยู่! ฉันไม่รู้จักใครที่ชอบพวกเขา บางครั้งเธรดบน p5p ได้กล่าวถึงประโยชน์ของการใช้ธงสมมุติ m / $ foo / r โดยที่ / r จะไม่มีการแก้ไข (ตัวอักษรไม่สำคัญ) เนื่องจากไม่มีใครสามารถจำสิ่งเดียวได้
dland

2
@dland: เห็นด้วย; ฉันจะเรียกคุณสมบัติผิดพลาดที่ซ่อนอยู่เหล่านี้และจะไม่ใช้ในรหัสการผลิต
Michael Carman

7
ฉันไม่สามารถจินตนาการได้ว่าโปรแกรมเมอร์ Perl ที่จำไม่ได้ (หรือแม้แต่เดา) ว่าเครื่องหมายคำพูดเดียวไม่สามารถแก้ไขได้ การใช้งานกับความหมายนี้เกือบจะเป็นสากลในภาษาที่ฉันคาดหวังว่ามันจะเป็นเช่นนั้น ...
sundar - Reinstate Monica

และถ้ารูปแบบว่างเปล่าและการจับคู่ที่ประสบความสำเร็จครั้งล่าสุดถูกคอมไพล์ด้วยโมดิฟายเออร์ / o จากนั้นจะติดอยู่ในรูปแบบนั้น
davidnicol

1
ฉันคิดว่าพฤติกรรมรูปแบบที่ว่างเปล่าเลิกใช้แล้ว หลักมาจากรูปแบบเช่น m / $ foo / กลายเป็นข้อผิดพลาดที่น่ารังเกียจเมื่อ $ foo ว่างเปล่า
แมทธิว S

12

ตัวดำเนินการ null filehandle diamond <>มีตำแหน่งในการสร้างเครื่องมือบรรทัดคำสั่ง มันทำหน้าที่เหมือน<FH>การอ่านจากที่จับยกเว้นว่ามันจะเลือกสิ่งที่พบได้อย่างน่าอัศจรรย์: ชื่อไฟล์บรรทัดคำสั่งหรือ STDIN นำมาจาก perlop:

while (<>) {
...         # code for each line
}

4
นอกจากนี้ยังตามความหมายของ UNIX ในการใช้ "-" เพื่อหมายถึง "read จาก stdin ดังนั้นคุณสามารถทำได้perl myscript.pl file1.txt - file2.txtและ Perl จะประมวลผลไฟล์แรกจากนั้น stdin จากนั้นไฟล์ที่สอง
Ryan C. Thompson

คุณสามารถผู้ประกอบการที่วัตถุของคุณเอง ( ) ในการทำงานเช่น iterator อย่างไรก็ตามมันไม่ทำงานอย่างที่คุณคาดหวังในบริบทรายการ overload<><$var>
dolmen

11

รหัสบล็อกพิเศษเช่นBEGIN, และCHECK ENDพวกเขามาจาก Awk แต่ทำงานแตกต่างกันใน Perl เพราะมันไม่ได้เป็นฐานข้อมูล

BEGINบล็อกสามารถนำมาใช้เพื่อระบุรหัสบางอย่างสำหรับขั้นตอนการแยก; perl -cมันจะถูกดำเนินการเมื่อคุณทำไวยากรณ์และตัวแปรการตรวจสอบ ตัวอย่างเช่นการโหลดตัวแปรการกำหนดค่า:

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ($@) {
        require 'config.default.pl';
    }
}

11
rename("$_.part", $_) for "data.txt";

เปลี่ยนชื่อ data.txt.part เป็น data.txt โดยไม่ต้องทำซ้ำตัวเอง


10

สิ่งที่คลุมเครือเล็กน้อยคือ "โอเปอเรเตอร์" tilde-tilde ซึ่งบังคับให้บริบทสเกลาร์

print ~~ localtime;

เป็นเช่นเดียวกับ

print scalar localtime;

และแตกต่างจาก

print localtime;

5
นี่เป็นสิ่งที่คลุมเครือเป็นพิเศษเพราะ perl5.10.0 ยังแนะนำ "ผู้ดำเนินการจับคู่อัจฉริยะ" ~~ซึ่งสามารถทำการจับคู่ regex สามารถดูว่ามีรายการอยู่ในอาร์เรย์หรือไม่
moritz

นั่นไม่ใช่สิ่งที่คลุมเครือนั่นคือสิ่งที่ทำให้สับสน (และมีประโยชน์สำหรับกอล์ฟและ JAPH)
Michael Carman

ไม่ถูกต้อง! ~~ ไม่ปลอดภัยสำหรับการอ้างอิง! มันทำให้พวกเขาสตริง
Leon Timmermans

ก็ใช่ การทำให้เป็นสตริงคือสิ่งที่เกิดขึ้นกับการอ้างอิงเมื่อถูกบังคับให้เข้ากับบริบทสเกลาร์ สิ่งนั้นทำให้ "~~ บังคับบริบทสเกลาร์" ไม่ถูกต้องได้อย่างไร
Dave Sherohman

3
@Nomad Dervish: บริบทสเกลาร์ / = การทำให้เป็นสตริง เช่น "$ n = @a" เป็นบริบทสเกลาร์ "$ s = qq '@ a'" คือการทำให้เป็นสตริง เกี่ยวกับการอ้างอิง "$ ref1 = $ ref2" เป็นบริบทสเกลาร์ แต่ไม่ได้ทำให้เป็นสตริง
Michael Carman


9

"โหมดการหมดหวัง" ของการควบคุมลูปของ Perl ซึ่งทำให้พวกเขาค้นหาสแต็กเพื่อค้นหาเลเบลที่ตรงกันช่วยให้พฤติกรรมที่อยากรู้อยากเห็นซึ่ง Test :: More ใช้ประโยชน์จากดีกว่าหรือแย่กว่านั้น

SKIP: {
    skip() if $something;

    print "Never printed";
}

sub skip {
    no warnings "exiting";
    last SKIP;
}

มีไฟล์. pmc ที่รู้จักกันน้อย "use Foo" จะค้นหา Foo.pmc ใน @INC ก่อน Foo.pm สิ่งนี้มีจุดประสงค์เพื่อให้สามารถโหลด bytecode ที่คอมไพล์ได้ก่อน แต่Module :: Compileใช้ประโยชน์จากสิ่งนี้เพื่อแคชโมดูลที่ถูกกรองซอร์สสำหรับเวลาโหลดเร็วขึ้นและการดีบักง่ายขึ้น

ความสามารถในการเปลี่ยนคำเตือนเป็นข้อผิดพลาด

local $SIG{__WARN__} = sub { die @_ };
$num = "two";
$sum = 1 + $num;
print "Never reached";

นั่นคือสิ่งที่ฉันสามารถนึกได้จากส่วนบนของหัวที่ไม่ได้กล่าวถึง


9

ผู้ประกอบการแพะ*:

$_ = "foo bar";
my $count =()= /[aeiou]/g; #3

หรือ

sub foo {
    return @_;
}

$count =()= foo(qw/a b c d/); #4

มันใช้งานได้เนื่องจากการกำหนดรายการในบริบทสเกลาร์ทำให้จำนวนองค์ประกอบในรายการที่ได้รับมอบหมาย

* หมายเหตุไม่ใช่ผู้ประกอบการจริงๆ


นั่นคือ "โอเปอเรเตอร์" ที่สวยงามที่สุด (ดีน้อย)
Chris Lutz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.