كيف يتم تنفيذ براغمات بيرل ذات النطاق المعجمي؟
-
13-12-2019 - |
سؤال
البراغماتية، مثل autodie
, ، وفقًا للمستندات، يتم تحديد نطاقها معجميًا.
{
use autodie;
..
..
}
# Can die here
هل ينطبق هذا على جميع الوحدات المحملة بـ use
؟بقدر ما أعرف، use
هو تقريبا نفس:
BEGIN {
require autodie;
autodie->import(LIST);
}
BEGIN
يحدث في وقت الترجمة، ولا يتم تحديد نطاق الطلب بشكل معجمي.فكيف الحال autodie
على علم بنطاقها؟
المحلول
الجواب القصير هو أن النطاق المعجمي وحدات عملية مكتوبة بشكل صريح لتتصرف بهذه الطريقة، وتستخدم المتغيرات الداخلية السحرية $^H
و %^H
أثناء وقت الترجمة لتمكين الميزات وتعطيلها.
يلعب المترجم دوره من خلال توطين هذه المتغيرات ضمنيًا بحيث تتم استعادة قيمتها في نهاية تجميع كتلة التعليمات البرمجية إلى ما كانت عليه في البداية.وبهذه الطريقة فإنه يوفر أساس الدلالات المعجمية.
في الأصل فقط $^H
المتغير كان متاحايحتوي على قناع بت يحدد خيارات المترجم المتوفرة في أي وقت أثناء التجميع.وبسبب ذلك، فإن البراغما المعجمية الوحيدة التي يمكن كتابتها هي تلك التي تلاعبت بالمجموعة المحددة من البتات السحرية في $^H
.
في وقت لاحق %^H
تم تقديم التجزئة، ويمكن لأي براغما الآن تخزين القيم في هذا التجزئة بمفاتيح تبدأ باسم البراغما.نظرًا لأن المترجم يقوم بترجمة التجزئة بنفس طريقة العددية، فيمكن لأي براغما تخزين معلومات الحالة المحددة تلقائيًا هنا.
ال autodie
لا تتعامل الوحدة النمطية مع أي من هذه المتغيرات، ولكنها تصنف فئات فرعية Fatal
الوحدة التي تقوم بكل العمل الشاق.يستخدم %^H
لتتبع العوامل التي أصبحت قاتلة، وتعتمد على المترجم لتجاهل هذه المعلومات في نهاية الكتلة.
نصائح أخرى
من طريقة الاستيراد Fatal.pm
وهي الواجهة الخلفية لـ autodie
, ، استمتع بهذا:
# Dark magic to have autodie work under 5.8
# Copied from namespace::clean, that copied it from
# autobox, that found it on an ancient scroll written
# in blood.
# This magic bit causes %^H to be lexically scoped.
$^H |= 0x020000;
لذا فإن الإجابة هي أن هناك حقًا طريقة لجعل وارداتك على دراية بنطاقها المعجمي، ولكنها متشابكة بشدة مع شجاعة لغة Perl وليس المقصود من المبرمجين العاديين استخدامها.
ليست كذلك require
هذا ممتع؛هذا ما تفعله البراغما import
.
معظم (كل؟) استخدام البراجما $^H
أو %^H
.يقوم المحلل اللغوي بترجمة هذه العناصر إلى النطاق الذي يتم تحليله، مما يعني أنه يعيدها إلى القيمة التي كانت عليها من قبل
يأخذ حازم, ، على سبيل المثال.إنه import
يعدل $^H
. $^H
يحتوي على سلسلة من العلامات التي ترشد المترجم إلى كيفية التصرف.
$ perl -e'
BEGIN { printf "%04X\n", $^H }
{
use strict;
BEGIN { printf "%04X\n", $^H }
}
BEGIN { printf "%04X\n", $^H }
'
0100
0702
0100
$^H
محجوز لاستخدام لغة Perl، ولكنه مترجم بالمثل %^H
متاح للاستخدام العام.على سبيل المثال، ميزة::qw_comment يتم ربطه بالمحلل مرة واحدة، عندما يتم تحميله بواسطة require
, ، لكنه لا يفعل أي شيء إلا إذا $^H{'feature::qw_comments::'}
صحيح.انها استيراد ما يعادل
sub import { $^H{'feature::qw_comments::'} = 1; }