evalbytes#
הידור והרצה של מחרוזת קוד מקור של Perl, תוך אילוץ פירוש המקור כבתים ולא כתווים.
evalbytes הוא התאום מוכוון־הבתים של eval על מחרוזת. הוא מקבל EXPR (או את $_ כאשר EXPR מושמט), מתייחס למחרוזת כזרם בתים גולמי, ומפענח אותה כקוד מקור של Perl. הפענוח מבודד מפרגמת use utf8 של הקורא: כללי הקידוד שהמחרוזת עצמה מצהירה הם הקובעים. יש להישען עליו כאשר הקוד שעומדים להדר נקרא מהדיסק, מהחוט, או משלב build, ונדרש שהמפענח יראה בדיוק את הבתים שנמסרו לו.
תקציר#
evalbytes EXPR
evalbytes
CORE::evalbytes EXPR # when the feature is not enabled
מה מקבלים בחזרה#
בהקשר סקלר, ערך הביטוי האחרון שהוערך; בהקשר רשימה, רשימה. בשגיאת הידור או זמן ריצה, undef (או רשימה ריקה) ו־$@ נקבע להודעת השגיאה; $@ הוא המחרוזת הריקה בהצלחה. צורת ההחזרה תואמת בדיוק את eval על מחרוזת - ההבדל היחיד הוא איך טקסט המקור עצמו מפוענח.
my $result = evalbytes $source;
die $@ if $@;
כיצד הוא שונה מ־eval על מחרוזת#
שתי התנהגויות קונקרטיות מבדילות את evalbytes מ־eval EXPR:
המקור מפוענח כבתים. כל אוקטט במחרוזת הוא תו קלט נפרד ל־lexer, ללא תלות בכך שהמחרוזת מסומנת פנימית כ־
utf8. רצף UTF-8 רב־בתים במקור מופיע ל־parser כבתים הבודדים, לא כנקודת הקוד המפוענחת.נקודות קוד מעל 255 הן שגיאה קשה. אם המחרוזת מכילה תו כלשהו שערכו הסידורי עולה על
0xFF, היא לא יכולה להיות זרם בתים וההידור נכשל עםWide character in evalמאוחסן ב־$@. יש להוריד את הקידוד עםutf8::encodeתחילה אם המקור מחזיק כעת טקסט מפוענח.
use utf8 ו־no utf8 בתוך הקוד המוערך פועלים כרגיל: הפרגמה מופעלת ברגע שה־parser מגיע אליה ומשפיעה על שאר ההידור הזה. המסגרת החיצונית של המקור היא זו הקבועה לבתים, לא מה שהמקור עצמו מצהיר.
הפעלת השם ללא CORE::#
evalbytes שמור מאחורי שער תכונה. כדי לקרוא לו כ־bareword:
use feature 'evalbytes';
הצהרת use v5.16 (או גבוהה יותר) מפעילה את תכונת evalbytes באופן אוטומטי, יחד עם שאר חבילת התכונות :5.16. ללא אחד מהשניים, השם הלא מוסמך אינו מזוהה ויש לכתוב CORE::evalbytes במפורש - שימושי בתוך קוד שנוצר אוטומטית או one-liners שאינם נושאים הצהרת גרסה.
use v5.16;
my $n = evalbytes '1 + 2'; # 3
# no feature, no version bundle:
my $n = CORE::evalbytes '1 + 2'; # 3
מצב גלובלי שהוא נוגע בו#
$@- מאופס לפני ההידור, ואז נקבע להודעת השגיאה בכישלון או למחרוזת הריקה בהצלחה. אותו חוזה כמוeval.$_- נקרא כטקסט המקור כאשרEXPRמושמט.
מסנני מקור המופעלים בתוך הקוד המוערך חלים על הקוד עצמו, בדיוק כפי שהיו חלים בתוך eval על מחרוזת. המסנן רואה את אותם בתים שה־parser רואה.
דוגמאות#
הערכת מחרוזת בתים ליטרלית - ללא הפתעות, ללא החלטות קידוד:
use feature 'evalbytes';
my $n = evalbytes 'my $x = 40; $x + 2'; # 42
הערכת מקור שנקרא מקובץ הידוע כמקודד UTF-8 אך הפרגמה המוצהרת בתוך המקור היא זו שאמורה לשלוט בפענוח:
use feature 'evalbytes';
open my $fh, '<:raw', 'script.pl' or die $!;
my $src = do { local $/; <$fh> };
my @values = evalbytes $src;
die "compile failed: $@" if $@;
קריאה עם :raw שומרת את $src כמחרוזת בתים. לאחר מכן evalbytes מזין את הבתים האלה ל־parser כפשוטם; שורת use utf8; בראש הסקריפט תעשה את העבודה שלה ברגע שה־parser מגיע אליה.
השוואה עם eval על מחרוזת כאשר לקורא יש use utf8:
use utf8;
use feature 'evalbytes';
my $src = "length('caf\xc3\xa9')"; # bytes for 'café' in UTF-8
print eval $src; # 3 (characters: c, a, f, é)
print "\n";
print evalbytes $src; # 5 (bytes: c, a, f, 0xC3, 0xA9)
print "\n";
תחת use utf8 הליטרל של הקורא עצמו "length('caf\xc3\xa9')" הוא מחרוזת תווים עבור eval, כך ש־length בתוך הקוד המוערך רואה תו é אחד. evalbytes מאלץ את אותו מקור להיות מפוענח כרצף הבתים c a f 0xC3 0xA9, כך ש־length מדווח את מספר הבתים.
תפיסת שגיאת תו רחב:
use feature 'evalbytes';
my $src = "print \x{2603}"; # contains U+2603 SNOWMAN
evalbytes $src;
warn "rejected: $@" if $@; # "Wide character in eval ..."
השמטת EXPR - המקור מגיע מ־$_:
use feature 'evalbytes';
for ('1+1', '2*3', '10-7') {
my $r = evalbytes;
print "$_ = $r\n";
}
מקרי קצה#
תו רחב במקור: כל נקודת קוד מעל
0xFFעוצרת את ההידור ומשאירהWide character in evalב־$@. יש להריץutf8::encodeעל המקור (או לקרוא את הקובץ ב־:raw) לפני הקריאה.use utf8הוא לוקלי לקוד המוערך. הוא משפיע על ליטרלי מחרוזת ומזהים בתוך הטקסט המוערך ברגע שה־parser מגיע לשורת הפרגמה. הוא אינו משנה את הדרך שבהevalbytesממסגר את המקור החיצוני - מסגור זה תמיד ”בתים“.התכונה אינה מופעלת: ללא
use feature 'evalbytes'וללא חבילתuse v5.16+, ה־bareword אינו מזוהה. יש לכתובCORE::evalbytesכדי לעקוף את שער התכונה.evalbytesללא ארגומנט ועם$_לא־מוגדר: מהדר מחרוזת ריקה, מה שמצליח ומחזירundefבהקשר סקלר, רשימה ריקה בהקשר רשימה, עם$@ריק.מסנני מקור בתוך הקוד המוערך רואים את זרם הבתים. מסנן שמצפה לתווים מפוענחים יתנהג לא נכון; יש לכתוב מסננים עבור
evalbytesבמונחי בתים.לקסיקליים ומצב חבילה: אותם כללים כמו
evalעל מחרוזת. הקוד המוערך חולק את החבילה הנוכחית של הקורא ורואה את המשתנים הלקסיקליים בתחום של הקורא; משתניmyמשלו נעלמים כשה־eval מסתיים.dieבתוךevalbytes: נתפס באותה דרך כמו עבורeval. הערך שנזרק נוחת ב־$@; הביצוע ממשיך לאחר קריאתevalbytes.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
eval- המקבילה במצב תווים; מפענחתEXPRלפי מסגור Unicode של הקורא, כך ש־use utf8בקורא משנה כיצד המקור מפורשdie- זריקת חריגה מתוך קוד מוערך; קובע את$@בדיוק כמו כל שגיאת זמן ריצה אחרתdo- הידור והרצה של קובץ; לוקח את המקור שלו מהדיסק ולא ממחרוזת, ואינו מושפע ממסגורutf8של הקוראrequire- טעינת והידור קובץ פעם אחת; הכלי הסטנדרטי כאשר המקור נמצא בדיסק ואמור לרוץ רק בהפניה ראשונהutf8- הפרגמה השולטת בסמנטיקת תווים מול בתים של ליטרלי מחרוזת;evalbytesקיים בדיוק כדי לקבע את המסגור החיצוני לבתים ללא תלות בפרגמה זו$@- חריץ השגיאה המאוכלס בכישלוןevalbytes, מאופס בהצלחה