perlref - على الإنترنت في السحابة

هذا هو الأمر perlref الذي يمكن تشغيله في مزود الاستضافة المجانية OnWorks باستخدام إحدى محطات العمل المجانية المتعددة عبر الإنترنت مثل Ubuntu Online أو Fedora Online أو محاكي Windows عبر الإنترنت أو محاكي MAC OS عبر الإنترنت

برنامج:

اسم


perlref - مراجع Perl وهياكل البيانات المتداخلة

نوت


هذه وثائق كاملة حول جميع جوانب المراجع. للحصول على برنامج تعليمي أقصر
مقدمة عن الميزات الأساسية فقط ، انظر perlreftut.

الوصف


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

المراجع الصلبة ذكية - فهي تتعقب أعداد المراجع تلقائيًا
تحرير الشيء المشار إليه عندما يذهب عدد المرجع الخاص به إلى الصفر. (مرجع التهم
بالنسبة للقيم في هياكل البيانات ذاتية المرجعية أو الدورية قد لا تذهب إلى الصفر بدون أ
القليل من المساعدة؛ راجع "المراجع الدائرية" للحصول على شرح مفصل.) إذا حدث هذا الشيء
ليكون كائنًا ، يتم تدمير الكائن. انظر perlobj لمزيد من المعلومات حول الكائنات. (في
بمعنى ، كل شيء في Perl هو كائن ، لكننا عادة نحتفظ بالكلمة للإشارة إليها
الأشياء التي تم "تباركها" رسميًا في حزمة فئة.)

المراجع الرمزية هي أسماء متغيرات أو كائنات أخرى ، تمامًا مثل ارتباط رمزي في ملف
يحتوي نظام ملفات Unix على اسم الملف فقط. تدوين * glob هو شيء من a
مرجع رمزي. (تسمى المراجع الرمزية أحيانًا "المراجع الناعمة" ، ولكن
من فضلك لا تسميهم ذلك ؛ المراجع مربكة بدرجة كافية بدون مرادفات عديمة الفائدة.)

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

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

ومع ذلك ، اعلم أن Perl الإصدار 5.14 يقدم استثناءً للقاعدة ، لـ
راحة نحوية. يسمح سلوك المصفوفة التجريبية ووظيفة حاوية التجزئة
مراجع المصفوفات والتجزئة التي سيتعامل معها Perl كما لو كانت صريحة
تم إلغاء الإشارة إليه نحويًا. راجع "التحسينات النحوية" في perl5140delta و perlfunc
للتفاصيل.

القيام ب مراجع حسابات
يمكن إنشاء المراجع بعدة طرق.

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

Scalarref $ = \ $ foo؛
arrayref دولار = \ @ ARGV ؛
التجزئة $ = \٪ ENV؛
$ coderef = \ & معالج ؛
$ globref = \ * foo؛

لا يمكن إنشاء مرجع حقيقي لمقبض الإدخال / الإخراج (مقبض الملف أو dirhandle)
باستخدام عامل الخط المائل العكسي. أقصى ما يمكنك الحصول عليه هو إشارة إلى أداة الكتابة ،
وهو في الواقع إدخال كامل لجدول الرموز. لكن انظر شرح
* foo {THING} البنية أدناه. ومع ذلك ، لا يزال بإمكانك استخدام نوع globs و globrefs كـ
على الرغم من أنها كانت مقابض IO.

2. يمكن إنشاء مرجع إلى مصفوفة مجهولة باستخدام الأقواس المربعة:

$ arrayref = [1، 2، ['a'، 'b'، 'c']]؛

هنا قمنا بإنشاء مرجع إلى مصفوفة مجهولة من ثلاثة عناصر نهائية
العنصر نفسه هو إشارة إلى مصفوفة أخرى مجهولة من ثلاثة عناصر. (ال
يمكن استخدام بناء الجملة متعدد الأبعاد الموصوف لاحقًا للوصول إلى هذا. على سبيل المثال،
بعد ما سبق ، "$ arrayref -> [2] [1]" سيكون لها القيمة "b".)

أخذ إشارة إلى قائمة تعداد ليس هو نفسه استخدام مربع
الأقواس - بدلاً من ذلك يكون الأمر مشابهًا لإنشاء قائمة بالمراجع!

list = (\ $ a ، \b ، \٪ c) ؛
list = \ ($ a،b،٪ c) ؛ # نفس الشيء!

كحالة خاصة ، يعرض "\ (@ foo)" قائمة مراجع لمحتوياتfoo ، وليس
إشارة إلىfoo نفسها. وبالمثل بالنسبة لـ٪ foo ، فيما عدا أن المراجع الرئيسية هي لـ
نسخ (لأن المفاتيح عبارة عن سلاسل فقط وليست نسخًا كاملة الحجم).

3. يمكن إنشاء مرجع إلى تجزئة مجهولة باستخدام الأقواس المتعرجة:

التجزئة $ = {
"آدم" => "حواء" ،
"كلايد" => "بوني" ،
};

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

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

على سبيل المثال ، إذا أردت أن تقوم دالة بعمل تجزئة جديدة وتعيد مرجعًا إليها ،
لديك هذه الخيارات:

الهاشم الفرعي {{_}} # خطأ بصمت
الهاشم الفرعي {+ {_}} # موافق
الهاشم الفرعي {return {_}} # ok

من ناحية أخرى ، إذا كنت تريد المعنى الآخر ، فيمكنك القيام بذلك:

عرض فرعي {{_}} # غامض (مقبول حاليًا ،
# لكن قد يتغير)
العرض الفرعي {{؛ @_ } } # نعم
عرض فرعي {{return_}} # ok

البادئة "{" و "{؛" يعمل دائمًا على إزالة الغموض عن التعبير ليعني أيًا منهما
مرجع HASH أو BLOCK.

4. يمكن إنشاء إشارة إلى روتين فرعي مجهول باستخدام "sub" بدون a
الاسم الفرعي:

$ coderef = sub {print "Boink! \ n"}؛

لاحظ الفاصلة المنقوطة. باستثناء الكود الداخلي الذي لا يتم تنفيذه على الفور ، فإن "sub
{} "ليس تصريحًا بقدر ما هو عامل ، مثل" do {} "أو" Eval {} ".
(ومع ذلك ، بغض النظر عن عدد المرات التي تنفذ فيها هذا السطر المعين (إلا إذا كنت في
"EVAL (" ... ")") ، سيظل لدى $ coderef مرجع إلى نفسه مجهول
روتين فرعي.)

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

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

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

طباعة فرعية {
بلدي $ x = التحول ؛
العودة الفرعية {my $ y = shift؛ طباعة "$ x، $ y! \ n"؛ } ؛
}
$ h = newprint ("Howdy") ؛
$ g = newprint ("تحياتي") ؛

# الوقت يمضي...

& $ h ("العالم")؛
& $ g ("أبناء الأرض") ؛

هذا يطبع

مرحبا العالم!
تحياتي ، أبناء الأرض!

لاحظ بشكل خاص أن $ x يستمر في الإشارة إلى القيمة التي تم تمريرها نيو برينت ()
على الرغم من لقد خرج "my $ x" عن النطاق بحلول الوقت الذي يتم فيه تشغيل الإجراء الفرعي المجهول.
هذا هو كل شيء عن الإغلاق.

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

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

$ objref = كلب جديد (الذيل => "قصير" ، الأذنين => "طويل") ؛

ولكن يمكن أن ينتج عن ذلك بناء جملة غامض في حالات معينة ، لذلك غالبًا ما يكون من الأفضل استخدامه
نهج الاحتجاج المباشر:

$ objref = Doggie-> جديد (الذيل => "قصير" ، الأذنين => "طويل") ؛

استخدام المصطلح :: غطاء ؛
$ terminal = Term :: Cap-> Tgetent ({OSPEED => 9600}) ؛

استخدام المعارف التقليدية
$ main = MainWindow-> new () ؛
menubar $ = $ main-> إطار (-relief => "مرفوع" ،
-عرض الحدود => 2)

6. يمكن أن تظهر الإشارات من النوع المناسب إلى الوجود إذا قمت بإلغاء الإشارة إليها
في سياق يفترض وجودها. لأننا لم نتحدث عن إلغاء المرجع
حتى الآن ، لا يمكننا أن نعرض لك أي أمثلة حتى الآن.

7. يمكن إنشاء مرجع باستخدام صيغة خاصة ، تُعرف بمحبة باسم
* foo {THING} البنية. * foo {THING} ترجع إشارة إلى خانة THING في * foo (أي
هو إدخال جدول الرموز الذي يحتوي على كل ما يُعرف باسم foo).

$ scalarref = * foo {SCALAR} ؛
arrayref $ = * ARGV {ARRAY} ؛
$ hashref = * ENV {HASH} ؛
$ coderef = * معالج {CODE} ؛
$ ioref = * STDIN {IO} ؛
$ globref = * foo {GLOB}؛
$ formatref = * foo {FORMAT}؛
$ globname = * foo {NAME} ؛ # "فو"
$ pkgname = * foo {PACKAGE} ؛ # "رئيسي"

معظمها لا تحتاج إلى شرح ، ولكن * foo {IO} تستحق اهتمامًا خاصًا. هو - هي
إرجاع مقبض الإدخال / الإخراج ، المستخدم لمقابض الملفات ("فتح" في perlfunc) ، المقابس ("المقبس"
في perlfunc و "socketpair" في perlfunc) ، ومقابض الدليل ("opendir" في
بيرلفونك). للتوافق مع الإصدارات السابقة من Perl ، * foo {FILEHANDLE} هو ملف
مرادف لـ * foo {IO} ، على الرغم من أنه مهمل اعتبارًا من 5.8.0. إذا تحذيرات الإيقاف
سارية المفعول ، فسوف تحذر من استخدامها.

* foo {THING} تعيد undef إذا لم يتم استخدام هذا الشيء المعين حتى الآن ، إلا في ملف
حالة عددي. * يعرض foo {SCALAR} إشارة إلى عدد مجهول إذا كان $ foo
لم تستخدم بعد. قد يتغير هذا في إصدار مستقبلي.

* foo {NAME} و * foo {PACKAGE} هما الاستثناء ، لأنهما يعيدان السلاسل بدلاً من ذلك
من المراجع. هذه تعيد الحزمة واسم النوع نفسه ، بدلاً من ذلك
من الذي تم تعيينه لها. لذلك ، بعد "* foo = * Foo :: bar" ، ستصبح * foo
"* Foo :: bar" عند استخدامها كسلسلة ، ولكن * foo {PACKAGE} و * foo {NAME} سيستمران في
إنتاج "main" و "foo" على التوالي.

* foo {IO} هو بديل لآلية * HANDLE الواردة في "Typeglobs و
مقابض الملفات "في بيرداتا لتمرير مقابض الملفات إلى أو خارج الإجراءات الفرعية ، أو
التخزين في هياكل بيانات أكبر. عيبه أنه لن يخلق ملف
ملف من أجلك. ميزته هي أن لديك مخاطر أقل من الضرب أكثر من
التي تريدها مع مهمة الكتابة. (لا يزال يدمج الملف والدليل
ومع ذلك ، إذا قمت بتعيين القيمة الواردة إلى عدد قياسي بدلاً من a
typeglob كما نفعل في الأمثلة أدناه ، لا يوجد خطر من حدوث ذلك.

بصمة (* STDOUT) ؛ # مرر الكرة الأرضية بأكملها
بصمة (* STDOUT {IO}) ؛ # تمرير كل من مقابض الملفات والدير

ضجيج ثانوي {
بلدي $ fh = التحول ؛
print $ fh "لها حسنًا هممم \ n"؛
}

rec = get_rec (* STDIN) ؛ # مرر الكرة الأرضية بأكملها
$ rec = get_rec (* STDIN {IO}) ؛ # تمرير كل من مقابض الملفات والدير

get_rec الفرعية {
بلدي $ fh = التحول ؛
العودة العددية <$ fh> ؛
}

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

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

$ بار = $$ scalarref ؛
push (@ $ arrayref، $ filename) ؛
$$ arrayref [0] = "يناير" ؛
$$ hashref {"KEY"} = "VALUE" ؛
& $ coderef (1,2,3،XNUMX،XNUMX) ؛
print $ globref "إخراج \ n"؛

من المهم أن نفهم أننا على وجه التحديد ليس الرجوع إلى $ arrayref [0]
أو $ hashref {"KEY"} هناك. يحدث الانحدار من المتغير القياسي قبل it
يقوم بأي عمليات بحث رئيسية. يجب أن يكون أي شيء أكثر تعقيدًا من المتغير القياسي البسيط
طرق الاستخدام 2 أو 3 أدناه. ومع ذلك ، فإن "العددية البسيطة" تتضمن معرفًا
يستخدم نفسه الطريقة 1 بشكل متكرر. لذلك ، فإن المطبوعات التالية "مرحبا".

$ refrefref = \\\ "howdy"؛
print $$$$ refrefref؛

2. في أي مكان تضع فيه معرّفًا (أو سلسلة من المعرّفات) كجزء من متغير أو
اسم الروتين الفرعي ، يمكنك استبدال المعرف بـ BLOCK بإرجاع مرجع لـ
النوع الصحيح. بمعنى آخر ، يمكن كتابة الأمثلة السابقة على النحو التالي:

$ bar = $ {$ scalarref} ؛
push (@ {$ arrayref}، $ filename) ؛
$ {$ arrayref} [0] = "يناير" ؛
$ {$ hashref} {"KEY"} = "VALUE" ؛
& {$ coderef} (1,2,3،XNUMX،XNUMX) ؛
$ globref-> print ("output \ n")؛ # iff IO :: يتم تحميل المقبض

من المسلم به أنه من السخف بعض الشيء استخدام الضفائر في هذه الحالة ، ولكن يمكن لـ BLOCK
تحتوي على أي تعبير تعسفي ، ولا سيما التعبيرات المكتوبة:

& {$ dispatch {$ index}} (1,2,3،XNUMX،XNUMX)؛ # استدعاء الروتين الصحيح

بسبب القدرة على حذف curlies للحالة البسيطة لـ $$ x ، الأشخاص في كثير من الأحيان
ارتكاب خطأ النظر إلى رموز إلغاء الإشارة باعتبارها عوامل تشغيل مناسبة ، وتتعجب
عن أسبقيتهم. إذا كانت كذلك ، فيمكنك استخدام الأقواس بدلاً من
الأقواس. هذا ليس هو الحال. ضع في اعتبارك الفرق أدناه ؛ الحالة 0 مختصرة
نسخة من الحالة 1 ، ليس القضية 2:

$$ hashref {"KEY"} = "VALUE" ؛ # القضية 0
$ {$ hashref} {"KEY"} = "VALUE" ؛ # حالة 1
$ {$ hashref {"KEY"}} = "VALUE" ؛ # القضية 2
$ {$ hashref -> {"KEY"}} = "VALUE" ؛ # حالة 3

الحالة 2 مخادعة أيضًا لأنك تصل إلى متغير يسمى٪ hashref ، وليس كذلك
الرجوع من خلال $ hashref إلى التجزئة التي يُفترض أنها تشير إليها. ممكن حدوثه
الحالة 3.

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

$ arrayref -> [0] = "يناير" ؛ # عنصر صفيف
$ hashref -> {"KEY"} = "VALUE" ؛ # عنصر تجزئة
كودريف $ -> (1,2,3،XNUMX،XNUMX) ؛ # مكالمة روتين فرعي

يمكن أن يكون الجانب الأيسر من السهم أي تعبير يعيد مرجعًا ، بما في ذلك a
مرجع سابق. لاحظ أن $ array [$ x] هو ليس نفس الشيء مثل "$ array -> [$ x]"
، هنا:

$ array [$ x] -> {"foo"} -> [0] = "يناير"؛

هذه إحدى الحالات التي ذكرناها سابقًا والتي يمكن أن تنبثق فيها المراجع
الوجود في سياق lvalue. قبل هذا البيان ، ربما كان $ array [$ x]
غير معرف. إذا كان الأمر كذلك ، فسيتم تعريفه تلقائيًا بمرجع تجزئة حتى نتمكن من ذلك
ابحث عن "{" foo "}" فيه. وبالمثل ، ستحصل تلقائيًا على "$ array [$ x] -> {" foo "}"
معرّف بمرجع مصفوفة حتى نتمكن من البحث عن "[0]" فيه. هذه العملية
تسمى التكييف التلقائي.

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

$ array [$ x] {"foo"} [0] = "يناير"؛

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

النتيجة بالدولار [x $] [$ y] [$ z] + = 42 ؛

حسنًا ، حسنًا ، ليس تمامًا مثل مصفوفات C ، في الواقع. لا يعرف C كيف ينمو
المصفوفات حسب الطلب. تفعل Perl.

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

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

if ($ ref1 == $ ref2) {# مقارنة رقمية رخيصة للمراجع
طباعة "المرجعان 1 و 2 يشيران إلى نفس الشيء \ n" ؛
}

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

تشير يبارك() يمكن استخدام عامل التشغيل لربط الكائن الذي يشير إليه المرجع بـ
تعمل الحزمة كفئة كائن. انظر perlobj.

قد يتم إلغاء الإشارة إلى نوع الخط بنفس الطريقة التي يمكن بها الإشارة إلى المرجع ، لأن المرجع
يشير بناء الجملة دائمًا إلى نوع المرجع المطلوب. إذًا "$ {* foo}" و "$ {\ $ foo}" كلاهما
تشير إلى نفس المتغير القياسي.

إليك خدعة لاستيفاء استدعاء إجراء فرعي في سلسلة:

طباعة "أعاد My sub @ {[mysub (1,2,3،XNUMX،XNUMX)]} ذلك الوقت. \ n"؛

الطريقة التي تعمل بها هي أنه عندما يتم عرض "@ {...}" في السلسلة ذات التنصيص المزدوج ، فإنها تكون كذلك
تقييمها على أنها كتلة. تقوم الكتلة بإنشاء مرجع إلى مصفوفة مجهولة تحتوي على الامتداد
نتائج الاستدعاء إلى "mysub (1,2,3،XNUMX،XNUMX)". لذا فإن الكتلة بأكملها ترجع إشارة إلى ملف
المصفوفة ، والتي يتم بعد ذلك إلغاء الإشارة إليها بواسطة "@ {...}" وتم وضعها في السلسلة ذات علامات الاقتباس المزدوجة.
هذا الخداع مفيد أيضًا للتعبيرات العشوائية:

طباعة "هذا ينتج @ {[$ n + 5]} من الأدوات \ n"؛

وبالمثل ، يمكن إلغاء الإشارة إلى التعبير الذي يُرجع مرجعًا إلى رقم قياسي عبر
"$ {...}". وبالتالي ، يمكن كتابة التعبير أعلاه على النحو التالي:

طباعة "هذا ينتج أدوات $ {\ ($ n + 5)} \ n"؛

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

my $ foo = {}؛
شريط $ الخاص بي = {foo => $ foo} ؛
$ foo -> {bar} = $ bar ؛

يمكنك أيضًا إنشاء مرجع دائري بمتغير واحد:

بلدي $ فو؛
$ foo = \ $ foo؛

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

نظرًا لأنه يتم تنفيذ الكائنات في Perl كمراجع ، فمن الممكن أن يكون لها دائري
المراجع مع الأشياء كذلك. تخيل فئة TreeNode حيث تشير كل عقدة إلى ملف
عقد الوالدين والطفل. ستكون أي عقدة مع أصل جزء من مرجع معاد.

يمكنك فصل المراجع الدائرية عن طريق إنشاء "مرجع ضعيف". إشارة ضعيفة تفعل ذلك
لا تزيد من عدد المرجع للمتغير ، مما يعني أن الكائن يمكن أن يخرج
من النطاق ويتم تدميرها. يمكنك إضعاف مرجع مع تصدير وظيفة "إضعاف"
بواسطة Scalar :: Util module.

إليك كيف يمكننا جعل المثال الأول أكثر أمانًا:

استخدام عددي :: Util "تضعف" ؛

my $ foo = {}؛
شريط $ الخاص بي = {foo => $ foo} ؛
$ foo -> {bar} = $ bar ؛

إضعاف $ foo -> {bar} ؛

تم إضعاف المرجع من $ foo إلى $ bar. عندما يخرج متغير شريط $ من
النطاق ، سيتم جمع القمامة. في المرة القادمة التي تنظر فيها إلى قيمة
مفتاح "$ foo -> {bar}" ، سيكون "undef".

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

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

كثيرا ما يتوقع الناس أن يعمل مثل هذا. هكذا هو الحال.

$ name = "foo" ؛
$$ الاسم = 1 ؛ # مجموعات $ foo
$ {$ name} = 2 ؛ # مجموعات $ foo
$ {$ name x 2} = 3 ؛ # مجموعات $ foofoo
اسم $ -> [0] = 4 ؛ # مجموعات $ foo [0]
@ $ name = ()؛ # مسح foo
& $ name () ؛ # Calls & foo ()
حزمة الدولار = "هذا" ؛
$ {"$ {pack} :: $ name"} = 5 ؛ # مجموعات $ THAT :: foo بدون EVAL

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

استخدام "المراجع" الصارمة ؛

وبعد ذلك سيتم السماح فقط بالمراجع الثابتة لبقية الكتلة المرفقة. ان
قد يبطل الكتلة الداخلية ذلك بـ

لا يوجد "حكام" صارمون ؛

فقط متغيرات الحزمة (globals ، حتى لو كانت مترجمة) مرئية للمراجع الرمزية.
المتغيرات المعجمية (معلنة بـ لي()) غير موجودة في جدول الرموز ، وبالتالي فهي غير مرئية
هذه الآلية. على سبيل المثال:

القيمة بالدولار المحلي = 10 ؛
المرجع $ = "القيمة" ؛
{
قيمتي بالدولار = 20 ؛
طباعة $$ المرجع ؛
}

سيستمر هذا في طباعة 10 ، وليس 20. تذكر ذلك محلي() يؤثر على متغيرات الحزمة ، والتي
كلها "عالمية" للحزمة.

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

$ push = "pop on" ؛
طباعة "$ {push} فوق"؛

لطالما قصدت طباعة "pop on over" ، على الرغم من أن الضغط كلمة محجوزة. هذا هو
معمم للعمل بنفس الطريقة دون تضمين علامات الاقتباس المزدوجة ، بحيث

طباعة $ {push}. "زيادة"؛

وحتى

طباعة $ {push}. "زيادة"؛

سيكون له نفس التأثير. هذا البناء ليس يعتبر مرجعا رمزيا
عندما تستخدم مراجع صارمة:

استخدام "المراجع" الصارمة ؛
$ {bareword}؛ # حسنًا ، يعني $ bareword.
$ {"bareword"}؛ # خطأ مرجعي رمزي.

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

$ array {"aaa"} {"bbb"} {"ccc"}

يمكنك الكتابة فقط

$ array {aaa} {bbb} {ccc}

ولا تقلق بشأن ما إذا كانت الأحرف المنخفضة كلمات محجوزة. في حالة نادرة أنك
لا ترغب في فعل شيء مثل

$ مجموعة {shift}

يمكنك فرض التفسير ككلمة محجوزة عن طريق إضافة أي شيء يجعلها أكثر من
كلمة بارو:

$ مجموعة {shift ()}
مجموعة $ {+ shift}
مجموعة $ {shift_}

"تحذيرات الاستخدام" pragma أو -w سيحذرك مفتاح التبديل إذا كان يفسر كلمة محجوزة
كسلسلة. لكنه لن يحذرك بعد الآن من استخدام الكلمات الصغيرة ، لأن
تم اقتباس السلسلة بشكل فعال.

تجزئة زائفة: باستخدام an مجموعة as a مزيج
تمت إزالة التجزئات الزائفة من Perl. تظل براغما "الحقول" متاحة.

الوظيفة النماذج
كما هو موضح أعلاه ، وظيفة مجهولة مع إمكانية الوصول إلى المتغيرات المعجمية مرئية
عندما تم تجميع هذه الوظيفة ، يتم إنشاء إغلاق. يحتفظ بالوصول إلى تلك المتغيرات
على الرغم من أنه لا يتم تشغيله إلا في وقت لاحق ، كما هو الحال في معالج الإشارة أو رد اتصال Tk.

يتيح لنا استخدام الإغلاق كقالب وظيفي إنشاء العديد من الوظائف التي تعمل
بصورة مماثلة. لنفترض أنك تريد وظائف مسماة على اسم الألوان التي أدت إلى إنشاء خط HTML
التغييرات للألوان المختلفة:

طباعة "كن" ، أحمر ("حذر") ، "مع ذلك" ، أخضر ("فاتح") ؛

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

@ الألوان = qw (أحمر أزرق أخضر أصفر برتقالي بنفسجي بنفسجي) ؛
لـ $ name (colors) {
لا يوجد "حكام" صارمون ؛ # السماح بمعالجة جدول الرموز
* $ name = * {uc $ name} = sub {" _ "}؛
}

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

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

* $ name = sub ($) {" $ _ [0] "} ؛

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

الوصول إلى المفردات التي تتغير بمرور الوقت - مثل تلك الموجودة في حلقة "for" أعلاه ، بشكل أساسي
الأسماء المستعارة لعناصر من النطاقات المعجمية المحيطة - تعمل فقط مع الغواصات المجهولة ،
ليس مع الإجراءات الفرعية المسماة. بشكل عام ، فإن الإجراءات الفرعية المسماة لا تتداخل بشكل صحيح و
يجب التصريح عنه فقط في نطاق الحزمة الرئيسية.

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

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

الفرعي الخارجي {
x دولار الخاص بي = $ _ [0] + 35 ؛
الداخلية الفرعية {return $ x * 19} # خطأ
إرجاع $ x + inner () ؛
}

الحل البديل هو ما يلي:

الفرعي الخارجي {
x دولار الخاص بي = $ _ [0] + 35 ؛
محلي * داخلي = فرعي {return $ x * 19} ؛
إرجاع $ x + inner () ؛
}

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

هذا له تأثير مثير للاهتمام في إنشاء دالة محلية لوظيفة أخرى ،
شيء غير مدعوم عادة في Perl.

تحذير


لا يجوز لك (بشكل مفيد) استخدام مرجع كمفتاح للتجزئة. سيتم تحويله إلى ملف
خيط:

$ x {\ $ a} = $ a ؛

إذا حاولت إلغاء إشارة المفتاح ، فلن يؤدي ذلك إلى إلغاء مرجعي صعب ، ولن تفعل ذلك
أنجز ما تحاول. قد ترغب في القيام بشيء يشبه

$ r = \ @ a ؛
$ x {$ r} = $ r ؛

وبعد ذلك على الأقل يمكنك استخدام ملف القيم ()، والتي ستكون حكامًا حقيقيين ، بدلاً من
مفاتيح ()التي لن تفعل ذلك.

توفر الوحدة القياسية Tie :: RefHash حلاً مناسبًا لذلك.

بوستفيكس عدم المرجعية بناء الجملة


بدءًا من v5.20.0 ، تتوفر صيغة postfix لاستخدام المراجع. يتصرف مثل
الموصوفة في "استخدام المراجع" ، ولكن بدلاً من sigil مسبوقة ، فإن postfixed sigil-and-
يستخدم النجم.

فمثلا:

$ r = \ @ a ؛
b = $ r -> @ * ؛ # مكافئ لـ @ $ r أو @ {$ r}

$ r = [1، [2، 3]، 4] ؛
$ r -> [1] -> @ * ؛ # مكافئ لـ @ {$ r -> [1]}

يجب تمكين بناء الجملة هذا باستخدام "ميزة استخدام" postderef "". إنه تجريبي وإرادة
التحذير افتراضيًا ما لم يتم تفعيل "no warnings" التجريبية :: postderef "".

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

$ sref -> $ *؛ # مثل $ {$ sref}
عارف دولار -> @ * ؛ # مثل @ {$ aref}
عارف $ -> $ # *؛ # مثل $ # {$ aref}
$ href ->٪ * ؛ # مثل٪ {$ href}
$ cref -> & * ؛ # مماثل لـ & {$ cref}
$ gref -> ** ؛ # مثل * {$ gref}

لاحظ بشكل خاص أن "$ cref -> & *" هو ليس تعادل "$ cref -> ()" ، ويمكن أن تقدم خدمة مختلفة
الأغراض.

يمكن استخراج عناصر Glob من خلال ميزة إلغاء مرجعية postfix:

$ gref -> * {SCALAR} ؛ # مثل * {$ gref} {SCALAR}

مصفوفة Postfix وإلغاء مرجعي عددي يمكن تستخدم في استيفاء السلاسل (علامات الاقتباس المزدوجة
أو عامل التشغيل "qq") ، ولكن فقط في حالة تمكين ميزة "postderef_qq" الإضافية.

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

$ aref -> @ [...] ؛ # مثل @ $ aref [...]
$ href -> @ {...} ؛ # مثل @ $ href {...}

تقطيع زوج المفتاح / القيمة Postfix ، تمت إضافته في 5.20.0 وتوثيقه في تجزئة المفتاح / القيمة
قسم الشرائح من بيرداتا ، يتصرف أيضًا كما هو متوقع:

$ aref ->٪ [...] ؛ # مثل٪ $ aref [...]
$ href ->٪ {...} ؛ # مثل٪ $ href {...}

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

تعيين إلى مراجع حسابات


بدءًا من الإصدار 5.22.0 ، يمكن تعيين عامل الإحالة إلى. ينفذ
عملية aliasing ، بحيث يصبح اسم المتغير المشار إليه في الجانب الأيسر بامتداد
الاسم المستعار للشيء المشار إليه على الجانب الأيمن:

\ $ a = \ $ b؛ # $ a و $ b الآن يشيران إلى نفس العدد
\ & foo = \ & شريط ؛ # foo () تعني الآن الشريط ()

يجب تمكين بناء الجملة هذا من خلال "استخدام ميزة 'refaliasing'". إنه تجريبي و
سيحذر بشكل افتراضي ما لم يتم تفعيل "no warnings" التجريبية :: refaliasing "".

قد يتم تعيين هذه النماذج ، وتتسبب في تقييم الجانب الأيمن بشكل عددي
سياق الكلام:

\ $ عددي
\@مجموعة مصفوفة
\٪ تجزئة
\&الفرعية
\ عددي $
\ myarray
\ الخاص بي٪ التجزئة
\ state $ scalar # أوarray ، إلخ.
\ لدينا عددي $ # إلخ.
\ local $ scalar # إلخ.
\ local our $ scalar # إلخ.
\ $ some_array [$ index]
\ $ some_hash {$ key}
\ local $ some_array [$ index]
\ محلي $ some_hash {$ key}
حالة ؟ \ $ this: \ $ that [0] # وما إلى ذلك.

تؤدي عمليات التقطيع والأقواس إلى تقييم الجانب الأيمن في القائمة
سياق الكلام:

\array [5..7]
(\array [5..7])
\ (@ مجموعة [5..7])
\ @ هاش {'foo'، 'bar'}
(\hash {'foo'، 'bar'})
\ (@ hash {'foo'، 'bar'})
(\ $ عددي)
\ (عددي بالدولار)
\ (عددي $)
\ (عددي $)
(\@مجموعة مصفوفة)
(\٪ تجزئة)
(\&الفرعية)
\(&الفرعية)
\ ($ foo،bar،٪ baz)
(\ $ foo، \bar، \٪ baz)

يجب أن يكون كل عنصر على الجانب الأيمن مرجعًا لمرجع من النوع الصحيح.
الأقواس المحيطة مباشرة بمصفوفة (وربما أيضًا
"my" / "state" / "our" / "local") ستجعل كل عنصر من المصفوفة اسمًا مستعارًا لـ
العددية المقابلة المشار إليها على الجانب الأيمن:

\ (@ أ) = \ (@ ب) ؛ #a و @ b لهما نفس العناصر الآن
\ (@ أ) = \ (@ ب) ؛ # على نفس المنوال
\ (mya) = \ (@ b) ؛ # على نفس المنوال
دفعa ، 3 ؛ # ولكن الآن يحتويa على عنصر إضافي يفتقر إليهb
\ (@ a) = (\ $ a ، \ $ b ، \ $ c) ؛ #a يحتوي الآن على $ a و $ b و $ c

دمج هذا النموذج مع "محلي" ووضع أقواس حول التجزئة على الفور
ممنوع (لعدم وضوح ما يجب عليهم فعله):

\ local (array) = foo () ؛ # خطأ
\ (٪ تجزئة) = شريط () ؛ # خطأ

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

(my $ tom، \ my $ dick، \ myharry) = (\ 1، \ 2، [1..3])؛
# $ توم الآن \ 1
# $ dick الآن 2 (للقراءة فقط)
# @ harry هو (1,2,3،XNUMX،XNUMX)

نوع $ الخاص بي = المرجع $ thingy؛
($ type؟ $ type == 'ARRAY'؟ \foo: \ $ bar: $ baz) = $ thingy؛

يمكن أن تأخذ حلقة "foreach" أيضًا مُنشئًا مرجعيًا لمتغير الحلقة الخاص بها ، على الرغم من أن
بناء الجملة يقتصر على واحد مما يلي ، مع اختيارية "my" أو "state" أو "our" التي تليها
الشرطة المائلة للخلف:

\ $ s
\@أ
\٪ h
\ & ج

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

foreach \ mya (array_of_arrays) {
frobnicate ($ a [0]، $ a [-1])؛
}

foreach \ my٪ h (array_of_hashes) {
$ h {gelastic} ++ if $ h {type} == 'funny'؛
}

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

استخدم perlref عبر الإنترنت باستخدام خدمات onworks.net



أحدث برامج Linux و Windows عبر الإنترنت