סקלרים ומחרוזות

q//#

ליטרל מחרוזת במירכאות בודדות עם בחירת מתחם.

q// היא הצורה הגנרית של ליטרל המחרוזת הרגיל '...'. היא מפיקה מחרוזת קבועה בזמן ההידור, אינה משלבת משתנים, ואינה מעבדת את רצפי ה־escape של backslash ש־qq// וליטרלי regex מזהים. פנו ל־q// בכל פעם שהליטרל שאתם רוצים לכתוב יהיה מסורבל תחת '...' - לרוב בגלל שהמחרוזת עצמה מכילה מירכאות בודדות - או כאשר מתחם שונה פשוט קריא יותר בהקשר.

תקציר#

q/STRING/
q(STRING)
q[STRING]
q{STRING}
q<STRING>
q!STRING!
q#STRING#
'STRING'

כל תו לא־אלפאנומרי עובד כמתחם. ארבעת זוגות הסוגריים ASCII ((), [], {}, <>) מקננים; כל המתחמים האחרים אינם. '...' הוא קיצור עבור q(...) עם סמנטיקה זהה.

מה מקבלים בחזרה#

מחרוזת בהקשר סקלרי - רצף הבייטים המדויק בין המתחם הפותח לסוגר, עם שני שכתובים:

  • \\ הופך ל־backslash בודד.

  • \<delim> הופך לעותק מילולי של תו המתחם (זה מה שמאפשר לכלול את המתחם בתוך הגוף).

כל תו אחר, כולל כל \ אחר, נשאר מילולית. אין \n, אין \t, אין הרחבת $var, אין \x{...}, אין \N{...} - תוכן q// קרוב ככל האפשר ל־״מה שהקלדתם זה מה שאתם מקבלים״ ש־Perl מציע.

בהקשר רשימה q// עדיין מוערך למחרוזת היחידה.

מתחמים וקינון#

מתחמים שאינם סוגריים משתמשים באותו תו מלפנים ומאחור:

my $a = q!I said, "You said, 'She said it.'"!;
my $b = q/path/to/file/;   # WRONG - ends at the second "/"
my $b = q{path/to/file};   # RIGHT - braces nest, slashes are literal

מתחמי סוגריים מקננים, אז סוגריים מאוזנים בתוך הגוף הם בסדר ורק סוגר לא־מאוזן מסיים את המחרוזת:

my $c = q{foo{bar}baz};    # "foo{bar}baz"
my $d = q(f(o(o)b)ar);     # "f(o(o)b)ar"

רווחים בין q לבין המתחם מותרים למעט כאשר המתחם הוא # - q#foo# היא המחרוזת "foo", אך q #foo# הוא האופרטור q ואחריו הערת שורה, וגוף המחרוזת ממשיך בשורה הבאה. כאשר המתחם הוא תו מילה (תואם ל־/\w/), רווחים בין q למתחם הם חובה: q XfooX הוא "foo", qXfooX הוא שגיאת תחביר.

כללי escape#

בתוך q// ל־backslash יש בדיוק שני תפקידים מיוחדים:

רצף

מפיק

\\

backslash בודד

\<delim>

עותק מילולי של המתחם

כל דבר אחר המתחיל ב־\ נשאר כשני תווים:

print q(\n), "\n";       # prints "\n" then a real newline
print length q(\n);      # 2
print q(\t\r\0);         # prints "\t\r\0" - six characters

זהו מקור הבלבול הנפוץ ביותר עבור מחברים המגיעים ממחרוזות במירכאות כפולות - ב־q// וב־'...', \n הוא backslash ואחריו האות n, לא ירידת שורה.

דוגמאות#

הטמעת שני סוגי מירכאות ללא escape:

my $msg = q{I said "hello", she said 'hi'.};

נתיב בסגנון Windows, שבו backslashes רבים והשילוב במירכאות כפולות יהיה מסוכן:

my $path = q(C:\Users\alice\Documents);
print $path;                 # C:\Users\alice\Documents

$ מילולי ללא שילוב - qq// היה דורש escape לכל $ ו־@, q// משאיר אותם כפי שהם:

my $expr = q($total = $x + $y);
print $expr;                 # $total = $x + $y

הדרך האחת והיחידה להכניס את המתחם בתוך הגוף: לעשות לו escape עם backslash. שימו לב שה־backslash עצמו נצרך.

my $s = q!He said "ouch\!" loudly!;
print $s;                    # He said "ouch!" loudly

תבנית regex מאוחסנת כמחרוזת רגילה, נדחית ל־qr// באתר השימוש - q// שומר backslashes מילולית כך שהתבנית שורדת בשלמותה:

my $pat = q(\d{3}-\d{4});
if ($phone =~ /$pat/) { ... }

ליטרל רב־שורות ללא עיבוד escape - כל ירידת שורה במקור הופכת לירידת שורה במחרוזת:

my $sql = q{
    SELECT id, name
    FROM   users
    WHERE  active = 1
};

מקרי קצה#

  • q// הוא בזמן הידור. המפענח פותר את המחרוזת כשהמקור נקרא; אין עלות זמן ריצה מעבר לשימוש בקבוע שכבר נבנה. כמו '...'.

  • '...' ו־q(...) בלתי ניתנים להבחנה לאחר הפענוח. הבחירה היא סגנונית בלבד - בחרו את הקריאה יותר לתוכן.

  • מחרוזת ריקה. q() ו־'' שניהם מניבים את המחרוזת באורך אפס.

  • אין \n, אין \t, אין שילוב, אף פעם. אם אתם זקוקים לאיזה מהם, עברו ל־qq// או "...". עירוב שני אלה בשורה אחת בסדר: q(literal ) . qq(interpolated $x).

  • Backslash בסוף הגוף. \ בודד מיד לפני המתחם הסוגר עושה לו escape, אז q(foo\) הוא שגיאת תחביר - ה־\) הופך ל־) מילולי והמחרוזת אינה מסתיימת. כתבו q(foo\\) כדי לסיים מחרוזת עם backslash אחד.

  • סוגריים לא־מאוזנים עם מתחמי סוגריים. מאחר שסוגריים מקננים, q{foo{bar} הוא שגיאת תחביר - ה־{ הפנימי פותח רמת קינון וה־} החיצוני סוגר אותה, ומשאיר את המחרוזת לא־מסתיימת. השתמשו במתחם שאינו סוגריים, או אזנו את הסוגריים, או עשו escape לאחד מהם: q{foo\{bar}.

  • # כמתחם אינו צריך רווח מ־q, אבל כל מתחם אחר שהוא תו מילה (אותיות, ספרות, _) דורש רווח בין q למתחם הפותח.

  • ציטוט קוד Perl הוא שביר. q{ if ($x eq "}") { ... } } הוא שגיאת תחביר: ה־} בתוך המחרוזת המוטמעת במירכאות כפולות סוגר את הסוגר החיצוני לפני ש־Perl רואה את המחרוזת הפנימית. כלים כמו Text::Balanced קיימים מאחר שכתיבה ידנית של quoter מקור Perl יציב היא בלתי־נעימה.

  • עמימות מפענח עם / כמתחם. q/.../ משתמש ב־/ באותה דרך ש־m// עושה. בתוך הגוף לא חל תחביר regex, אבל לוכסן בתוכן יסיים את המחרוזת מוקדם - בחרו מתחם שונה (q{...}, q(...)) כאשר לוכסנים מופיעים בטקסט.

  • Heredocs עם <<'TAG' עוקבים אחר אותם כללי escape כמו q//: אין שילוב, אין עיבוד escape מעבר ל־\\ ו־\TAG שאינו מיוחד (התג מסתיים בשורה משלו). השתמשו ב־heredoc במירכאות בודדות כשרוצים סמנטיקת q// על־פני שורות רבות ללא מתחם סוגר באמצע הטקסט.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • qq// - ליטרל במירכאות כפולות; אותה גמישות מתחמים כמו q// בתוספת שילוב משתנים ואוצר המילים המלא של escape \n/\t/\x{...}

  • qw// - רשימת מילים מופרדות־רווחים; מה שרוצים כשהליטרל הוא רשימת טוקנים קצרים, לא מחרוזת בודדת

  • qr// - הידור ליטרל regex; חבר התאמת התבנית של משפחת ה־quote-like

  • qx// - הרצת פקודה ב־shell ולכידת הפלט שלה; אותם כללי מתחם, סמנטיקה של backticks

  • quotemeta - שווה ערך של \Q...\E בזמן ריצה, שימושי כשצריך להזין ליטרל q// ל־regex כמחרוזת קבועה

  • $" - מפריד רשימה שמשמש כאשר מערכים משולבים בתוך qq//; לא רלוונטי ל־q// עצמו אבל הסיבה הרגילה שמישהו פונה ל־q// היא להימנע ממנגנון זה