Scroll to navigation

PERLDATA(1) دليل مرجع مبرمجي بيرل PERLDATA(1)

الاسم

perldata - أنواع بيانات بيرل

الوصف

أسماء المتغيرات

تمتلك بيرل ثلاثة أنواع بيانات مدمجة: السكالار (scalars)، ومصفوفات السكالار، والمصفوفات الترابطية للسكالار، المعروفة باسم "hashes". السكالار هو سلسلة نصية واحدة (بأي حجم، محدودة فقط بالذاكرة المتاحة)، أو رقم، أو مرجع لشيء ما (سيُنقش في perlref). المصفوفات العادية هي قوائم مرتبة من السكالار مفهرسة بالأرقام، بدءًا من 0. الـ Hashes هي مجموعات غير مرتبة من قيم السكالار مفهرسة بمفتاح نصي مرتبط بها.

يُشار إلى القيم عادةً بالاسم، أو من خلال مرجع مسمى. يخبرك الحرف الأول من الاسم بنوع بنية البيانات التي يشير إليها. يسمى هذا الحرف "sigil". يخبرك باقي الاسم بالقيمة المعينة التي يشير إليها. عادةً ما يكون هذا الاسم عبارة عن معرف واحد، أي سلسلة تبدأ بحرف أو شرطة سفلية، وتحتوي على حروف وشرطات سفلية وأرقام. في بعض الحالات، قد يكون سلسلة من المعرفات، تفصل بينها "::" (أو بواسطة "'" المهجورة)؛ تُفسر جميعها باستثناء الأخير كأوامر حزم، لتحديد مساحة الأسماء التي يجب البحث فيها عن المعرف النهائي (انظر "Packages" في perlmod لمزيد من التفاصيل). لمناقشة أكثر عمقاً حول المعرفات، انظر "Identifier parsing". من الممكن استبدال المعرف البسيط بتعبير ينتج مرجعاً للقيمة في وقت التشغيل. وُصف هذا بمزيد من التفصيل أدناه وفي perlref. من القانوني، ولكن لا يُنصح به، فصل sigil الخاص بالمتغير عن اسمه بمسافة و/أو أحرف جدولة.

تمتلك بيرل أيضاً متغيراتها المدمجة الخاصة التي لا تتبع أسماؤها هذه القواعد. لها أسماء غريبة حتى لا تتصادم عرضاً مع أحد متغيراتك العادية. تُحفظ السلاسل التي تطابق الأجزاء الموجودة بين قوسين من تعبير نمطي تحت أسماء تحتوي فقط على أرقام بعد "$" (انظر perlop و perlre). بالإضافة إلى ذلك، تمتلك العديد من المتغيرات الخاصة التي توفر نوافذ على العمل الداخلي لبيرل أسماءً تحتوي على علامات ترقيم. وُثقت هذه في perlvar.

تُسمى القيم العددية دائماً بـ sigil ‏'$'، حتى عند الإشارة إلى قيمة عددية هي جزء من مصفوفة أو هاش. يعمل الرمز '$' دلالياً مثل أداة التعريف "الـ" في العربية من حيث أنه يشير إلى توقع قيمة واحدة.

    $days               # قيمة السكالار البسيطة "days"
    $days[28]           # العنصر 29 في المصفوفة @days
    $days{'Feb'}        # القيمة المقابلة لـ 'Feb' من الـ hash %days
    $#days              # الفهرس الأخير للمصفوفة @days

يُشار إلى المصفوفات الكاملة (وشرائح المصفوفات والهاش) بـ sigil ‏'@'، الذي يعمل تماماً مثل أسماء الإشارة للجمع، من حيث أنه يشير إلى توقع قيم متعددة.

    @days               # ($days[0], $days[1],... $days[n])
    @days[3,4,5]        # تكافئ ($days[3],$days[4],$days[5])
    @days{'a','c'}      # تكافئ ($days{'a'},$days{'c'})

يُشار إلى الهاش بالكامل بـ sigil ‏'%':

    %days               # (مفتاح1، قيمة1، مفتاح2، قيمة2 ...)

بالإضافة إلى ذلك، تُسمى الروتينات الفرعية بـ sigil ابتدائي '&'، رغم أن هذا اختياري عندما لا يكون هناك لبس. يمكن تسمية إدخالات جدول الرموز بـ '*' ابتدائي، لكنك لا تهتم حقاً بذلك بعد (هذا إذا اهتممت يوماً :-).

لكل نوع متغير مساحة أسماء خاصة به، وكذلك لعدة معرفات غير متغيرة. وهذا يعني أنه يمكنك، دون خوف من التعارض، استخدام الاسم نفسه لمتغير عددي، أو مصفوفة، أو هاش - أو، في هذا الصدد، لمقبض ملف، أو مقبض دليل، أو اسم روتين فرعي، أو اسم تنسيق، أو وسم. وهذا يعني أن $foo و @foo متغيران مختلفان. ويعني أيضاً أن $foo[1] جزء من @foo، وليس جزءاً من $foo. قد يبدو هذا غريباً بعض الشيء، لكن هذا لا بأس به، لأنه غريب بالفعل.

نظراً لأن مراجع المتغيرات تبدأ دائماً بـ sigils ‏'$'، أو '@'، أو '%'، فإن الكلمات "المحجوزة" ليست في الواقع محجوزة فيما يتعلق بأسماء المتغيرات. ومع ذلك، فهي محجوزة فيما يتعلق باللصائق ومقابض الملفات، التي لا تحتوي على حرف خاص ابتدائي. لا يمكنك امتلاك مقبض ملف باسم "log"، على سبيل المثال. تلميح: يمكنك قول "open(LOG,'logfile')" بدلاً من "open(log,'logfile')". كما أن استخدام مقابض الملفات بأحرف كبيرة يحسن قابلية القراءة ويحميك من التعارض مع الكلمات المحجوزة المستقبلية. حالة الأحرف مهمة -- "FOO" و "Foo" و "foo" كلها أسماء مختلفة. الأسماء التي تبدأ بحرف أو شرطة سفلية قد تحتوي أيضاً على أرقام وشرطات سفلية.

من الممكن استبدال مثل هذا الاسم الأبجدي الرقمي بتعبير يعيد مرجعًا للنوع المناسب. لوصف هذا، راجع perlref.

الأسماء التي تبدأ برقم قد تحتوي فقط على مزيد من الأرقام. الأسماء التي لا تبدأ بحرف أو شرطة سفلية أو رقم أو علامة أقحوان تقتصر على حرف واحد، مثل $% أو $$. (معظم هذه الأسماء المكونة من حرف واحد لها أهمية محددة مسبقاً في بيرل. على سبيل المثال، $$ هو معرف العملية الحالي. وجميع هذه الأسماء محجوزة لاستخدام بيرل المحتمل.)

تحليل المعرف

حتى بيرل 5.18، كانت القواعد الفعلية لما يعد معرفاً صالحاً غامضة قليلاً. ومع ذلك، بشكل عام، أي شيء مُعرّف هنا يجب أن يعمل في الإصدارات السابقة من بيرل، بينما العكس -- الحالات الحدية التي تعمل في الإصدارات السابقة ولكنها ليست مُعرّفة هنا -- ربما لن تعمل في الإصدارات الأحدث. كملاحظة جانبية رئيسة، يرجى ملاحظة أن ما يلي ينطبق فقط على معرفات الكلمات المجردة (bareword) كما توجد في كود مصدر بيرل، وليس المعرفات المقدمة من خلال المراجع الرمزية، التي لديها قيود أقل بكثير. إذا كنت تعمل تحت تأثير "use utf8;"، فتطبق القواعد التالية:

    / (?[ ( \p{Word} & \p{XID_Start} ) + [_] ])
      (?[ ( \p{Word} & \p{XID_Continue} ) ]) *    /x

أي، حرف "بداية" متبوع بأي عدد من حروف "الاستمرار". تطلب بيرل أن يطابق كل حرف في المعرف أيضًا "\w" (هذا يمنع بعض الحالات الإشكالية)؛ كما تقبل بيرل بالإضافة إلى ذلك أسماء المعرفات التي تبدأ بشرطة سفلية.

إذا لم يكن تحت "use utf8"، فسيُعامل المصدر على أنه ASCII + 128 حرفًا عامًا إضافيًا، ويجب أن تطابق المعرفات

    / (?aa) (?!\d) \w+ /x

أي، أي حرف كلمة في نطاق ASCII، طالما أن الحرف الأول ليس رقمًا.

يوجد فاصل حزم واحد في بيرل: النقطتان المزدوجتان ("::"). يمكن للمعرفات العادية أن تبدأ أو تنتهي بنقطتين مزدوجتين، ويمكن أن تحتوي على عدة أجزاء مفصولة بنقطتين مزدوجتين.

سابقاً كان بإمكانك استخدام "'" كفاصل حزم، وُزيل هذا في بيرل 5.42.

بالإضافة إلى ذلك، إذا كان المعرف مسبوقاً بـ sigil -- أي إذا كان المعرف جزءاً من اسم متغير -- فيمكن اختيارياً وضعه بين أقواس مجعدة. على سبيل المثال، "${name}"، ‏"@{bigcats}"، ‏"%{pizza_toppings}".

بتجميعها معًا، يصبح القواعد النحوية لمطابقة معرف أساسي هي

 /
  (?(DEFINE)
      (?<variable>
          (?&sigil)
          (?:
                  (?&normal_identifier)
              |   \{ \s* (?&normal_identifier) \s* \}
          )
      )
      (?<normal_identifier>
          (?: :: )*
           (?&basic_identifier)
           (?: (?= :: ) (?&normal_identifier) )?
          (?: :: )*
      )
      (?<basic_identifier>
        # هل use utf8 مفعل؟
          (?(?{ (caller(0))[8] & $utf8::hint_bits })
              (?&Perl_XIDS) (?&Perl_XIDC)*
            | (?aa) (?!\d) \w+
          )
      )
      (?<sigil> \$\# | [&*\$\@%])
      (?<Perl_XIDS> (?[ ( \p{Word} & \p{XID_Start} ) + [_] ]) )
      (?<Perl_XIDC> (?[ \p{Word} & \p{XID_Continue} ]) )
  )
 /x

وفي الوقت نفسه، لا تتبع المعرفات الخاصة القواعد المذكورة أعلاه؛ ففي الغالب، تمتلك جميع المعرفات في هذه الفئة معنى خاصاً تمنحه بيرل. ولأن لها قواعد تحليل خاصة، فلا يمكن عموماً جعلها مؤهلة بالكامل. وتأتي في ستة أشكال (لكن لا تستخدم الشكلين 5 و 6):

1.
رمز (sigil)، متبوع حصراً بأرقام تطابق "\p{POSIX_Digit}"، مثل $0، أو $1، أو $10000.
2.
sigil متبوع بحرف واحد يطابق خاصية "\p{POSIX_Punct}"، مثل $! أو "%+"، باستثناء الحرف "{" الذي لا يعمل.
3.
رمز، متبوع بعلامة أقحوان (caret) وأي حرف من الأحرف "[][A-Z^_?\]"، مثل $^V أو $^].
4.
على غرار ما سبق، رمز متبوع بنص bareword داخل أقواس مجعدة، حيث يكون الحرف الأول علامة أقحوان. الحرف التالي هو أي واحد من الأحرف "[][A-Z^_?\]"، متبوعًا بأحرف كلمات ASCII. مثال على ذلك هو "${^GLOBAL_PHASE}".
5.
رمز متبوع بأي حرف واحد في النطاق "[\xA1-\xAC\xAE-\xFF]" عندما لا يكون تحت "use utf8". (تحت "use utf8"، تنطبق قواعد المعرفات العادية المذكورة سابقًا في هذا القسم). مُنع استخدام الأحرف غير الرسومية (عناصر تحكم C1، والمسافة غير المنقسمة، والواصلة الناعمة) منذ الإصدار v5.26.0. استخدام الأحرف الأخرى غير حكيم، حيث إنها جميعًا محجوزة ليكون لها معنى خاص لبيرل، ولا يوجد لأي منها حاليًا معنى خاص، رغم أن هذا قد يتغير دون إشعار.

لاحظ أن مضمن هذا الشكل هو وجود معرفات قانونية فقط تحت "use utf8"، والعكس صحيح، على سبيل المثال المعرف $état قانوني تحت "use utf8"، ولكن بخلاف ذلك يُعتبر المتغير المكون من حرف واحد متبوعاً بالكلمة المجردة "tat"، وهذا المزيج يعد خطأً في الصيغة.

6.
هذا مزيج من الشكلين السابقين. يكون صالحًا فقط عندما لا يكون تحت "use utf8" (تنطبق قواعد المعرفات العادية عندما تكون تحت "use utf8"). الشكل هو رمز متبوع بنص داخل أقواس مجعدة، حيث يكون الحرف الأول أيًا من الأحرف في النطاق "[\x80-\xFF]" متبوعًا بأحرف كلمات ASCII حتى قوس الإغلاق.

تنطبق نفس التنبيهات الخاصة بالشكل السابق: لم تعد الأحرف غير الرسومية مسموحة مع "use utf8"، وليس من الحكمة استخدام هذا الشكل على الإطلاق، كما أن استخدام utf8 يحدث فرقًا كبيرًا.

قبل الإصدار v5.24 من بيرل، كانت أحرف تحكم ASCII غير الرسومية مسموحة أيضًا في بعض الحالات؛ وقد تم هجر هذا منذ الإصدار v5.20.

السياق

يعتمد تفسير العمليات والقيم في بيرل أحيانًا على متطلبات السياق المحيط بالعملية أو القيمة. هناك سياقان رئيسان: سياق القائمة وسياق السكالار. تعيد عمليات معينة قيم قائمة في السياقات التي تطلب قائمة، وقيم سكالار في غير ذلك. إذا كان هذا ينطبق على عملية ما، فسيتم ذكره في توثيق تلك العملية. بعبارة أخرى، تقوم بيرل بتحميل عمليات معينة بشكل زائد بناءً على ما إذا كانت القيمة المعادة المتوقعة مفردة أم جمع. بعض الكلمات في اللغة الإنجليزية تعمل بهذه الطريقة، مثل "fish" و "sheep".

بشكل متبادل، توفر العملية إما سياق سكالار أو سياق قائمة لكل من وسائطها. على سبيل المثال، إذا قلت

    int( <STDIN> )

فإن عملية العدد الصحيح توفر سياق سكالار لعامل التشغيل <>، الذي يستجيب بقراءة سطر واحد من STDIN وتمريره مرة أخرى إلى عملية العدد الصحيح، والتي ستجد بعد ذلك القيمة الصحيحة لذلك السطر وتعيدها. أما إذا قلت

    sort( <STDIN> )

فإن عملية الفرز (sort) توفر سياق قائمة لـ <>، والذي سيستمر في قراءة كل سطر متاح حتى نهاية الملف، ويمرر تلك القائمة من السطور مرة أخرى إلى روتين الفرز، الذي سيقوم بعد ذلك بفرز تلك السطور وإعادتها كقائمة إلى أيًا كان سياق الفرز.

التعيين (Assignment) خاص قليلاً لأنه يستخدم وسيطه الأيسر لتحديد سياق الوسيط الأيمن. التعيين لسكالار يقيم الجانب الأيمن في سياق سكالار، بينما التعيين لمصفوفة أو hash يقيم الجانب الأيمن في سياق قائمة. التعيين لقائمة (أو شريحة، وهي مجرد قائمة على أي حال) يقيم أيضًا الجانب الأيمن في سياق قائمة.

عندما تستخدم "use warnings" أو خيار سطر الأوامر -w لبيرل، قد ترى تحذيرات حول استخدامات عديمة الفائدة للثوابت أو الدوال في "سياق باطل" (void context). السياق الباطل يعني ببساطة أنه وُبذلت القيمة، مثل عبارة تحتوي فقط على ""fred";" أو "getpwuid(0);". ولا يزال يُحسب كسياق عددي للدوال التي تهتم بما إذا كان قد وُستدعيت في سياق قائمة أم لا.

قد تختار الروتينات الفرعية التي يحددها المستخدم الاهتمام بما إذا كان قد وُستدعيت في سياق باطل أو عددي أو قائمة. ومع ذلك، لا تحتاج معظم الروتينات الفرعية إلى الاهتمام بذلك. وذلك لأن كلاً من المقادير العددية والقوائم تُدمج آلياً في القوائم. انظر "wantarray" في perlfunc لمعرفة كيفية تمييز سياق استدعاء دالتك ديناميكياً.

قيم السكالار

جميع البيانات في بيرل هي سكالار، أو مصفوفة من السكالار، أو hash من السكالار. يمكن أن يحتوي السكالار على قيمة واحدة بأي من ثلاث نكهات مختلفة: رقم، أو سلسلة نصية، أو مرجع. بشكل عام، التحويل من شكل إلى آخر يكون شفافًا. على الرغم من أن السكالار قد لا يحمل قيمًا متعددة بشكل مباشر، إلا أنه قد يحتوي على مرجع لمصفوفة أو hash يحتوي بدوره على قيم متعددة.

المقادير العددية ليست بالضرورة شيئاً واحداً أو آخر. لا يوجد مكان للتصريح عن متغير عددي بأنه من نوع "سلسلة" أو "رقم" أو "مرجع" أو أي شيء آخر. بسبب التحويل الآلي للمقادير العددية، لا تحتاج العمليات التي تعيد مقادير عددية إلى الاهتمام (وفي الواقع، لا يمكنها الاهتمام) بما إذا كان المستدعِي يبحث عن سلسلة أو رقم أو مرجع. بيرل لغة متعددة الأشكال سياقياً يمكن أن تكون مقاديرها العددية سلاسل أو أرقاماً أو مراجع (بما في ذلك الكائنات). على الرغم من أن السلاسل والأرقام تُعتبر الشيء نفسه تقريباً لجميع الأغراض تقريباً، إلا أن المراجع هي مؤشرات قوية النوع، غير قابلة للتحويل، مع عد مراجع مدمج واستدعاء مدمر.

تُفسر قيمة السكالار على أنها خطأ (FALSE) بالمعنى البولياني إذا كانت غير معرفة، أو كانت السلسلة الفارغة، أو الرقم 0 (أو ما يعادلها نصيًا "0")، وتكون صواب (TRUE) إذا كانت أي شيء آخر. السياق البولياني هو مجرد نوع خاص من سياق السكالار حيث لا يتم إجراء أي تحويل إلى نص أو رقم. نفي القيمة الصحيحة بواسطة "!" أو "not" يعيد قيمة خطأ خاصة. عند تقييمها كسلسلة نصية تُعامل كـ ""، ولكن كرقم، تُعامل كـ 0. معظم معاملات بيرل التي تعيد صواب أو خطأ تتصرف بهذه الطريقة.

هناك في الواقع نوعان من السلاسل النصية الخالية (يُشار إليها أحيانًا باسم السلاسل "الفارغة")، واحدة معرفة وأخرى غير معرفة. النسخة المعرفة هي مجرد سلسلة بطول صفر، مثل "". النسخة غير المعرفة هي القيمة التي تشير إلى عدم وجود قيمة حقيقية لشيء ما، كما هو الحال عند حدوث خطأ، أو في نهاية ملف، أو عند الإشارة إلى متغير غير مهيأ أو عنصر في مصفوفة أو hash. رغم أنه في إصدارات بيرل المبكرة، كان بإمكان السكالار غير المعرف أن يصبح معرفًا عند استخدامه لأول مرة في مكان يتوقع قيمة معرفة، إلا أن هذا لم يعد يحدث باستثناء حالات نادرة من autovivification كما هو موضح في perlref. يمكنك استخدام معامل defined() لتحديد ما إذا كانت قيمة السكالار معرفة (ليس لهذا معنى في المصفوفات أو الـ hashes)، ومعامل undef() لإنتاج قيمة غير معرفة.

لمعرفة ما إذا كانت سلسلة معينة رقماً صالحاً غير صفري، يكفي أحياناً اختبارها مقابل 0 الرقمي وأيضاً "0" اللفظي (رغم أن هذا سيسبب ضجيجاً إذا كانت التحذيرات مفعلة). وذلك لأن السلاسل التي ليست أرقاماً تُحسب كـ 0، تماماً كما هو الحال في awk:

    if ($str == 0 && $str ne "0")  {
        warn "هذا لا يبدو وكأنه رقم";
    }

قد تكون هذه الطريقة هي الأفضل لأنك بخلاف ذلك لن تعامل تدوينات IEEE مثل "NaN" أو "Infinity" بشكل صحيح. في أوقات أخرى، قد تفضل تحديد ما إذا كان يمكن استخدام بيانات السلسلة عددياً عن طريق استدعاء دالة POSIX::strtod() أو بفحص سلسلتك بتعبير نمطي (كما هو موثق في perlre).

    warn "يحتوي على غير أرقام"        if     /\D/;
    warn "ليس رقما طبيعيا" unless /^\d+$/;             # يرفض -3
    warn "ليس عددا صحيحا"       unless /^-?\d+$/;           # يرفض +3
    warn "ليس عددا صحيحا"       unless /^[+-]?\d+$/;
    warn "ليس رقما عشريا" unless /^-?\d+\.?\d*$/;     # يرفض .2
    warn "ليس رقما عشريا" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
    warn "ليس عددا عائما بلغة C"
        unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;

طول المصفوفة هو قيمة عددية. يمكنك العثور على طول المصفوفة @days من خلال تقييم $#days، كما في csh. ومع ذلك، هذا ليس طول المصفوفة؛ إنه دليل العنصر الأخير، وهو قيمة مختلفة لأن هناك عادة عنصراً في المرتبة 0. التعيين لـ $#days يغير بالفعل طول المصفوفة. تقصير المصفوفة بهذه الطريقة يدمر القيم البينية. إطالة المصفوفة التي وُقصرت سابقاً لا يستعيد القيم التي كانت في تلك العناصر.

يمكنك أيضًا كسب قدر ضئيل من الكفاءة من خلال تمديد مصفوفة مسبقًا ستصبح كبيرة. يمكنك أيضًا تمديد مصفوفة من خلال التعيين لعنصر يقع خارج نهاية المصفوفة. يمكنك اقتطاع مصفوفة لتصبح لا شيء عن طريق تعيين القائمة الفارغة () لها. ما يلي متكافئ:

    @whatever = ();
    $#whatever = -1;

إذا قمت بتقييم مصفوفة في سياق سكالار، فإنها تعيد طول المصفوفة. (لاحظ أن هذا لا ينطبق على القوائم، التي تعيد القيمة الأخيرة، مثل معامل الفاصلة في لغة C، ولا على الدوال المدمجة، التي تعيد ما تشاء إعادته). ما يلي صحيح دائمًا:

    scalar(@whatever) == $#whatever + 1;

يختار بعض المبرمجين استخدام تحويل صريح حتى لا يتركوا مجالاً للشك:

    $element_count = scalar(@whatever);

إذا قمت بتقييم hash في سياق سكالار، فإنه يعيد قيمة خطأ إذا كان الـ hash فارغًا. إذا كان هناك أي أزواج مفتاح/قيمة، فإنه يعيد قيمة صواب. يعتمد التعريف الأكثر دقة على الإصدار.

قبل بيرل 5.25 كانت القيمة المعادة عبارة عن سلسلة تتكون من عدد السلال المستخدمة وعدد السلال المخصصة، مفصولة بشرطة مائلة. هذا مفيد فقط لمعرفة ما إذا كانت خوارزمية الهاش الداخلية لبيرل تعمل بشكل ضعيف على مجموعة بياناتك. على سبيل المثال، تضع 10,000 شيء في هاش، لكن تقييم %HASH في سياق عددي يكشف عن "1/16"، مما يعني أن واحدة فقط من أصل ست عشرة سلة قد وُلمست، ويُفترض أنها تحتوي على جميع العناصر الـ 10,000 الخاصة بك. ليس من المفترض أن يحدث هذا.

بدءًا من الإصدار 5.25 من بيرل، غُيرت القيمة المعادة لتكون عدد المفاتيح في الـ hash. إذا كنت بحاجة للوصول إلى السلوك القديم، يمكنك استخدام Hash::Util::bucket_ratio() بدلاً من ذلك.

إذا قُيمت دالة هاش مربوطة (tied hash) في سياق عددي (scalar context)، تُستدعى الوسيلة "SCALAR" (مع الرجوع إلى "FIRSTKEY" في حال الإخفاق).

يمكنك حجز مساحة مسبقًا لدالة هاش عبر التعيين للدالة keys(). يؤدي هذا إلى تقريب الدلاء (buckets) المخصصة إلى القوة التالية للعدد اثنين:

    keys(%users) = 1000;                # حجز 1024 دلوًا

منشئات القيمة العددية

تُحدد الأرقام الحرفية بأي من تنسيقات الفاصلة العائمة أو الأعداد الصحيحة التالية:

 12345
 12345.67
 .23E-10             # رقم صغير جداً
 3.14_15_92          # رقم مهم جداً
 4_294_967_296       # شرطة سفلية للوضوح
 0xff                # سداسي عشر
 0xdead_beef         # مزيد من السداسي عشر
 0377                # ثماني (أرقام فقط، يبدأ بـ 0)
 0o12_345            # ثماني بديل (قُدم في بيرل 5.33.5)
 0b011011            # ثنائي
 0x1.999ap-4         # فاصلة عائمة سداسية عشرية (الحرف 'p' مطلوب)
 07.65p2             # فاصلة عائمة ثمانية (الحرف 'p' مطلوب)
 0o7.65p2            # فاصلة عائمة ثمانية بديلة
 0b101.01p-1         # فاصلة عائمة ثنائية (الحرف 'p' مطلوب)

يُسمح لك باستخدام الشرطات السفلية في الأرقام الحرفية بين الأرقام لسهولة القراءة (ولكن ليس شرطات سفلية متعددة متتالية: "23__500" غير قانوني؛ بينما "23_500" قانوني). يمكنك، على سبيل المثال، تجميع الأرقام الثنائية في مجموعات من ثلاثة (كما في معامل الوضع بأسلوب يونكس مثل 0b110_100_100) أو أربعة (لتمثيل النيبلات nibbles، كما في 0b1010_0110) أو في مجموعات أخرى.

تُحدد السلاسل الحرفية عادةً إما بعلامات اقتباس مفردة أو مزدوجة. وهي تعمل بشكل مشابه جدًا لعلامات الاقتباس في صدفات يونكس القياسية: تخضع السلاسل الحرفية ذات الاقتباس المزدوج لتبديل المتغيرات والشرطة المائلة العكسية؛ بينما لا تخضع السلاسل ذات الاقتباس المفرد لذلك (باستثناء "\'" و "\\"). تنطبق قواعد الشرطة المائلة العكسية المعتادة بأسلوب C لإنشاء محارف مثل السطر الجديد، والتبويب، وما إلى ذلك، بالإضافة إلى بعض الأشكال الأكثر غرابة. انظر "Quote and Quote-like Operators" في perlop للحصول على قائمة.

التمثيلات السداسية عشرية أو الثمانية أو الثنائية في السلاسل النصية (مثل '0xff') لا تُحول آلياً إلى تمثيلها الصحيح. تقوم الدوال hex() و oct() بهذه التحويلات من أجلك. انظر "hex" في perlfunc و "oct" في perlfunc لمزيد من التفاصيل.

يمكن أن تبدأ الفاصلة العائمة السداسية عشرية تماماً مثل الثابت السداسي عشر، ويمكن أن تتبعها جزئية سداسية عشرية كسرية اختيارية، ولكن يجب أن يتبعها "p"، وعلامة اختيارية، وقوة للرقم اثنين. التنسيق مفيد لتقديم قيم الفاصلة العائمة بدقة، وتجنب التحويلات من أو إلى الفاصلة العائمة العشرية، وبالتالي تجنب فقدان الدقة المحتمل. لاحظ أنه بينما تستخدم معظم المنصات الحالية الفاصلة العائمة IEEE 754 ذات 64 بت، لا تفعل ذلك جميعها. مصدر محتمل آخر للاختلافات (منخفضة الرتبة) هو أوضاع تقريب الفاصلة العائمة، والتي قد تختلف بين المعالجات وأنظمة التشغيل والمترجمات، والتي لا تتحكم فيها بيرل.

تستخدم أرقام الفاصلة العائمة الثمانية والثنائية التنسيق نفسه لأرقام الفاصلة العائمة السداسية عشرية، ولكنها تقتصر على الأرقام الثنائية والثمانية، على التوالي.

يمكنك أيضًا تضمين أسطر جديدة مباشرة في سلاسلك النصية، أي يمكن أن تنتهي في سطر مختلف عن الذي بدأت فيه. هذا أمر جيد، ولكن إذا نسيت علامة الاقتباس الختامية، فلن يُبلغ عن الخطأ حتى تجد Perl سطرًا آخر يحتوي على محرف الاقتباس، والذي قد يكون بعيدًا جدًا في السكربت. يقتصر تبديل المتغيرات داخل السلاسل النصية على المتغيرات العددية، والمصفوفات، وشرائح المصفوفات أو الهاش. (بمعنى آخر، الأسماء التي تبدأ بـ $ أو @، متبوعة بتعبير اختياري بين أقواس كمؤشر سفلي subscript.) مقطع الكود التالي يطبع "The price is $100."

    $Price = '$100';    # لا يستوفى
    print "The price is $Price.\n";     # يستوفى

لا يوجد استيفاء مزدوج في Perl، لذا تترك $100 كما هي.

مبدئيًا، تستخدم أرقام الفاصلة العائمة المستبدلة داخل السلاسل النصية النقطة (".") كفاصل عشري. إذا كان "use locale" قيد التنفيذ، واستُدعيت POSIX::setlocale()، فإن المحرف المستخدم للفاصل العشري يتأثر بإعدادات LC_NUMERIC المحلية. انظر perllocale و POSIX.

أسماء المتغيرات المحددة باستخدام الأقواس المعقوفة

كما هو الحال في بعض الصدفات، يمكنك إحاطة اسم المتغير بأقواس معقوفة كعلامة تحديد لرفع اللبس بينه وبين ما يليه من أحرف وأرقام وشرطات سفلية أو نصوص أخرى. يجب عليك أيضًا القيام بذلك عند استيفاء متغير داخل سلسلة نصية لفصل اسم المتغير عن نقطتين مزدوجتين تاليتين أو فاصلة عليا، حيث ستُعامل هذه غير ذلك كفاصل حزم:

    $who = "Larry";
    print PASSWD "${who}::0:0:Superuser:/:/bin/perl\n";
    print "We use ${who}speak when ${who}'s here.\n";

بدون الأقواس المعقوفة، كانت Perl ستبحث عن المتغيرات $whospeak، و $who::0، و "$who's". المتغيران الأخيران سيكونا $0 و $s في حزمة (يُفترض) أنها غير موجودة تسمى "who".

في الواقع، يُجبر المعرف البسيط داخل هذه الأقواس المعقوفة على أن يكون سلسلة نصية، وبالمثل داخل مؤشر الهاش السفلي. لا يحتاج أي منهما إلى اقتباس. مثالنا السابق، $days{'Feb'} يمكن كتابته كـ $days{Feb} وستُفترض علامات الاقتباس آليًا. ولكن أي شيء أكثر تعقيدًا في المؤشر السفلي سيُفسر كتعبير. وهذا يعني على سبيل المثال أن "$version{2.0}++" تكافئ "$version{2}++"، وليس "$version{'2.0'}++".

توجد مشكلة مماثلة في الاستيفاء مع النص الذي يشبه تدوين الوصول إلى المصفوفة أو الهاش. وضع متغير بسيط مثل $who مباشرة أمام نص مثل "[1]" أو "{foo}" سيؤدي إلى استيفاء المتغير كوصول إلى عنصر في @who أو قيمة مخزنة في %who:

    $who = "Larry Wall";
    print "$who[1] is the father of Perl.\n";

سيحاول الوصول إلى الفهرس 1 لمصفوفة تسمى @who. مرة أخرى، استخدام الأقواس سيمنع حدوث ذلك:

    $who = "Larry Wall";
    print "${who}[1] is the father of Perl.\n";

سيُعامل بنفس طريقة

    $who = "Larry Wall";
    print $who . "[1] is the father of Perl.\n";

ينطبق هذا التدوين أيضًا على أوصاف المتغيرات الأكثر تعقيدًا، مثل الوصول إلى المصفوفة أو الهاش باستخدام المؤشرات السفلية. على سبيل المثال

    @name = qw(Larry Curly Moe);
    print "Also ${name[0]}[1] was a member\n";

بدون الأقواس، سيُحلل المثال أعلاه كمؤشر مصفوفة من مستويين في مصفوفة @name، وتحت "use strict" سينتج على الأرجح استثناءً قاتلاً، لأنه سيُحلل هكذا:

    print "Also " . $name[0][1] . " was a member\n";

وليس كما هو مقصود:

    print "Also " . $name[0] . "[1] was a member\n";

يمكن اشتقاق نتيجة مماثلة باستخدام شرطة مائلة عكسية على المحرف الأول من تدوين المؤشر السفلي أو الحزمة الذي ليس جزءًا من المتغير الذي تريد الوصول إليه. وبالتالي يمكن كتابة المثال أعلاه أيضًا:

    @name = qw(Larry Curly Moe);
    print "Also $name[0]\[1] was a member\n";

ومع ذلك، بالنسبة لبعض المتغيرات الخاصة (متغيرات علامة الإقحام متعددة المحارف)، فإن الشكل المحدد باستخدام الأقواس المعقوفة هو الطريقة الوحيدة التي يمكنك بها الإشارة إلى المتغير على الإطلاق، والطريقة الوحيدة التي يمكنك بها الوصول إلى مؤشر سفلي للمتغير عبر الاستيفاء.

تأمل المصفوفة السحرية "@{^CAPTURE}" التي يملؤها محرك التعبيرات النمطية بمحتويات جميع مخازن الالتقاط في نمط ما (انظر perlvar و perlre). الطريقة الوحيدة التي يمكنك بها الوصول إلى أحد هذه الأعضاء داخل سلسلة نصية هي عبر الشكل المحاط بأقواس (المحدد):

    "abc"=~/(.)(.)(.)/
        and print "Second buffer is ${^CAPTURE[1]}";

يكافئ

    "abc"=~/(.)(.)(.)/
        and print "Second buffer is " . ${^CAPTURE}[1];

قول "@^CAPTURE" هو خطأ في بناء الجملة، لذا يجب الإشارة إليه كـ "@{^CAPTURE}"، وللوصول إلى أحد عناصره في الكود العادي ستكتب " ${^CAPTURE}[1] ". ومع ذلك عند الاستيفاء في سلسلة نصية "${^CAPTURE}[1]" سيكون مكافئًا لـ "${^CAPTURE} . "[1]""، والذي لا يشير حتى إلى نفس المتغير! وبالتالي يجب أيضًا وضع المؤشرات السفلية داخل الأقواس: "${^CAPTURE[1]}".

يمكن استخدام الشكل المحدد باستخدام الأقواس المعقوفة مع جميع الأنواع المختلفة للوصول إلى المتغيرات، بما في ذلك شرائح المصفوفة والهاش. على سبيل المثال كود مثل التالي:

    @name = qw(Larry Curly Moe);
    local $" = " and ";
    print "My favorites were @{name[1,2]}.\n";

سيخرج

    My favorites were Curly and Moe.

فاصلة عائمة خاصة: اللانهاية (Inf) وليس رقمًا (NaN)

تتضمن قيم الفاصلة العائمة القيم الخاصة "Inf" و "NaN"، للانهاية وليس رقمًا. يمكن أن تكون اللانهاية سالبة أيضًا.

اللانهاية هي نتيجة لعمليات حسابية معينة تتجاوز نطاق الفاصلة العائمة، مثل 9**9**9. وقيمة "ليس رقمًا" هي النتيجة عندما تكون النتيجة غير محددة أو غير قابلة للتمثيل. لاحظ أنه لا يمكنك الحصول على "NaN" من بعض العمليات الشائعة "غير المحددة" أو "خارج النطاق" مثل القسمة على صفر، أو الجذر التربيعي لعدد سالب، لأن Perl تولد أخطاءً قاتلة لهذه الحالات.

للانهاية و "ليس رقمًا" قواعد حسابية خاصة بهما. القاعدة العامة هي أنهما "معديان": "Inf" زائد واحد هو "Inf"، و "NaN" زائد واحد هو "NaN". تزداد الأمور إثارة عندما تجمع بين اللانهايات وقيم "ليس رقمًا": "Inf" ناقص "Inf" و "Inf" مقسومًا على "Inf" هي "NaN" (بينما "Inf" زائد "Inf" هو "Inf" و "Inf" ضرب "Inf" هو "Inf"). وقيمة "NaN" غريبة أيضًا في أنها لا تساوي أي رقم، بما في ذلك نفسها: "NaN" != "NaN".

لا تفهم بيرل "Inf" و "NaN" كثوابت عددية، ولكن يمكنك الحصول عليها كسلاسل، وستقوم بيرل بتحويلها حسب الحاجة: "Inf" + 1. (يمكنك، مع ذلك، استيرادها من ملحق POSIX؛ باستخدام "use POSIX qw(Inf NaN);" ثم استخدامها كثوابت.)

لاحظ أنه عند الإدخال (من سلسلة نصية إلى رقم) تقبل Perl "Inf" و "NaN" بأشكال عديدة. يتم تجاهل حالة الأحرف، وتُفهم الأشكال الخاصة بـ Win32 مثل "1.#INF"، ولكن عند الإخراج يتم تطبيع القيم إلى "Inf" و "NaN".

سلاسل الإصدار

يُحلل الحرفي الذي يأتي على الشكل "v1.20.300.4000" كسلسلة نصية مكونة من محارف ذات أرقام ترتيبية محددة. يوفر هذا الشكل، المعروف باسم v-strings، طريقة بديلة وأكثر قابلية للقراءة لإنشاء السلاسل، بدلاً من استخدام شكل الاستيفاء الأقل قابلية للقراءة "\x{1}\x{14}\x{12c}\x{fa0}". هذا مفيد لتمثيل سلاسل يونيكود، ومقارنة "أرقام" الإصدارات باستخدام معاملات مقارنة السلاسل، "cmp"، و "gt"، و "lt" وما إلى ذلك. إذا كان هناك نقطتان أو أكثر في الحرفي، فيمكن حذف حرف "v" البادئ.

    print v9786;              # يطبع SMILEY، "\x{263a}"
    print v102.111.111;       # يطبع "foo"
    print 102.111.111;        # نفس الشيء

تُقبل هذه الأحرف الحرفية من قِبل كل من "require" و "use" لإجراء فحص الإصدار. لاحظ أن استخدام v-strings لعناوين IPv4 ليس قابلاً للنقل ما لم تستخدم أيضًا روتينات inet_aton()/inet_ntoa() الخاصة بحزمة Socket.

لاحظ أنه منذ بيرل 5.8.1، لم تعد سلاسل v المكونة من رقم واحد (مثل "v65") سلاسل v قبل عامل "=>" (الذي يُستخدم عادةً لفصل مفتاح الهاش عن قيمته)؛ وبدلاً من ذلك تُفسر كسلاسل نصية ('v65'). لقد كانت سلاسل v من بيرل 5.6.0 إلى 5.8.0، لكن ذلك تسبب في ارتباك وأعطال أكثر من النفع. تستمر سلاسل v متعددة الأرقام مثل "v65.66" و 65.66.67 في كونها سلاسل v دائماً.

أحرف حرفية خاصة

تمثل الأحرف الحرفية الخاصة __FILE__ و __LINE__ و __PACKAGE__ اسم الملف الحالي، ورقم السطر، واسم الحزمة في تلك النقطة من برنامجك. ويعطي __SUB__ مرجعًا للروتين الفرعي الحالي. لا يجوز استخدامها إلا كرموز (tokens) منفصلة؛ ولن تُستوفى داخل السلاسل النصية. إذا لم تكن هناك حزمة حالية (بسبب توجيه "package;" فارغ)، فإن __PACKAGE__ سيكون القيمة غير المحددة. (لكن "package;" الفارغ لم يعد مدعومًا اعتبارًا من الإصدار 5.10.) خارج الروتين الفرعي، يكون __SUB__ هو القيمة غير المحددة. لا يتوفر __SUB__ إلا في الإصدار 5.16 أو أعلى، وفقط مع إعلان "use v5.16" أو "use feature "current_sub"".

يمكن استخدام محرفي التحكم ^D و ^Z، والرمزين __END__ و __DATA__ للإشارة إلى النهاية المنطقية للسكربت قبل نهاية الملف الفعلية. يتم تجاهل أي نص تالٍ من قِبل المفسر ما لم يقرأه البرنامج كما هو موضح أدناه.

النص بعد __DATA__ يمكن قراءته عبر مقبض الملف "PACKNAME::DATA"، حيث "PACKNAME" هي الحزمة التي كانت حالية عند مواجهة علامة __DATA__. يُترك مقبض الملف مفتوحاً ليشير إلى السطر بعد __DATA__. يجب على البرنامج "close DATA" عند الانتهاء من القراءة منه. (تركه مفتوحاً يسبب تسريب مقابض الملفات إذا وُأعيد تحميل الوحدة لأي سبب، لذا فإن إغلاقه ممارسة أكثر أماناً). للتوافق مع السكربتات القديمة المكتوبة قبل تقديم __DATA__، يتصرف __END__ مثل __DATA__ في السكربت ذي المستوى الأعلى (ولكن ليس في الملفات المحملة بـ "require" أو "do") ويترك بقية محتويات الملف متاحة عبر "main::DATA".

  while (my $line = <DATA>) { print $line; }
  close DATA;
  __DATA__
  Hello world.

يمتلك مقبض الملف "DATA" مبدئياً أي طبقات PerlIO كانت موجودة عندما قرأت بيرل الملف لتحليل المصدر. يعني هذا عادةً أن الملف يُقرأ بالبايت، كما لو كان مرموزاً بترميز Latin-1، ولكن هناك طريقتان رئيستان ليكون الأمر بخلاف ذلك. أولاً، إذا كانت علامة "__END__"/"__DATA__" في نطاق "use utf8"، فإن مقبض "DATA" سيكون في وضع UTF-8. وثانياً، إذا كان المصدر يُقرأ من الدخل القياسي لبيرل، فإن مقبض الملف "DATA" يكون في الواقع اسماً مستعاراً لمقبض ملف "STDIN"، وقد يكون في وضع UTF-8 بسبب متغير البيئة "PERL_UNICODE" أو مفاتيح سطر الأوامر لبيرل.

انظر SelfLoader لمزيد من الوصف لـ __DATA__، ومثال على استخدامه. لاحظ أنه لا يمكنك القراءة من مقبض ملف DATA في كتلة BEGIN: تُنفذ كتلة BEGIN بمجرد رؤيتها (أثناء الترجمة)، وفي تلك النقطة يكون الرمز المقابل __DATA__ (أو __END__) لم يُرَ بعد.

Barewords (الكلمات المجردة)

تُعامل الكلمة التي ليس لها تفسير آخر في قواعد اللغة كما لو كانت سلسلة نصية مقتبسة. تُعرف هذه باسم "barewords". كما هو الحال مع مقابض الملفات واللصائق، فإن الكلمة المجردة التي تتكون بالكامل من أحرف صغيرة تخاطر بالتعارض مع كلمات محجوزة مستقبلاً، وإذا كنت تستخدم براغما "use warnings" أو مفتاح -w، فستحذرك Perl من أي كلمات من هذا القبيل. تحد Perl الكلمات المجردة (مثل المعرفات) بحوالي 250 محرفًا. ومن المرجح أن تلغي الإصدارات المستقبلية من Perl هذه القيود التعسفية.

قد يرغب البعض في منع الكلمات المجردة تمامًا. إذا قلت

    use strict 'subs';

فإن أي كلمة مجردة لن تُفسر كاستدعاء روتين فرعي ستنتج خطأ في وقت الترجمة بدلاً من ذلك. يستمر هذا القيد حتى نهاية الكتلة المحيطة. ويمكن لكتلة داخلية إلغاء هذا بقول "no strict 'subs'".

استيفاء المصفوفة

تُستوفى المصفوفات والشرائح داخل السلاسل النصية ذات الاقتباس المزدوج عبر ربط العناصر بالفاصل المحدد في المتغير $" (أو $LIST_SEPARATOR إذا حُدد "use English;")، وهو المسافة مبدئيًا. ما يلي متكافئ:

    $temp = join($", @ARGV);
    system "echo $temp";
    system "echo @ARGV";

داخل أنماط البحث (التي تخضع أيضاً لاستبدال علامات الاقتباس المزدوجة) يوجد لبس مؤسف: هل يجب تفسير "/$foo[bar]/" على أنه "/${foo}[bar]/" (حيث "[bar]" هي فئة أحرف للتعبير النمطي) أو كـ "/${foo[bar]}/" (حيث "[bar]" هو دليل للمصفوفة @foo)؟ إذا لم تكن @foo موجودة، فمن الواضح أنها فئة أحرف. إذا كانت @foo موجودة، فإن بيرل تأخذ تخميناً جيداً بشأن "[bar]"، وتكون مصيبة دائماً تقريباً. إذا خمنت بشكل خاطئ، أو إذا كنت تشعر بالقلق فحسب، يمكنك فرض التفسير الصحيح باستخدام الأقواس المجعدة كما هو موضح أعلاه.

إذا كنت تبحث عن معلومات حول كيفية استخدام مستندات-هنا (here-documents)، التي كانت موجودة هنا، فقد وُنقلت إلى "Quote and Quote-like Operators" في perlop.

منشئات قيمة القائمة

يُشار إلى قيم القائمة بفصل القيم الفردية بفاصلات (وإحاطة القائمة بأقواس حيث تتطلب الأسبقية ذلك):

    (قائمة)

في سياق لا يتطلب قيمة قائمة، تكون قيمة ما يبدو أنه حرفي قائمة هي ببساطة قيمة العنصر الأخير، كما هو الحال مع معامل الفاصلة في C. على سبيل المثال،

    @foo = ('cc', '-E', $bar);

يعين قيمة القائمة بأكملها للمصفوفة @foo، ولكن

    $foo = ('cc', '-E', $bar);

يعين قيمة المتغير $bar للمتغير العددي $foo. لاحظ أن قيمة المصفوفة الفعلية في السياق العددي هي طول المصفوفة؛ التالي يعين القيمة 3 لـ $foo:

    @foo = ('cc', '-E', $bar);
    $foo = @foo;                # $foo يحصل على 3

يمكنك وضع فاصلة اختيارية قبل قوس الإغلاق لحرفي القائمة، بحيث يمكنك قول:

    @foo = (
        1,
        2,
        3,
    );

لاستخدام مستند-هنا لتعيين مصفوفة، سطر واحد لكل عنصر، قد تستخدم نهجًا مثل هذا:

    @sauces = <<End_Lines =~ m/(\S.*\S)/g;
        normal tomato
        spicy tomato
        green chile
        pesto
        white wine
    End_Lines

تجري القوائم (LISTs) استكمالاً آلياً للقوائم الفرعية. أي أنه عند تقييم قائمة (LIST)، يُقيّم كل عنصر من عناصرها في سياق القائمة، وتُستكمل قيمة القائمة الناتجة داخل القائمة (LIST) تماماً كما لو كان كل عنصر فردي عضواً في القائمة. وبالتالي تفقد المصفوفات والمفرومات هويتها في القائمة (LIST)--حيث إن القائمة

    (@foo,@bar,&SomeSub,%glarch)

تحتوي على كافة عناصر @foo تليها كافة عناصر @bar، تليها كافة العناصر التي يعيدها الروتين الفرعي المسمى SomeSub والمستدعى في سياق القائمة، تليها أزواج المفتاح/القيمة لـ %glarch. لإنشاء مرجع قائمة لا يُستكمل، انظر perlref.

تُمثّل القائمة الفارغة بالرمز (). ولا يكون لاستكمالها في قائمة أي أثر. وبالتالي فإن ((),(),()) تكافئ (). وبالمثل، فإن استكمال مصفوفة بلا عناصر هو تماماً كعدم استكمال أي مصفوفة في تلك النقطة.

يجتمع هذا الدمج مع حقيقة أن الأقواس الافتتاحية والختامية اختيارية (إلا عند الضرورة للأسبقية) وأن القوائم قد تنتهي بفاصلة اختيارية ليعني أن الفواصل المتعددة داخل القوائم هي صيغة قانونية. القائمة "1,,3" هي دمج لقائمتين، "1," و 3، تنتهي الأولى منهما بتلك الفاصلة الاختيارية. "1,,3" هي "(1,),(3)" وهي "1,3" (وبالمثل بالنسبة لـ "1,,,3" هي "(1,),(,),3" وهي "1,3" وما إلى ذلك). ليس بمعنى أننا ننصحك باستخدام هذا الغموض.

يمكن أيضاً فهرسة قيمة القائمة مثل المصفوفة العادية. يجب وضع القائمة بين قوسين لتجنب اللبس. على سبيل المثال:

    # تعيد Stat قيمة قائمة.
    $time = (stat($file))[8];
    # خطأ في الصيغة هنا.
    $time = stat($file)[8];  # عذراً، نسيت الأقواس
    # البحث عن رقم ست عشري.
    $hexdigit = ('a','b','c','d','e','f')[$digit-10];
    # "عامل فاصلة عكسي".
    return (pop(@foo),pop(@foo))[0];

لا يمكن التعيين للقوائم إلا عندما يكون كل عنصر في القائمة قابلاً للتعيين إليه قانونياً:

    ($x, $y, $z) = (1, 2, 3);
    ($map{'red'}, $map{'blue'}, $map{'green'}) = (0x00f, 0x0f0, 0xf00);

الاستثناء الوحيد لهذا هو إمكانية التعيين لـ "undef" في قائمة. وهذا مفيد للتخلص من بعض القيم التي يعيدها التابع:

    ($dev, $ino, undef, undef, $uid, $gid) = stat($file);

بدءاً من Perl 5.22، يمكنك أيضاً استخدام "(undef)x2" بدلاً من "undef, undef". (يمكنك أيضاً إجراء "($x) x 2"، وهو أقل فائدة لأنه يعين لنفس المتغير مرتين، مما يؤدي لمحو القيمة الأولى المعينة.)

عند تعيين قائمة من القيم السلمية إلى مصفوفة، تُمسح كافة القيم السابقة في تلك المصفوفة ويصبح عدد عناصر المصفوفة الآن مساوياً لعدد العناصر في القائمة التي على الطرف الأيمن -- القائمة التي تم التعيين منها. ستغير المصفوفة حجمها آلياً لتتسع بدقة لكل عنصر في القائمة اليمنى.

    use warnings;
    my (@xyz, $x, $y, $z);
    @xyz = (1, 2, 3);
    print "@xyz\n";                             # 1 2 3
    @xyz = ('al', 'be', 'ga', 'de');
    print "@xyz\n";                             # al be ga de
    @xyz = (101, 102);
    print "@xyz\n";                             # 101 102

أما عندما تعين قائمة من القيم السلمية إلى قائمة أخرى من القيم السلمية، فتختلف النتائج بناءً على ما إذا كانت القائمة التي على الطرف الأيسر -- القائمة التي يُعين إليها -- تحتوي على عدد عناصر مساوٍ، أو أكثر، أو أقل من القائمة اليمنى.

    ($x, $y, $z) = (1, 2, 3);
    print "$x $y $z\n";                         # 1 2 3
    ($x, $y, $z) = ('al', 'be', 'ga', 'de');
    print "$x $y $z\n";                         # al be ga
    ($x, $y, $z) = (101, 102);
    print "$x $y $z\n";                         # 101 102
    # استخدام قيمة غير مهيأة $z في السلسلة (.)
    # أو السلسلة النصية في [البرنامج] السطر [رقم السطر].

إذا كان عدد القيم السلمية في القائمة اليسرى أقل من القائمة اليمنى، فلن تُعين القيم السلمية "الزائدة" في القائمة اليمنى ببساطة.

إذا كان عدد القيم السلمية في القائمة اليسرى أكبر من القائمة اليمنى، فستصبح القيم السلمية "المفقودة" غير معرفة (undefined).

    ($x, $y, $z) = (101, 102);
    for my $el ($x, $y, $z) {
        (defined $el) ? print "$el " : print "<undef>";
    }
    print "\n";
                                                # 101 102 <undef>

يعيد تعيين القائمة في سياق سلمي عدد العناصر التي أنتجها التعبير على الطرف الأيمن من التعيين:

    $x = (($foo,$bar) = (3,2,1));       # تُضبط $x لتكون 3، وليس 2
    $x = (($foo,$bar) = f());           # تُضبط $x لتكون عدد القيم التي أعادها f()

يكون هذا مفيداً عندما تريد إجراء تعيين قائمة في سياق منطقي، لأن معظم دوال القوائم تعيد قائمة فارغة عند الانتهاء، مما ينتج 0 عند التعيين، وهو ما يُفسر على أنه خطأ (FALSE).

إنه أيضاً مصدر لاصطلاح مفيد لتنفيذ دالة أو إجراء عملية في سياق قائمة ثم عد عدد القيم المعادة، من خلال التعيين لقائمة فارغة ثم استخدام هذا التعيين في سياق عددي. على سبيل المثال، هذا الكود:

    $count = () = $string =~ /\d+/g;

سيضع في $count عدد مجموعات الأرقام الموجودة في $string. يحدث هذا لأن مطابقة النمط تكون في سياق قائمة (بما أنها تُعين لقائمة فارغة)، وبالتالي ستعيد قائمة بجميع الأجزاء المطابقة من السلسلة النصية. سيترجم تعيين القائمة في السياق السلمي ذلك إلى عدد العناصر (هنا، عدد مرات مطابقة النمط) ويعين ذلك لـ $count. لاحظ أن مجرد استخدام

    $count = $string =~ /\d+/g;

ما كان ليعمل، لأن مطابقة النمط في السياق السلمي لن تعيد سوى صح أو خطأ، بدلاً من عدد المطابقات.

قد يكون العنصر الأخير في تعيين القائمة مصفوفة أو مفرومة:

    ($x, $y, @rest) = split;
    my($x, $y, %rest) = @_;

يمكنك في الواقع وضع مصفوفة أو مفرومة في أي مكان في القائمة، ولكن الأولى في القائمة ستمتص جميع القيم، وأي شيء بعدها سيصبح غير معرف (undefined). قد يكون هذا مفيداً في my() أو local().

يمكن تهيئة المفرومة باستخدام قائمة حرفية تحتوي على أزواج من العناصر التي ستُفسر كمفتاح وقيمة:

    # نفس تعيين الخارطة أعلاه
    %map = ('red',0x00f,'blue',0x0f0,'green',0xf00);

بينما تكون القوائم الحرفية والمصفوفات المسماة قابلة للتبادل غالباً، إلا أن الأمر ليس كذلك بالنسبة للهاش. مجرد قدرتك على وضع دليل لقيمة قائمة مثل مصفوفة عادية لا يعني أنه يمكنك وضع دليل لقيمة قائمة كهاش. وبالمثل، فإن الهاش المضمنة كأجزاء من قوائم أخرى (بما في ذلك قوائم المعاملات وقوائم الإرجاع من الدوال) تُسطح دائماً إلى أزواج مفتاح/قيمة. لهذا السبب من الجيد استخدام المراجع أحياناً.

غالباً ما يكون من الأسهل قراءتها باستخدام عامل "=>" بين أزواج المفتاح/القيمة. عامل "=>" هو في الغالب مجرد مرادف أكثر تميزاً بصرياً للفاصلة، ولكنه يرتب أيضاً لتفسير المعامل الأيسر كسلسلة نصية إذا كان كلمة مجردة (bareword) يمكن أن تكون معرفاً بسيطاً قانونياً. لا يقتبس "=>" المعرفات المركبة التي تحتوي على نقطتين مزدوجتين. هذا يجعله جيداً لتمهيد الهاش:

    %map = (
                 red   => 0x00f,
                 blue  => 0x0f0,
                 green => 0xf00,
   );

أو لتهيئة مراجع مفرومات لتستخدم كسجلات:

    $rec = {
                witch => 'Mable the Merciless',
                cat   => 'Fluffy the Ferocious',
                date  => '10/31/1776',
    };

أو لاستخدام الاستدعاء بالمعاملات المسماة للدوال المعقدة:

   $field = $query->radio_group(
               name      => 'group_name',
               values    => ['eenie','meenie','minie'],
               default   => 'meenie',
               linebreak => 'true',
               labels    => \%labels
   );

لاحظ أن مجرد تمهيد الهاش بهذا الترتيب لا يعني أنها تخرج بهذا الترتيب. انظر "sort" في perlfunc للحصول على أمثلة حول كيفية ترتيب مخرجات.

إذا ظهر مفتاح أكثر من مرة في قائمة تهيئة مفرومة، فإن الظهور الأخير هو الذي يسود:

    %circle = (
                  center => [5, 10],
                  center => [27, 9],
                  radius => 100,
                  color => [0xDF, 0xFF, 0x00],
                  radius => 54,
    );
    # نفس
    %circle = (
                  center => [27, 9],
                  color => [0xDF, 0xFF, 0x00],
                  radius => 54,
    );

يمكن استخدام هذا لتوفير إعدادات مبدئية للتكوين قابلة للتجاوز:

    # القيم في %args لها الأولوية على %config_defaults
    %config = (%config_defaults, %args);

الفهارس (Subscripts)

يمكن الوصول إلى المصفوفة عنصراً سلمياً واحداً في كل مرة بتحديد علامة الدولار ("$")، ثم اسم المصفوفة (بدون علامة "@" البادئة)، ثم الفهرس داخل أقواس مربعة. على سبيل المثال:

    @myarray = (5, 50, 500, 5000);
    print "العنصر الثالث هو ", $myarray[2], "\n";

تبدأ فهارس المصفوفة بـ 0. الفهرس السالب يستعيد قيمته من النهاية. في مثالنا، ستكون قيمة $myarray[-1] هي 5000، وقيمة $myarray[-2] هي 500.

فهارس المفرومات مشابهة، ولكن تستخدم الأقواس المجعدة بدلاً من الأقواس المربعة. على سبيل المثال:

    %scientists =
    (
        "Newton" => "Isaac",
        "Einstein" => "Albert",
        "Darwin" => "Charles",
        "Feynman" => "Richard",
    );
    print "الاسم الأول لداروين هو ", $scientists{"Darwin"}, "\n";

يمكنك أيضاً فهرسة قائمة للحصول على عنصر واحد منها:

    $dir = (getpwnam("daemon"))[7];

محاكاة المصفوفة متعددة الأبعاد

يمكن محاكاة المصفوفات متعددة الأبعاد بفهرسة مفرومة بواسطة قائمة. تُدمج عناصر القائمة باستخدام فاصل الفهارس (انظر "$;" في perlvar).

    $foo{$x,$y,$z}

يكافئ

    $foo{join($;, $x, $y, $z)}

فاصل الفهارس المبدئي هو "\034"، وهو نفس SUBSEP في awk.

الشرائح (Slices)

تصل الشريحة إلى عدة عناصر من قائمة أو مصفوفة أو هاش في آن واحد باستخدام قائمة من الأدلة. إنه أكثر ملاءمة من كتابة العناصر الفردية كقائمة من القيم العددية المنفصلة.

    ($him, $her)   = @folks[0,-1];              # شريحة مصفوفة
    @them          = @folks[0 .. 3];            # شريحة مصفوفة
    ($who, $home)  = @ENV{"USER", "HOME"};      # شريحة مفرومة
    ($uid, $dir)   = (getpwnam("daemon"))[2,7]; # شريحة قائمة

بما أنه يمكنك التعيين لقائمة من المتغيرات، يمكنك أيضاً التعيين لشريحة مصفوفة أو مفرومة.

    @days[3..5]    = qw/Wed Thu Fri/;
    @colors{'red','blue','green'}
                   = (0xff0000, 0x0000ff, 0x00ff00);
    @folks[0, -1]  = @folks[-1, 0];

التعيينات السابقة تكافئ تماماً

    ($days[3], $days[4], $days[5]) = qw/Wed Thu Fri/;
    ($colors{'red'}, $colors{'blue'}, $colors{'green'})
                   = (0xff0000, 0x0000ff, 0x00ff00);
    ($folks[0], $folks[-1]) = ($folks[-1], $folks[0]);

بما أن تغيير الشريحة يغير المصفوفة أو الهاش الأصلية التي تُشرّح، فإن بنية "foreach" ستغير بعض -- أو حتى كل -- قيم المصفوفة أو الهاش.

    foreach (@array[ 4 .. 10 ]) { s/peter/paul/ }
    foreach (@hash{qw[key1 key2]}) {
        s/^\s+//;                       # تقليم المساحات البيضاء البادئة
        s/\s+$//;                       # تقليم المساحات البيضاء اللاحقة
        s/\b(\w)(\w*)\b/\u$1\L$2/g;     # تحويل الكلمات إلى "حالة العنوان"
    }

كاستثناء خاص، عند تشريح قائمة (وليس مصفوفة أو مفرومة)، إذا كانت القائمة فارغة، فإن أخذ شريحة من تلك القائمة الفارغة سينتج دائماً قائمة فارغة بدورها. وبالتالي:

    @a = ()[0,1];          # @a ليس بها عناصر
    @b = (@a)[0,1];        # @b ليس بها عناصر
    @c = (sub{}->())[0,1]; # @c ليس بها عناصر
    @d = ('a','b')[0,1];   # @d بها عنصران
    @e = (@d)[0,1,8,9];    # @e بها أربعة عناصر
    @f = (@d)[8,9];        # @f بها عنصران

هذا يسهل كتابة حلقات تنتهي عندما تُعاد قائمة فارغة:

    while ( ($home, $user) = (getpwent)[7,0] ) {
        printf "%-8s %s\n", $user, $home;
    }

كما ذُكر سابقاً في هذا المستند، المعنى السلمي لتعيين القائمة هو عدد العناصر الموجودة على الطرف الأيمن من التعيين. القائمة الفارغة لا تحتوي على عناصر، لذا عندما ينفد ملف كلمة السر، تكون النتيجة 0، وليس 2.

تعيد الشرائح في السياق السلمي العنصر الأخير من الشريحة.

    @a = qw/first second third/;
    %h = (first => 'A', second => 'B');
    $t = @a[0, 1];                  # قيمة $t الآن هي 'second'
    $u = @h{'first', 'second'};     # قيمة $u الآن هي 'B'

إذا كنت مرتبكاً بشأن سبب استخدامك لـ '@' هناك على شريحة هاش بدلاً من '%'، ففكر في الأمر على النحو التالي. نوع القوس (مربع أو مجعد) يحكم ما إذا كانت مصفوفة أو هاش هي التي يُنظر إليها. ومن ناحية أخرى، يشير الرمز البادئ ('$' أو '@') على المصفوفة أو الهاش إلى ما إذا كنت تحصل على قيمة مفردة (عددي) أو قيمة جمع (قائمة).

شرائح مفتاح/قيمة للمفرومة

بدءاً من Perl 5.20، تعد عملية شريحة المفرومة باستخدام الرمز % نوعاً من أنواع عمليات التشريح التي تعيد قائمة من أزواج المفتاح/القيمة بدلاً من القيم فقط:

    %h = (blonk => 2, foo => 3, squink => 5, bar => 8);
    %subset = %h{'foo', 'bar'}; # شريحة مفتاح/قيمة للمفرومة
    # %subset هي الآن (foo => 3, bar => 8)
    %removed = delete %h{'foo', 'bar'};
    # %removed هي الآن (foo => 3, bar => 8)
    # %h هي الآن (blonk => 2, squink => 5)

ومع ذلك، لا يمكن إضفاء طابع محلي (localized) على نتيجة مثل هذه الشريحة أو التعيين إليها. وهي خلاف ذلك تتسق تماماً مع شرائح المفرومة التي تستخدم الرمز @.

شرائح فهرس/قيمة للمصفوفة

على غرار شرائح مفتاح/قيمة للمفرومة (والتي قُدمت أيضاً في Perl 5.20)، تعيد صيغة شريحة المصفوفة % قائمة من أزواج الفهرس/القيمة:

    @a = "a".."z";
    @list = %a[3,4,6];
    # @list هي الآن (3, "d", 4, "e", 6, "g")
    @removed = delete %a[3,4,6]
    # @removed هي الآن (3, "d", 4, "e", 6, "g")
    # @list[3,4,6] هي الآن undef

لاحظ أن استدعاء "delete" على قيم المصفوفة هو أمر غير محبذ بشدة.

أشكال الأنواع (Typeglobs) ومقابض الملفات

تستخدم Perl نوعاً داخلياً يسمى typeglob لحفظ مدخل كامل في جدول الرموز. بادئة النوع لـ typeglob هي "*"، لأنها تمثل جميع الأنواع. كان هذا هو الأسلوب المفضل لتمرير المصفوفات والمفرومات بالمرجع إلى الدالة، ولكن الآن بما أننا نملك مراجع حقيقية، نادراً ما تبرز الحاجة إلى ذلك.

الاستخدام الرئيس لـ typeglobs في بيرل الحديثة هو إنشاء أسماء مستعارة لجدول الرموز. هذا التعيين:

    *this = *that;

يجعل $this اسماً مستعاراً لـ $that، و @this اسماً مستعاراً لـ @that، و %this اسماً مستعاراً لـ %that، و &this اسماً مستعاراً لـ &that، إلخ. الأكثر أماناً هو استخدام المرجع. هذا:

    local *Here::blue = \$There::green;

يجعل $Here::blue مؤقتاً اسماً مستعاراً لـ $There::green، لكنه لا يجعل @Here::blue اسماً مستعاراً لـ @There::green، أو %Here::blue اسماً مستعاراً لـ %There::green، وما إلى ذلك. انظر "Symbol Tables" في perlmod لمزيد من الأمثلة على ذلك. رغم أن هذا قد يبدو غريباً، إلا أنه أساس نظام استيراد وتصدير الوحدات بالكامل.

استخدام آخر لـ typeglobs هو تمرير مقابض الملفات إلى دالة أو إنشاء مقابض ملفات جديدة. إذا كنت بحاجة لاستخدام typeglob لحفظ مقبض ملف، فافعل ذلك بهذه الطريقة:

    $fh = *STDOUT;

أو ربما كمرجع حقيقي، هكذا:

    $fh = \*STDOUT;

انظر perlsub لمعرفة أمثلة عن استخدام هذه كمقابض ملفات غير مباشرة في الدوال.

تعد Typeglobs أيضاً وسيلة لإنشاء مقبض ملف محلي باستخدام عامل التشغيل local(). تستمر هذه حتى يتم الخروج من كتلتها، ولكن يمكن إعادتها. على سبيل المثال:

    sub newopen {
        my $path = shift;
        local  *FH;  # not my!
        open   (FH, $path)          or  return undef;
        return *FH;
    }
    $fh = newopen('/etc/passwd');

الآن بعد أن أصبح لدينا تدوين *foo{THING}، لم تعد تُستخدم typeglobs بكثرة لمعالجة مقابض الملفات، رغم أنها لا تزال مطلوبة لتمرير مقابض ملفات وأدلة جديدة تماماً إلى الدوال أو منها. وذلك لأن *HANDLE{IO} تعمل فقط إذا كان HANDLE قد وُاستخدم بالفعل كمقبض. بعبارة أخرى، يجب استخدام *FH لإنشاء إدخالات جدول رموز جديدة؛ ولا يمكن لـ *foo{THING} فعل ذلك. عند الشك، استخدم *FH.

كل الدوال القادرة على إنشاء مقابض الملفات (open()، وopendir()، وpipe()، وsocketpair()، وsysopen()، وsocket()، وaccept()) تُنشئ آليًا مقبض ملف مجهول إذا كان المقبض الممرر إليها متغيرًا سلميًا غير مُهيأ. يسمح هذا لاستخدام تراكيب مثل "open(my $fh, ...)" و "open(local $fh,...)" لإنشاء مقابض ملفات ستُغلق آليًا بشكل ملائم عند انتهاء النطاق، شريطة عدم وجود مراجع أخرى لها. يقلل هذا إلى حد كبير من الحاجة إلى typeglobs عند فتح مقابض الملفات التي يجب تمريرها، كما في المثال التالي:

    sub myopen {
        open my $fh, "@_"
             or die "Can't open '@_': $!";
        return $fh;
    }
    {
        my $f = myopen("</etc/motd");
        print <$f>;
        # $f implicitly closed here
    }

لاحظ أنه إذا استُخدم متغير عددي ممهد بدلاً من ذلك، فإن النتيجة ستختلف: "my $fh='zzz'; open($fh, ...)" تكافئ "open( *{'zzz'}, ...)". تمنع "use strict 'refs'" مثل هذه الممارسة.

طريقة أخرى لإنشاء مقابض ملفات مجهولة هي باستخدام وحدة Symbol أو وحدة IO::Handle وأمثالها. تتميز هذه الوحدات بعدم إخفاء الأنواع المختلفة للاسم نفسه أثناء local(). انظر أسفل "open" في perlfunc للحصول على مثال.

انظر أيضًا

انظر perlvar لوصف متغيرات بيرل المدمجة ومناقشة أسماء المتغيرات القانونية. انظر perlref و perlsub و "Symbol Tables" في perlmod لمزيد من النقاش حول typeglobs وصيغة *foo{THING}.

ترجمة

تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.

11 يوليو 2025 perl v5.42.0