מ־Python ל־Perl#
אתם מכירים את Python. אתם כותבים list comprehensions בשנתכם, אתם פונים אל dict בלי לחשוב, ו־for x in xs: הוא זיכרון שרירי. המדריך הזה ממפה כל אחד מההרגלים האלה אל Perl, כך שתוכלו להיות יצרניים ב־pperl תוך אחר צהריים אחד במקום ללמוד מחדש תכנות מאפס.
שני זעזועים נוחתים בחמש הדקות הראשונות, אז הכירו אותם עכשיו:
Perl משתמשת בסוגריים מסולסלים ובנקודה־פסיק, לא בהזחה. אין רווח לבן משמעותי. בלוק הוא
{ ... }; משפט מסתיים ב־;. הזיחו לשם השפיות שלכם, אבל המנתח מתעלם מכך.משתנים עוטים sigils. סקלר הוא
$x, מערך הוא@x, hash הוא%x. ה־sigil הוא חלק מהאופן שבו אתם קוראים את המשתנה, לא רק שמו. זהו ההבדל השטחי הגדול ביותר מ־Python, וחלק ראשון אינו עוסק בשום דבר אחר.
Every example here runs on pperl, a Rust reimplementation of Perl 5.42. Each Perl snippet was executed on pperl; the # ... comments show its real output. Start your scripts with:
use v5.42;
השורה האחת הזו מפעילה את strict (ללא משתנים גלובליים בשוגג), את warnings, את הפונקציה המובנית say (זהו print עם תו שורה חדשה בסופו, כמו print של Python), חתימות של תת־שגרות, ואת מערכת התכונות המודרנית המשמשת לאורך כל המדריך הזה.
כיצד לקרוא את זה#
משתנים ו־sigils - המעבר בין
$/@/%.מחרוזות - שִחלוף ושרשור.
מספרים - טיפוס שטחי אחד, חלוקה צפה.
מערכים ורשימות - ה־
listשלכם, בתוספתmap/grep.Hashים - ה־
dictשלכם.הקשר - המושג שאין ל־Python מילה עבורו. קראו את זה.
אמיתות - מה נחשב לשקר, עם הפתעות.
בקרת זרימה -
if, לולאות, הצורות הסופיתיות.תת־שגרות -
defהופך ל־sub.הפניות - נתונים מקוננים ו־closures.
ביטויים רגולריים - regex כתחביר, לא כספרייה.
קלט/פלט של קבצים וזרמים -
open, קריאות שורה, slurp.מודולים וחבילות -
importהופך ל־use.אובייקטים - תחביר ה־
classהמודרני.טיפול בשגיאות -
try/exceptהופך ל־evalאו ל־try/catch.ניבים - שורות־היחיד היומיומיות.
מלכודות בהגעה מ־Python - סרקו לפני שאתם כותבים.
משתנים ו־sigils#
ב־Python שם פשוט נותן שם לערך. ב־Perl הsigil מספר לכם את הצורה: $ עבור ערך יחיד, @ עבור רשימה מסודרת, % עבור מיפוי מפתח/ערך. my מצהיר על משתנה בעל היקף לקסיקלי, המקבילה ב־Perl לקישור מקומי רגיל.
name = "Ada"
langs = ["Python", "Perl"]
ages = {"Ada": 36, "Linus": 56}
use v5.42;
my $name = "Ada";
my @langs = ("Python", "Perl");
my %ages = (Ada => 36, Linus => 56);
say $name; # Ada
say $langs[0]; # Python
say $ages{Ada}; # 36
המלכודת: כשאתם נשלחים לתוך צבר כדי לקבל איבר אחד, ה־sigil עוקב אחר הערך שאתם מקבלים בחזרה, לא אחר המכל. איבר יחיד של @langs הוא סקלר, ולכן הוא $langs[0], לא @langs[0]; ערך אחד מתוך %ages הוא $ages{Ada}. צורת ה־@/% היא האוסף כולו; צורת ה־$ היא חלק אחד ממנו.
מחרוזות#
מירכאות כפולות משחלפות משתנים, מירכאות בודדות אינן עושות זאת. אין f-string כי המחרוזת שבברירת המחדל היא f-string. שרשור הוא ., לא + (השמור למספרים).
name = "Ada"
greeting = f"Hello, {name}"
shout = "AB" * 3
use v5.42;
my $name = "Ada";
my $greeting = "Hello, $name"; # Hello, Ada
my $literal = 'Hello, $name'; # Hello, $name (no interpolation)
my $joined = "AB" . "CD"; # ABCD
my $shout = "AB" x 3; # ABABAB
המלכודת: שכפול מחרוזת הוא x, לא *, ואופרטור החיבור הוא ., לא +. בלבול ביניהם הוא טעות הכתיב הנפוצה ביותר ביום הראשון של מפתח Python. גם איברי מערך וערכי hash משוחלפים בתוך מירכאות כפולות: "First: $langs[0]" עובד כפי שנכתב.
מספרים#
ל־Perl יש טיפוס מספרי אחד ברמת השטח; אינכם מצהירים על int מול float. חלוקה תמיד מייצרת float, בדיוק כמו ב־Python 3.
print(7 / 2) # 3.5
print(7 // 2) # 3
print(2 ** 10) # 1024
print(10 % 3) # 1
use v5.42;
say 7 / 2; # 3.5
say int(7 / 2); # 3
say 2 ** 10; # 1024
say 10 % 3; # 1
המלכודת: אופרטורי ההשוואה והשוויון מגיעים בשתי משפחות, ואתם בוחרים לפי טיפוס האופרנדים, לא לפי זה של המשתנים. מספרים משתמשים ב־==, !=, <, >, <=>; מחרוזות משתמשות ב־eq, ne, lt, gt, cmp. "10" == "10.0" הוא אמת (מספרי), אבל "10" eq "10.0" הוא שקר (מחרוזת). שימוש ב־== על מחרוזות, או ב־eq על מספרים, הוא באג תכוף ושקט.
מערכים ורשימות#
מערך של Perl הוא ה־list של Python שלכם. הפעלים משונים בשמם אבל הפעולות זהות, ואינדקסים שליליים עובדים כפי שאתם מצפים.
nums = [1, 2, 3, 4, 5]
nums.append(6)
last = nums.pop()
print(len(nums)) # 5
print(nums[1:3]) # [2, 3]
use v5.42;
my @nums = (1, 2, 3, 4, 5);
push @nums, 6;
my $last = pop @nums; # 6
say scalar @nums; # 5
say "@nums[1,2]"; # 2 3 (a slice)
Comprehensions הופכים ל־map ו־grep. map ממיר ([f(x) for x in xs] של Python); grep מסנן ([x for x in xs if p(x)] של Python). $_ הוא האיבר הנוכחי, משתנה הלולאה המובלע של Perl.
squares = [x * x for x in nums]
evens = [x for x in nums if x % 2 == 0]
desc = sorted(nums, reverse=True)
use v5.42;
my @nums = (1, 2, 3, 4, 5);
my @squares = map { $_ * $_ } @nums; # 1 4 9 16 25
my @evens = grep { $_ % 2 == 0 } @nums; # 2 4
my @desc = sort { $b <=> $a } @nums; # 5 4 3 2 1
המלכודת: sort משווה כמחרוזות כברירת מחדל, כך ש־sort (10, 9, 100) נותן 10 100 9. עבור מספרים עליכם להעביר משווה: sort { $a <=> $b } @nums. $a ו־$b הם שני האיברים המושווים, ו־<=> הוא אופרטור התלת־כיווני המספרי (cmp הוא אחיו של המחרוזות).
האשים#
hash של Perl הוא ה־dict של Python שלכם. מוצהר עם %, ניגשים אליו ערך אחד בכל פעם עם $h{key}.
h = {"apple": 3, "pear": 5, "plum": 2}
print(h["apple"]) # 3
print(sorted(h.keys())) # ['apple', 'pear', 'plum']
print("pear" in h) # True
del h["plum"]
for k in sorted(h):
print(k, "=>", h[k])
use v5.42;
my %h = (apple => 3, pear => 5, plum => 2);
say $h{apple}; # 3
say join ",", sort keys %h; # apple,pear,plum
say exists $h{pear} ? "yes" : "no"; # yes
delete $h{plum};
for my $k (sort keys %h) {
say "$k => $h{$k}";
}
המלכודת: בדיקת חברוּת היא exists $h{key}, לא ה־in של Python, והפסיק השמן => הוא מפריד המפתח/ערך הניבי. => גם מצטט אוטומטית את ה־bareword שמשמאלו, כך ש־apple => 3 אינו זקוק למירכאות סביב apple. ל־hash אין סדר; עברו sort keys %h כשאתם רוצים סדר יציב.
הקשר#
זהו הפרק שכדאי לקרוא פעמיים. ל־Python אין מקבילה, וכמעט כל סיפור ”Perl מוזרה“ מתחקה בחזרה אליו.
כל ביטוי ב־Perl רץ או בהקשר רשימה או בהקשר סקלר, הנקבע לפי המקום שבו הוא מופיע, לא לפי מה שהוא. אותו מערך עצמו מתנהג אחרת בכל אחד מהם. השמה של מערך אל סקלר נותנת את אורכו; השמה שלו אל רשימה (קבוצת משתנים בסוגריים) מעתיקה איברים.
use v5.42;
my @list = (10, 20, 30);
my $count = @list; # scalar context -> 3 (the length)
say $count; # 3
my ($first) = @list; # list context -> first element copied
say $first; # 10
my ($a, $b) = @list; # 10 and 20
say "$a $b"; # 10 20
הסוגריים שמשמאל הם כל ההבדל. my $x = @list שואל ”כמה?“ ומקבל 3. my ($x) = @list שואל ”תן לי את האיברים“ ומקבל 10. מפתח Python קורא את שניהם כ“השם את הרשימה“, וזו בדיוק המלכודת.
תת־שגרה יכולה לשאול באיזה הקשר היא נקראה, באמצעות wantarray, ולהחזיר דברים שונים בהתאם:
use v5.42;
sub items {
return wantarray ? (1, 2, 3) : "three items";
}
my @got = items(); # list context
my $msg = items(); # scalar context
say "@got"; # 1 2 3
say $msg; # three items
פונקציות מובנות משתמשות בזה גם כן. scalar @array מאלץ הקשר סקלר כדי לקבל מניין; התאמת regex עם /g מחזירה את רשימת ההתאמות בהקשר רשימה ואמת/שקר בהקשר סקלר. הניב הקלאסי ל“מנה את ההתאמות“ מאלץ השמת רשימה בהקשר סקלר באמצעות הצורה הקרויה countof:
use v5.42;
my $n = () = "a1b2c3" =~ /\d/g;
say $n; # 3
המלכודת: אין תשובה יחידה ל“מה המערך הזה עושה“ - זה תלוי בביטוי הסובב. כשמשהו מחזיר מספר שציפיתם שיהיה רשימה (או להפך), ההקשר הוא החשוד הראשון. פנו אל scalar כדי לאלץ מניין, ואל סוגריים משמאל כדי לאלץ העתקת איברים.
אמיתיוּת#
ערכי השקר של Perl הם רשימה קצרה וספציפית: המספר 0, המחרוזת הריקה "", המחרוזת "0", ו־undef (ה־None של Perl). כל השאר הוא אמת - וזה כולל כמה מחרוזות שמפתח Python מניח שהן שקריות.
use v5.42;
for my $v (0, 1, "", "0", "00", "0.0", "false") {
say "'$v' is ", ($v ? "true" : "false");
}
זה מדפיס, בדיוק:
'0' is false
'1' is true
'' is false
'0' is false
'00' is true
'0.0' is true
'false' is true
המלכודת: "00" ו־"0.0" הם אמת ב־Perl, אף שהם נראים אפס מספרית, מפני שרק המחרוזת המדויקת "0" היא שקר. המחרוזת "false" היא אמת (זוהי מחרוזת לא־ריקה ולא־"0"). ובניגוד ל־Python, מערך ריק או hash ריק אינו בעצמו ערך שקרי - בהקשר בוליאני מערך מניב את אורכו, כך ש־if (@list) הוא אמת כשהרשימה אינה ריקה, וזו הבדיקה שאתם רוצים. עבור בחירת ”השתמש בזה אם מוגדר, אחרת ברירת מחדל“, השתמשו ב־defined-or //, שנופל לערך החלופי רק על undef (לא על 0 או ""):
use v5.42;
my %cfg = (host => "localhost");
my $port = $cfg{port} // 8080; # key absent -> undef -> 8080
say $port; # 8080
זרימת בקרה#
מילות המפתח מוכרות; האיות נבדל. elif הוא elsif, ואין : ואין הזחה - בלוקים מוקפים בסוגריים מסולסלים.
if n < 0:
sign = "neg"
elif n == 0:
sign = "zero"
else:
sign = "pos"
for x in nums:
print(x)
while running:
step()
use v5.42;
my $sign;
if ($n < 0) { $sign = "neg" }
elsif ($n == 0) { $sign = "zero" }
else { $sign = "pos" }
for my $x (@nums) { say $x }
while ($running) { step() }
Perl מוסיפה שני דברים שאין ל־Python. משני סופית מאפשרים למשפט פשוט לשאת עליו את התנאי או הלולאה שלו עצמו, מה שנקרא בטבעיות עבור שורות־יחיד:
use v5.42;
say $_ for @nums; # loop, one statement
say "negative" if $n < 0; # guarded statement
$sum += $_ for @nums; # accumulate
ו־unless/until הם הצורות השליליות של if/while, למקרים שבהם הניסוח החיובי נקרא במגושמות: say "ok" unless $error.
המלכודת: האופרטור התלת־איברי משתשר באותו אופן כמו של Python, אבל עם ?/:, לא if/else: my $sign = $n < 0 ? "neg" : $n == 0 ? "zero" : "pos". ה־?: בסגנון C הוא הניב; אין צורת x if c else y.
תת־שגרות#
def הופך ל־sub. ל־Perl המודרנית יש חתימות שנראות מאוד כמו רשימות הפרמטרים של Python, כולל ערכי ברירת מחדל.
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
def total(*nums):
return sum(nums)
use v5.42;
sub greet ($name, $greeting = "Hello") {
return "$greeting, $name!";
}
say greet("Ada"); # Hello, Ada!
say greet("Linus", "Hi"); # Hi, Linus!
sub total (@nums) {
my $sum = 0;
$sum += $_ for @nums;
return $sum;
}
say total(1, 2, 3, 4); # 10
ארגומנטים על שם מילת מפתח ממופים לפרמטר hash, מאחר שזוגות key => value משתטחים לרשימה שחתימת %opts אוספת:
use v5.42;
sub connect_to (%opts) {
return "host=$opts{host} port=$opts{port}";
}
say connect_to(host => "localhost", port => 8080);
# host=localhost port=8080
המלכודת: תת־שגרה מחזירה את ערך הביטוי האחרון שלה גם בלי return, וההחזרה היא רגישת־הקשר (ראו הקשר). אם תכתבו return @list, הקורא מקבל את הרשימה בהקשר רשימה אבל את המניין בהקשר סקלר. היו מכוונים לגבי מה שאתם מחזירים כשהוא עשוי לשמש בכל אחת מהדרכים.
הפניות#
המערכים וה־hashים של Perl אינם מקננים ישירות; אתם מקננים אותם דרך הפניות, שהן המקבילה ב־Perl לידיות האובייקטים של Python (ב־Python כל מכל הוא כבר הפניה, ולכן הצעד הזה בלתי נראה לכם שם). הפניה היא סקלר המצביע אל צבר. קחו אותה עם \, עקבו אחריה עם ->.
data = {"name": "Ada", "langs": ["Perl", "Python"]}
print(data["langs"][1]) # Python
data["langs"].append("Ruby")
use v5.42;
my $data = { name => "Ada", langs => ["Perl", "Python"] };
say $data->{name}; # Ada
say $data->{langs}[1]; # Python
push $data->{langs}->@*, "Ruby"; # postfix deref to push
say "@{$data->{langs}}"; # Perl Python Ruby
{ ... } בונה הפניית hash אנונימית ו־[ ... ] הפניית מערך אנונימית - אבני הבניין הליטרליות של נתונים מקוננים, התואמות את הליטרלים {} ו־[] של Python. החץ -> עוקב אחר הפניה צעד אחד; בין שני מנויים הוא רשות, כך ש־$data->{langs}[1] ו־$data->{langs}->[1] זהים.
תת־שגרות אנונימיות הן closures, בדיוק כמו ה־lambda של Python אבל בלי הגבלת הביטוי היחיד:
use v5.42;
my $double = sub ($n) { $n * 2 };
say $double->(21); # 42
המלכודת: צורות ה־deref הסופיתיות (->@*, ->%*, ->$*) הן הדרך המודרנית והקריאה לבצע dereference לצבר שלם, ו־"@{ ... }" הוא האופן שבו אתם משחלפים מערך מ־dereferenced אל מחרוזת. הצורות הישנות יותר @$ref ו־${$ref}{key} עדיין עובדות ומופיעות בקוד קיים, אבל פנו אל צורות החץ והסופית בקוד חדש.
ביטויים רגולריים#
ב־Python ה־regex הוא הספרייה re. ב־Perl הוא תחביר: =~ קושר תבנית למחרוזת, m// מתאים, s/// מציב. קבוצות לכידה נוחתות ב־$1, $2, ולכידות על שם ב־%+.
import re
m = re.search(r"(\d{4})-(\d{2})-(\d{2})", s)
if m:
year, month, day = m.groups()
t = re.sub(",", ";", "a,b,c")
parts = "one,two,three".split(",")
use v5.42;
my $s = "2026-06-20";
if ($s =~ /(\d{4})-(\d{2})-(\d{2})/) {
say "$1 $2 $3"; # 2026 06 20
}
if ($s =~ /(?<year>\d{4})/) {
say $+{year}; # 2026
}
(my $t = "a,b,c") =~ s/,/;/g; # a;b;c
my @parts = split /,/, "one,two,three"; # one two three
התאמת /g בהקשר רשימה מחזירה את כל הלכידות, וזו המקבילה הישירה של re.findall:
use v5.42;
my @nums = "x1y2z3" =~ /(\d)/g; # 1 2 3
say "@nums";
המלכודת: s/// משנה את היעד שלו במקום ומחזיר את מספר ההצבות, לא מחרוזת חדשה. בגלל זה הדוגמה מעתיקה תחילה עם (my $t = "a,b,c") ואז מציבה על העותק - אחרת הייתם עורכים ליטרל מחרוזת. כדי לקבל מחרוזת חדשה בלי לגעת במקור, השתמשו בדגל /r: my $t = $s =~ s/,/;/gr.
קלט/פלט של קבצים וזרמים#
הניב הוא ה־open בעל שלושת הארגומנטים עם ידית קובץ לקסיקלית, המקבילה הישירה של with open(...) as f: של Python. אופרטור הסוגריים המשולשים <$fh> קורא שורה, בתפקיד זהה למעבר על אובייקט קובץ של Python.
with open("/tmp/sample.txt", "w") as f:
for i in range(1, 4):
f.write(f"line {i}\n")
with open("/tmp/sample.txt") as f:
for line in f:
print("got:", line.rstrip())
use v5.42;
my $path = "/tmp/sample.txt";
open my $wh, '>', $path or die "cannot write: $!";
print {$wh} "line $_\n" for 1 .. 3;
close $wh;
open my $rh, '<', $path or die "cannot read: $!";
while (my $line = <$rh>) {
chomp $line;
say "got: $line"; # got: line 1 ... got: line 3
}
close $rh;
כדי לבלוע את כל השורות בבת אחת, קראו את הידית בהקשר רשימה:
use v5.42;
open my $fh, '<', "/tmp/sample.txt" or die $!;
my @lines = <$fh>; # all lines, including newlines
say scalar @lines; # 3
המלכודת: שורה הנקראת עם <$fh> שומרת על תו השורה החדשה שבסופה; קראו ל־chomp כדי להסירו (רפלקס ה־line.rstrip() של Python). ו־open מחזיר שקר בכישלון במקום לזרוק, ולכן הניב or die "...: $!" הוא חובה - $! הוא הודעת שגיאת המערכת, ה־errno של Perl.
מודולים וחבילות#
import הופך ל־use. מפריד מרחב השמות הוא ::, לא ., ומודול Foo::Bar שוכן ב־Foo/Bar.pm על נתיב ההכללה @INC (ה־sys.path של Perl). רשימת הייבוא של מודול היא בחירה של שמות, בדומה מאוד ל־from module import name.
from math import sqrt
import json
data = json.loads(text)
use v5.42;
use List::Util qw(sum0 max first);
say sum0(1 .. 10); # 55
say max(3, 7, 2); # 7
say first { $_ % 2 == 0 } (1, 3, 4, 5); # 4
הספרייה הסטנדרטית גדולה, והרבה ממה שלשמו הייתם פונים ל־PyPI מגיע במובנה או ב־CPAN, ארכיון החבילות של Perl. List::Util, Scalar::Util, POSIX, File::Spec, ו־Data::Dumper הם היומיומיים.
המלכודת: use רץ בזמן ההידור, לא בנקודה בקובץ שבה הוא מופיע, ולכן סדר שורות ה־use ביחס לקוד שלכם אינו משנה כפי שמיקום import משנה. הייבוא גם הוא הצטרפות־מרצון לכל שם: use List::Util qw(sum0 max) מביא בדיוק את sum0 ו־max אל מרחב השמות שלכם, ולא יותר.
אובייקטים#
עבור קוד חדש, ל־Perl 5.42 יש תחביר class ממדרגה ראשונה שייראה מוכר בהגעה מ־Python. שדות מוצהרים עם field, מתודות עם method, ו־$self זמין בתוך כל מתודה בדיוק כפי ש־self זמין ב־Python (אינכם מציינים אותו כפרמטר).
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def to_string(self):
return f"({self.x}, {self.y})"
def move(self, dx, dy):
self.x += dx
self.y += dy
return self
p = Point(x=3, y=4)
print(p.to_string()) # (3, 4)
p.move(1, 1)
print(p.to_string()) # (4, 5)
use v5.42;
use feature 'class';
class Point {
field $x :param = 0;
field $y :param = 0;
method to_string { return "($x, $y)" }
method move ($dx, $dy) {
$x += $dx;
$y += $dy;
return $self;
}
}
my $p = Point->new(x => 3, y => 4);
say $p->to_string; # (3, 4)
$p->move(1, 1);
say $p->to_string; # (4, 5)
הבנאי נוצר עבורכם: :param מסמן שדה שה־new הבנוי־אוטומטית מקבל כארגומנט על שם, ו־= 0 הוא ברירת המחדל שלו. הורשה היא :isa:
use v5.42;
use feature 'class';
class Point3D :isa(Point) {
field $z :param = 0;
method z { return $z }
}
my $q = Point3D->new(x => 1, y => 2, z => 3);
say $q->to_string, " z=", $q->z; # (1, 2) z=3
המלכודת: תכונת ה־class עדיין מסומנת כניסיונית ב־Perl 5.42, ועל pperl הודעות ”class is experimental“ מודפסות אל stderr אפילו עם no warnings 'experimental::class' בהיקף. הן אינן נוגעות בפלט התוכנית שלכם, ולכן סקריפט המדפיס אל stdout מתנהג בדיוק כפי שמוצג למעלה; פשוט צפו להודעות בזרם השגיאות. עבור מודל האובייקטים הישן יותר מבוסס ה־bless שתפגשו בקוד קיים, ועבור roles, פרטי הורשה, והגירה, ראו את מדריך התכנות מונחה־העצמים.
טיפול בשגיאות#
ל־try/except של Python יש שתי מקבילות. הקלאסית עוטפת קוד ב־eval { } ובוחנת את $@ (השגיאה שנתפסה) לאחר מכן:
try:
risky(-1)
except Exception as e:
print("caught:", e)
use v5.42;
my $result = eval { risky(-1) };
if ($@) {
print "caught: $@"; # caught: negative!
}
הצורה המודרנית היא try/catch, הנקראת כמעט בדיוק כמו זו של Python:
use v5.42;
use feature 'try';
try {
risky(-4);
}
catch ($e) {
print "caught: $e"; # caught: negative!
}
כאשר הצד הזורק הוא die:
use v5.42;
sub risky ($n) {
die "negative!\n" if $n < 0;
return sqrt $n;
}
המלכודת: die עם מחרוזת המסתיימת ב־\n מייצר בדיוק את ההודעה הזו; die עם מחרוזת שאינה מסתיימת בתו שורה חדשה מקבל " at SCRIPT line N.\n" מצורף אוטומטית. סיימו את מחרוזות השגיאה שלכם ב־\n כשאתם רוצים הודעה נקייה, והשמיטו זאת כשאתם רוצים את עקבת הקובץ־והשורה. שימו לב גם לשני משתני השגיאה: $@ הוא החריגה האחרונה שנתפסה (except ... as e של Python), בעוד $! הוא שגיאת המערכת האחרונה (open שנכשל, מחרוזת ה־errno).
ניבים#
כמה דפוסים שתראו מדי יום ותרצו באצבעות שלכם.
מיון רשימה לפי מפתח מחושב (טרנספורם שוורץ - ה־sorted(xs, key=f) של Python בעבודת יד, קישוט ואז מיון ואז הסרת קישוט):
use v5.42;
my @words = qw(apple fig pear);
my @by_length =
map { $_->[1] }
sort { $a->[0] <=> $b->[0] }
map { [ length $_, $_ ] } @words;
say "@by_length"; # fig pear apple
בניית hash מרשימה, מקבילת ה־dict-comprehension ({w: len(w) for w in words}):
use v5.42;
my @words = qw(apple pear fig);
my %len = map { $_ => length $_ } @words;
say "$_ => $len{$_}" for sort keys %len;
# apple => 5
# fig => 3
# pear => 4
ו־pperl הוא כלי שורת־פקודה בנישה של awk/sed. שורת־היחיד עם הלולאה המובלעת היא הרפלקס היומיומי של מפתח Perl:
pperl -lane '$s += $F[-1]; END { print $s }' data.txt
המלכודת: קראו את מדריך שורות־היחיד עבור המתגים (-n, -p, -a, -l, -e) ועשרות המתכונים הבנויים עליהם; זהו אחד הדברים בעלי המנוף הגבוה ביותר ללמוד בהגעה מרקע של shell ו־Python.
מלכודות בהגעה מ־Python#
המלכודות, אסופות לסריקה אחרונה לפני שאתם מתחילים לכתוב:
Sigils משתנים עם השימוש. איבר אחד של
@aהוא$a[0]; ערך אחד של%hהוא$h{k}. sigil המכל ו־sigil האיבר נבדלים..מצרף מחרוזות,+מחבר מספרים. לעולם אל תשתמשו ב־+כדי לשרשר שתי מחרוזות; זה כופה עליהן המרה למספרים ומזהיר.שתי משפחות השוואה.
==/</<=>למספרים,eq/lt/cmpלמחרוזות. בחרו לפי טיפוס האופרנד, לא לפי המשתנה.sortממוין כמחרוזות כברירת מחדל. העבירו{ $a <=> $b }לסדר מספרי.הקשר.
my $x = @aהוא האורך;my ($x) = @aהוא האיבר הראשון. הסוגריים הם כל ההבדל. קראו מחדש את הקשר כשערך חוזר בצורה הלא־נכונה.הפתעות אמיתות.
"0"הוא שקר, אבל"00"ו־"0.0"הם אמת. רק0,"","0", ו־undefהם שקר.s///עורך במקום ומחזיר מניין; השתמשו בדגל/rכדי לקבל מחרוזת חדשה במקום זאת.openאינו זורק. השתמשו ב־open ... or die "...: $!".הריצו
chompעל קריאות השורה שלכם.<$fh>שומר על תו השורה החדשה שבסוף.מקור שאינו ASCII זקוק ל־
use utf8;. תחתuse v5.42;בית שאינו ASCII כליטרל במקור שלכם הוא שגיאת הידור בלעדיו. שמרו על נתוני מחרוזות כ־ASCII אלא אם תוסיפו במפורשuse utf8;.The
classfeature prints experimental notices to stderr onpperl. Correct output, noisy error stream.