מ־Tcl ל־Perl#
אתם מכירים את Tcl. אתם כותבים set x 5, מבצעים החלפה עם $x, נשענים על [expr {...}] לביצוע חשבון, בונים רשימות עם lappend ועוברים עליהן עם foreach, ומכופפים מחרוזות עם regexp ו־regsub. מדריך זה ממפה כל אחד מההרגלים הללו אל Perl, כך שתוכלו לשמר כל רפלקס שיש לכם ולאמץ את הדברים ש־Tcl מקשה עליהם.
ל־Tcl ול־Perl יש אותם שורשים: כתיבת סקריפטים ב־Unix, השקפת־עולם של מחרוזת־תחילה, והחלפת־$ כדרך להגיע למשתנה. רוב מה שאתם יודעים ממופה כמעט ישירות - ו־Perl נותנת לכם מבני נתונים אמיתיים (@arrays ו־%hashes כטיפוסים ממדרגה ראשונה, לא רשימות שגויסו לתפקיד) ומערכת מודולים עצומה לנחות בה. שני פריטי חיכוך ספציפיים מקבלים את המשקל במדריך זה: טיפוסי המערך/האש הנפרדים של Perl היכן של־Tcl יש רשימות ומערכים אסוציאטיביים, והביטויים הרגולריים של Perl (על־קבוצה של אלה של Tcl). חומר השורה־בכל־פעם ושורת־הקוד־האחת קל יותר כאן, מכיוון ש־Tcl אינה שפת שורת־קוד־אחת; את זמנכם תבלו במשתנים, נתונים, זרימת בקרה, וביטויים רגולריים.
Every runnable example here was executed on pperl, a Rust reimplementation of Perl 5.42; the # ... comments show its real output. Start scripts with:
use v5.42;
שורה אחת זו מפעילה את strict, את warnings, ואת הפונקציה המובנית say (כלומר print עם תו שורה חדשה נגרר, התאום הגס של ה־puts של Tcl), מערך התכונות המודרני המשמש לאורך כל הדרך.
הערה
מתגי שורה־אחת ב־build הזה של pperl מתגי שורת־הקוד־האחת של Perl - perl -ne, perl -pe, -a, -i, -l - הם perl5 5.42 תקני והם הצורה האידיומטית לעבודת טקסט אד־הוק. אך משפחת מתגי הלולאה המשתמעת (-n, -p, -a, -F, -i, -l) עדיין אינה מזוהה על ידי build זה של pperl - רק -e מזוהה. לכן דוגמאות שורת־הקוד־האחת שלהלן מוצגות ללא פלט, וכל אחת מהן מצומדת לצורת סקריפט־מלא עם לולאה מפורשת (while (<$fh>) { ... }) שאכן רצה על pperl היום ונושאת את הפלט המאומת. השתמשו בצורת הסקריפט המלא עד שהמתגים ייכנסו.
כיצד לקרוא את זה#
משתנים והחלפה -
setהופך ל־my,[expr]נעלם, החלפת$xנשארת.רשימות ומערכים -
lindex/lappend/lsortהופכים לפעולות מערך של Perl.מערכים אסוציאטיביים והאשים -
set a(k) vהופך ל־$a{k};dictהופך להאש.פרוצים והפניות -
procהופך ל־sub;upvar/uplevelהופכים להפניות.ביטויים רגולריים והחלפה -
regexp/regsub/string mapהופכים ל־m///s////tr///.זרימת בקרה -
if/while/foreach/switchהופכים לאלה של Perl, בתוספת ציטוט{}מול"".לולאת השורה/רשומה - קריאת קובץ שורה אחר שורה עם
$_ו־$..שדות ופיצול -
split/join, המקבילה ל־splitשל Tcl.קלט/פלט, צינורות, ועריכה במקום -
open/gets/puts/execהופכים ל־open/<$fh>/print/qx.שורות־קוד־אחת ומתגים -
-n,-p,-e, נשמר תמציתי.מלכודות בהגעה מ־Tcl - סרקו לפני שאתם כותבים.
משתנים והחלפה#
ב־Tcl, set x 5 יוצר משתנה ו־$x מחליף את ערכו. ב־Perl, my $x = 5; מצהיר על משתנה מתוחם מילונית ו־$x מחליף אותו - תחביר ההחלפה שאתם כבר מכירים עובר מילולית. ההקלה היא ש־Perl יש לה אופרטורים מולדים: אין [expr {...}]. חשבון הוא פשוט חשבון.
set x 5
set name "world"
set sum [expr {$x + 3}]
puts "x is $x"
puts "sum is $sum"
use v5.42;
my $x = 5; # set x 5
my $name = "world";
my $sum = $x + 3; # native operators, no [expr] needed
say "x is $x"; # x is 5
say "sum is $sum"; # sum is 8
ציטוט ממופה בנקיות, וזה מיפוי משמח: ה־"..." של Tcl (החלפה מתרחשת) הוא מחרוזת מצוטטת־כפול של Perl, וה־{...} של Tcl (מילולי, ללא החלפה) הוא מחרוזת מצוטטת־בודד של Perl.
use v5.42;
my $name = "world";
say "hello, $name"; # hello, world (interpolates)
say 'no $interp here'; # no $interp here (literal)
המלכודת: Tcl היא ”הכול הוא מחרוזת“ ו־Perl קרובה לכך - סקלר מומר אוטומטית בין מספר למחרוזת לפי הקשר - אך Perl מפצלת השוואה לשתי משפחות אופרטורים, ואתם בוחרים לפי הפעולה, לא לפי הערך. מספרים משתמשים ב־==, !=, <, >; מחרוזות משתמשות ב־eq, ne, lt, gt.
use v5.42;
my $x = "5";
say $x + 3; # 8 (numeric context coerces "5")
say $x . "3"; # 53 (string context)
say "10" == "10.0" ? "num-equal" : "num-differ"; # num-equal
say "10" eq "10.0" ? "str-equal" : "str-differ"; # str-differ
== משווה את "10" ו־"10.0" כמספרים (שווים); eq משווה אותם כמחרוזות (שונים). שימוש ב־== היכן שהתכוונתם ל־eq, או להפך, הוא הבאג השקט האחד שהשקפת־העולם של מחרוזת־תחילה מכינה לכם.
רשימות ומערכים#
רשימת Tcl היא מערך Perl, והפעלים מתיישרים אחד לאחד. ההסטה הגדולה: ב־Tcl הכול הוא רשימה, כולל מחרוזות שאתם מפצלים תוך כדי תנועה; ב־Perl מערך (@a) הוא טיפוס נפרד ממדרגה ראשונה עם הסיגיל שלו. כשאתם מגיעים לאיבר אחד, הסיגיל עוקב אחר האיבר, כך שזה $a[0] (סקלר), לא @a[0].
set items [list apple pear fig]
puts [lindex $items 0]
puts [llength $items]
lappend items plum
set sorted [lsort $items]
foreach it $items { puts "item: $it" }
use v5.42;
my @items = ("apple", "pear", "fig");
say $items[0]; # apple (lindex $items 0)
say scalar @items; # 3 (llength $items)
push @items, "plum"; # lappend items plum
my @sorted = sort @items; # lsort
say "@sorted"; # apple fig pear plum
for my $it (@items) { # foreach it $items
say "item: $it";
}
ל־lsearch - ”מצא את האינדקס של איבר תואם“ - אין פונקציה מובנית יחידה; ה־Perl האידיומטית היא grep על טווח האינדקסים, עם $#items כאינדקס האחרון:
use v5.42;
my @items = ("apple", "pear", "fig", "plum");
my ($idx) = grep { $items[$_] eq "fig" } 0 .. $#items; # lsearch
say "fig at $idx"; # fig at 2
המלכודת: scalar @items היא הדרך שבה אתם משיגים את האורך (ה־llength של Tcl); כתיבת my $n = @items עובדת מכיוון שהשמת מערך לסקלר מניבה את ספירתו, אך אייתו זאת scalar @items כשאתם רוצים את האורך בתוך ביטוי גדול יותר. ו־sort משווה כמחרוזות כברירת מחדל, כך ש־sort (10, 9, 100) נותן 10 100 9; העבירו משווה מספרי sort { $a <=> $b } @nums לסדר מספרי, היכן ש־$a ו־$b הם שני האיברים ו־<=> הוא האופרטור המספרי התלת־כיווני.
מערכים אסוציאטיביים והאשים#
מערך אסוציאטיבי של Tcl - set a(red) 1 - הוא האש Perl. גישת האיבר ממופה ישירות: ה־$a(red) של Tcl הוא ה־$a{red} של Perl, והאוסף כולו הוא %a (ל־Tcl אין תחביר למערך כערך יחיד; ל־Perl יש). ה־dict של Tcl המודרנית ממופה לאותה האש Perl, או להפניית האש כשאתם זקוקים לקנן או להעביר אותה.
set a(red) 1
set a(green) 2
set a(blue) 3
puts $a(red)
puts [array exists a]
foreach k [lsort [array names a]] { puts "$k => $a($k)" }
unset a(blue)
use v5.42;
my %a = (red => 1, green => 2, blue => 3);
say $a{red}; # 1 ($a(red))
say exists $a{green} ? "yes" : "no"; # yes (info exists a(green))
for my $k (sort keys %a) { # array names a
say "$k => $a{$k}";
}
delete $a{blue}; # unset a(blue)
זה מדפיס:
1
yes
red => 1
green => 2
blue => 3
המלכודת: חברות היא exists $a{key}, לא פקודה נפרדת, והפסיק השמן => הוא מפריד המפתח/ערך האידיומטי בליטרל האש. => גם מצטט אוטומטית את ה־bareword משמאלו, כך ש־red => 1 אינו זקוק לגרשיים סביב red. להאש אין סדר מובנה (גם למערך Tcl אין); עברו sort keys %a כשאתם רוצים סדר יציב, בדיוק כפי שאתם נשענים על lsort [array names a].
פרוצים והפניות#
proc name {args} {body} הופך ל־sub name { ... } של Perl. הדרך הקלאסית של Tcl לקרוא ארגומנטים - מיקומית, לפי שם - יש לה תאום Perl ישיר: my ($a, $b) = @_; פורק את מערך הארגומנטים @_. ל־Perl מודרנית יש גם חתימות, הנקראות כמו רשימת ה־{args} של Tcl ומוסיפות ברירות מחדל.
proc add {a b} {
return [expr {$a + $b}]
}
puts [add 3 4]
proc greet {who {greeting Hello}} {
return "$greeting, $who!"
}
puts [greet Tcl]
puts [greet Perl Hi]
use v5.42;
sub add {
my ($a, $b) = @_; # unpack the argument array
return $a + $b;
}
say add(3, 4); # 7
sub greet ($who, $greeting = "Hello") { # signature with default
return "$greeting, $who!";
}
say greet("Tcl"); # Hello, Tcl!
say greet("Perl", "Hi"); # Hi, Perl!
ההעברה־לפי־שם של Tcl - upvar, שבה פרוצדורה מושיטה יד מעלה ומשנה משתנה של הקורא - הופכת להפניה של Perl: קחו אחת עם \, עקבו אחריה עם $$ref. אתם מעבירים את ההפניה במפורש במקום לנקוב את המשתנה, מה שהופך את זרימת הנתונים לגלויה באתר הקריאה.
use v5.42;
sub increment {
my ($ref) = @_;
$$ref++; # mutate through the reference (Tcl: upvar)
}
my $count = 10;
increment(\$count); # pass a reference to $count
say $count; # 11
המלכודת: @_ הוא מערך הארגומנטים, ו־my ($a, $b) = @_; מעתיק את הארגומנטים למקומיים בעלי שם - השורה שאתם כמעט תמיד רוצים בראש תת־שגרה. נשיאה לכינוי בסגנון upvar נדרשת לעיתים רחוקות ב־Perl; כשאתם כן זקוקים לשנות נתוני קורא, העבירו הפניה (\$x, \@arr, \%h) במכוון במקום לכנות לפי שם. הפניות הן גם הדרך שבה Perl מקננת נתונים (מערך של האשים, האש של מערכים); אותו מנגנון המחליף את upvar הוא זה המחליף את הרשימות המקוננות המקודדות־מחרוזת של Tcl.
ביטויים רגולריים והחלפה#
זה סעיף מטען. ה־regexp וה־regsub של Tcl משתמשים בביטויים רגולריים מתקדמים; הביטויים הרגולריים של Perl הם על־קבוצה, כך שהתבניות שאתם מכירים עוברות וצוברות תכונות. Perl הופכת ביטויים רגולריים לתחביר, לא לפקודה: =~ קושר תבנית למחרוזת, m// מתאים, s/// מחליף, ו־tr/// מתעתק.
set s "order 42 shipped"
if {[regexp {(\d+)} $s -> num]} {
puts "number: $num"
}
set t [regsub -all {o} "foo boo zoo" O]
puts $t
set u [string map {a A b B} "abcabc"]
puts $u
use v5.42;
my $s = "order 42 shipped";
if ($s =~ /(\d+)/) { # regexp; capture lands in $1
say "number: $1"; # number: 42
}
(my $t = "foo boo zoo") =~ s/o/O/g; # regsub -all -> s///g
say $t; # fOO bOO zOO
(my $u = "abcabc") =~ tr/ab/AB/; # string map (char-for-char)
say $u; # ABcABc
גם הלכידה ממופה: משתנה ההתאמה -> num של Tcl הופך ל־$1, $2 של Perl, וכן הלאה, כשלכודות בעלות שם נוחתות ב־%+:
use v5.42;
if ("2026-06-21" =~ /(?<y>\d{4})-(?<m>\d{2})/) {
say "$+{y} / $+{m}"; # 2026 / 06
}
ה־string match של Tcl הוא התאמת glob, לא ביטוי רגולרי (string match *.txt $name). ב־Perl, עגנו ביטוי רגולרי במקום - /\.txt$/ היא המקבילה - מכיוון ששפת התבנית האחת של Perl מכסה את שתי המשימות.
use v5.42;
my $name = "report.txt";
say "matches" if $name =~ /\.txt$/; # string match *.txt $name
# matches
המלכודת: s/// משנה את היעד שלו במקום ומחזיר את ספירת ההחלפות, לא את המחרוזת החדשה - וזו הסיבה שהדוגמאות לעיל מעתיקות תחילה עם (my $t = "...") לפני ההחלפה. כדי לקבל מחרוזת חדשה ולהשאיר את המקור ללא שינוי, השתמשו בדגל /r: my $new = $s =~ s/o/O/gr. ו־tr/// (המקבילה ל־string map עבור תווים בודדים) אינו ביטוי רגולרי: צידו השמאלי הוא קבוצת תווים מילולית, כך ש־tr/ab/AB/ ממפה את a ו־b בלבד. לעבודת תבניות, נשענו על s///.
זרימת בקרה#
מבני הבקרה ממופים כמעט אחד לאחד; האיות מוסט והסוגריים המסולסלים נשארים. ה־if {cond} {body} של Tcl הופך ל־if (cond) { body } של Perl, elseif הופך ל־elsif, ו־foreach הופך ל־for (שני האיותים הם כינויים ב־Perl; foreach עובד גם הוא).
if {$n < 0} {
set sign neg
} elseif {$n == 0} {
set sign zero
} else {
set sign pos
}
set i 0
while {$i < 3} { puts "i=$i"; incr i }
foreach w {a b c} { puts "w=$w" }
use v5.42;
my $n = 0;
my $sign;
if ($n < 0) { $sign = "neg" }
elsif ($n == 0) { $sign = "zero" } # elseif -> elsif
else { $sign = "pos" }
say $sign; # zero
my $i = 0;
while ($i < 3) { say "i=$i"; $i++ } # incr i -> $i++
for my $w (qw(a b c)) { say "w=$w" } # foreach w {a b c}
ל־switch של Tcl אין מילת־מפתח יחידה ב־Perl; ההחלפה האידיומטית היא האש שיגור הממפה כל מקרה להפניית קוד, מה שמהיר וגמיש יותר משרשרת if:
use v5.42;
my $cmd = "start";
my %dispatch = (
start => sub { "starting" },
stop => sub { "stopping" },
);
say $dispatch{$cmd}->(); # starting
המלכודת: ההבחנה בין {} ל־"" שעליה אתם נשענים ב־Tcl לדחייה מול החלפה ממופה ל־'' מול "" של Perl למחרוזות (שכוסה לעיל), אך הסוגריים המסולסלים של בלוק ב־Perl אינם ציטוט - { ... } של Perl לאחר if/while/for הוא בלוק קוד, תמיד מוערך, לעולם לא מחרוזת נדחית. אין שלב של ”הגוף הוא מחרוזת עד שאני מריץ אותו“; Perl מנתחת את הבלוק בזמן ההידור. מתאמי סיומת הם בונוס של־Tcl אין צורה אליו: say $_ for @items; ו־say "neg" if $n < 0; נושאים את הלולאה או התנאי לאחר המשפט.
לולאת השורה/רשומה#
Tcl קוראת קובץ עם set fh [open f r]; while {[gets $fh line] >= 0} {...}. המקבילה של Perl היא לולאת while (<$fh>), כשכל שורה נוחתת ב־$_ (משתנה הנושא המשתמע) או בסקלר בעל שם. מספר השורה נמצא ב־$..
set fh [open /tmp/tcl_data.txt r]
while {[gets $fh line] >= 0} {
puts "got: $line"
}
close $fh
use v5.42;
open my $fh, '<', '/tmp/tcl_data.txt' or die "open: $!";
while (my $line = <$fh>) { # gets $fh line
chomp $line; # <$fh> keeps the newline; strip it
say "got: $line"; # puts
}
close $fh;
# got: apple
# got: banana
# got: cherry
(קובץ הקלט החזיק apple, banana, cherry.) שימוש ב־$_ ובמונה השורות $. נקרא קרוב עוד יותר ללולאת רשומה:
use v5.42;
open my $fh, '<', '/tmp/tcl_data.txt' or die "open: $!";
while (<$fh>) { # each line lands in $_
chomp; # chomp defaults to $_
say "$. : $_"; # $. is the current line number
}
close $fh;
# 1 : apple
# 2 : banana
# 3 : cherry
המלכודת: ה־gets של Tcl מקצץ עבורכם את תו השורה החדשה הנגרר; ה־<$fh> של Perl שומר עליו, לכן קראו ל־chomp כשאינכם רוצים אותו. ללא ארגומנט, chomp ו־say/print שניהם משתמשים בברירת המחדל $_, וזו הסיבה שהלולאה השנייה לעולם אינה נוקבת את משתנה השורה.
שדות ופיצול#
ה־split $line $sep של Tcl מחזיר רשימה; ה־split /sep/, $line של Perl מחזיר מערך, ו־join מחבר אותו בחזרה. ההבדל: מפריד פיצול של Perl הוא ביטוי רגולרי, כך שאתם מקבלים את שפת התבנית המלאה בחינם.
set line "a:b:c"
set parts [split $line ":"]
puts [llength $parts]
puts [lindex $parts 1]
puts [join $parts ","]
use v5.42;
my $line = "a:b:c";
my @parts = split /:/, $line; # split $line ":" (separator is a regex)
say scalar @parts; # 3 (llength $parts)
say $parts[1]; # b (lindex $parts 1)
say join ",", @parts; # a,b,c (join $parts ",")
המלכודת: split ' ' עם מחרוזת רווח־בודד מילולית הוא מקרה מיוחד המפצל על כל רצף של רווחים לבנים ומשמיט שדות ריקים מובילים - התנהגות ”פיצול למילים“ בסגנון awk, ובדרך כלל מה שאתם רוצים לקלט חופשי־צורה. split / / (ביטוי רגולרי עם רווח אחד) הוא ה“פיצול על כל רווח בודד“ המילולי ואינו דוחס רצפים. הישענו על split ' ' כדי לחלק מילים לאסימונים:
use v5.42;
my @words = split ' ', " the quick brown ";
say "@words"; # the quick brown
קלט/פלט, צינורות, ועריכה במקום#
ה־open/gets/puts/read/close של Tcl ממופים אל ה־open/<$fh>/ print/בליעה/close של Perl. הניב הוא ה־open התלת־ארגומנטי עם מטפל קובץ מילוני. ה־exec של Tcl - הרץ פקודה ולכוד את פלטה - הופך ל־qx{...} (גרשים אחוריים) של Perl או ל־system כשאינכם זקוקים לפלט.
set out [exec echo hello from shell]
puts "exec said: $out"
use v5.42;
my $out = qx{echo hello from shell}; # exec -> qx// (backticks)
chomp $out;
say "exec said: $out"; # exec said: hello from shell
ל־Tcl אין עריכת קובץ במקום מובנית; אתם קוראים, ממירים, וכותבים חזרה. המתג -i של Perl הוא צורת שורת־הקוד־האחת של בדיוק זה, והמקבילה הניתנת־להרצה של סקריפט מלא היא קריאה־שינוי־כתיבה שאתם יכולים לכתוב היום:
use v5.42;
my $path = '/tmp/tcl_inplace.txt'; # holds: red green blue
open my $in, '<', $path or die "read: $!";
my @lines = <$in>; # slurp all lines (list context)
close $in;
s/e/E/g for @lines; # transform each line's $_
open my $out, '>', $path or die "write: $!";
print {$out} @lines; # write them back
close $out;
# file now holds:
# rEd
# grEEn
# bluE
המלכודת: open מחזיר שקר בכישלון במקום לזרוק חריגה (Tcl זורקת שגיאה שאתם תופסים עם catch), לכן הניב or die "...: $!" הוא חובה - $! היא מחרוזת שגיאת המערכת. לצינורות, Perl פותחת מטפל קובץ של צינור ישירות: open my $fh, '-|', 'ls', '-l' קורא את פלט הפקודה ו־open my $fh, '|-', 'sort' כותב לקלט הפקודה, הצורה המובנית של ה־open "|command" של Tcl.
שורות־קוד־אחת ומתגים#
Tcl אינה שפת שורת־קוד־אחת, כך שסעיף זה תמציתי - אך Perl כן, וברגע שאתם משאירים את Tcl מאחור כדאי לדעת שהרפלקס קיים. משפחת המתגים: -e מספק את התוכנית, -n עוטף אותה בלולאה ללא הדפסה אוטומטית, -p עוטף אותה בלולאת הדפסה אוטומטית, -i עורך במקום, ו־-a/-F מפצלים אוטומטית כל שורה אל @F. בלוקי BEGIN { } ו־END { } רצים לפני ואחרי הלולאה.
perl -ne 'print if /error/' log.txt # print matching lines
perl -pe 's/\d+/N/g' input.txt # mask numbers
perl -nE 'END { say $n } $n++ if /error/' log.txt # count, END block
אלה מוצגים ללא פלט מכיוון שמתגי הלולאה המשתמעת אינם מזוהים על ידי build זה של pperl עדיין (ראו את ההערה בראש). כל אחד ממופה לצורת לולאה מפורשת מאומתת: perl -ne 'CODE' הוא while (<$fh>) { CODE }, ו־perl -pe 'CODE' הוא אותו דבר עם print נגרר. הצורה הניתנת־להרצה ”ספירת שורות תואמות“:
use v5.42;
open my $fh, '<', '/tmp/tcl_data.txt' or die "open: $!";
my $n = 0;
while (<$fh>) {
$n++ if /banana/; # the body of -ne
}
say $n; # 1
המלכודת: עד שהמתגים ייכנסו ל־pperl, כתבו את הלולאה המפורשת (היא רצה היום וזה ממילא מה שהמתגים מתרחבים אליו), ועיינו במדריך שורות־הקוד־האחת לקטלוג המתגים המלא ולמתכונים. ל־Perl יש גם תת־שגרות מלאות, הפניות, מודולים, ותכנות מונחה־עצמים אם הסקריפט שלכם גדל מעבר למשימת דבק: המחלקות namespace eval ו־[incr Tcl] של Tcl ממופות לחבילות Perl ולתחביר ה־class המודרני; ראו את מדריך התכנות מונחה־העצמים לצד הזה של השפה.
מלכודות בהגעה מ־Tcl#
המלכודות, מקובצות לסריקה אחרונה לפני שאתם כותבים:
שתי משפחות השוואה.
==/</<=>משווים מספרית;eq/lt/cmpמשווים כמחרוזות."10" == "10.0"הוא אמת,"10" eq "10.0"הוא שקר. בחרו לפי הפעולה, לא לפי הערך - הבאג השקט האחד שהשקפת־העולם של מחרוזת־תחילה מזמינה.הסיגיל עוקב אחר האיבר. איבר אחד של
@itemsהוא$items[0](סקלר), לא@items[0]; ערך אחד של%aהוא$a{red}. סיגיל המכל וסיגיל האיבר שונים.sortממוין כמחרוזות כברירת מחדל, כמו השוואה עםeq. העבירו{ $a <=> $b }לסדר מספרי.s///מחזיר ספירה, לא את המחרוזת החדשה, ועורך במקום. העתיקו תחילה ((my $t = $s) =~ s/.../.../) או השתמשו בדגל/rלמחרוזת רעננה.tr///(המקבילה ל־string map) הוא קבוצת תווים מילולית, לא ביטוי רגולרי.tr/ab/AB/ממפה תווים בודדים. לתבניות, השתמשו ב־s///.split ' 'ו־split / /שונים. מחרוזת הרווח־המילולי מפצלת על רצפי רווחים לבנים ומשמיטה ריקים מובילים (מחלק־המילים־לאסימונים); ביטוי הרווח־האחד אינו עושה זאת. השתמשו ב־split ' 'לקלט חופשי־צורה.<$fh>שומר על תו השורה החדשה הנגרר, בניגוד ל־getsשל Tcl. קראו ל־chompכדי לקצץ אותו.openאינו זורק חריגה בכישלון. השתמשו ב־open my $fh, '<', $path or die "...: $!".$!היא מחרוזת שגיאת המערכת; איןcatchלעטוף אותה.הפניות מחליפות את
upvar. כדי לשנות משתנה של הקורא, העבירו הפניה (\$x,\@arr,\%h) במכוון במקום לכנות לפי שם. הפניות הן גם הדרך שבה Perl מקננת נתונים.בלוק
{ ... }הוא קוד, לא מחרוזת נדחית. Perl מנתחת בלוקים בזמן ההידור; אין שלב של ”הגוף הוא מחרוזת עד שאני מריץ אותו“. רק''/""נושאים את הבחנת ההחלפה{}/""של Tcl.מתגי הלולאה המשתמעת (
-n/-p/-a/-F/-i/-l) עדיין אינם מזוהים על ידי build זה שלpperl. רק-eעובד היום. כתבו את הלולאה המפורשתwhile (<$fh>) { ... }, שהיא בדיוק מה שהמתגים מתרחבים אליו, עד שהם ייכנסו.