بنية لغة بيرل

يشمل هيكل لغة برمجة بيرل كلاً من قواعدها النحوية والطرق العامة لتنظيم البرامج. وتتجلى فلسفة تصميم بيرل في الشعار الشائع " هناك أكثر من طريقة لفعل ذلك ". وباعتبارها لغة متعددة الأنماط وديناميكية الكتابة ، تتيح بيرل درجة عالية من المرونة في تصميم البرامج. كما تشجع بيرل على التجزئة؛ ويعزى ذلك إلى بنية التصميم القائمة على المكونات في جذورها من يونكس ، [ 1 ] وهو ما يفسر حجم أرشيف CPAN ، وهو مستودع يديره المجتمع ويضم أكثر من 100,000 وحدة برمجية. [ 2 ]

بناء الجملة الأساسي

في لغة بيرل، يمكن كتابة برنامج "Hello World" البسيط على النحو التالي:

اطبع "مرحباً بالعالم!"

يطبع هذا الأمر السلسلة " Hello, World!" وسطرًا جديدًا ، معبرًا عنه رمزيًا بحرف nيتغير تفسيره بواسطة حرف الهروب السابق (الشرطة المائلة العكسية ). منذ الإصدار 5.10، تُنتج الدالة المدمجة الجديدة "say" [ 3 ] التأثير نفسه بشكل أبسط.

قل "مرحباً بالعالم!"

يمكن أيضًا تحديد برنامج Perl كامل كمعامل سطر أوامر لـ Perl، بحيث يمكن تنفيذ البرنامج نفسه من سطر الأوامر (مثال معروض لنظام Unix):

$ perl - e 'print "Hello, World!\n"'

الصيغة الرسمية للبرنامج أكثر تفصيلاً بعض الشيء:

#!/usr/bin/env perl print "Hello, World!\n" ;

يُستخدم رمز التجزئة (#) لإضافة تعليق في لغة بيرل، يمتد حتى نهاية سطر الكود ويتجاهله المُصرّف ( باستثناء نظام ويندوز). التعليق المُستخدم هنا من نوع خاص يُسمى سطر shebang . يُخبر هذا السطر أنظمة التشغيل الشبيهة بنظام يونكس بالبحث عن مُفسّر بيرل، مما يُتيح استدعاء البرنامج دون الحاجة إلى ذكره صراحةً perl. (تجدر الإشارة إلى أنه في أنظمة مايكروسوفت ويندوز ، يتم استدعاء برامج بيرل عادةً بربط .plالامتداد بمُفسّر بيرل. وللتعامل مع هذه الحالات، perlيكتشف المُصرّف سطر shebang ويُحلّله بحثًا عن المُبدّلات. [ 4 ] )

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

يقدم الإصدار 5.10 من لغة بيرل دالة sayتقوم ضمنيًا بإضافة حرف سطر جديد إلى مخرجاتها، مما يجعل برنامج "Hello World" البسيط أقصر بكثير:

استخدم 5.010 ؛ # يجب أن يكون موجودًا لاستيراد وظائف 5.10 الجديدة، لاحظ أنها 5.010 وليست 5.10 قل "مرحباً بالعالم!"

أنواع البيانات

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

يكتبسيجيلمثالوصف
كمية قياسيةدولار$fooقيمة واحدة؛ قد تكون رقمًا أو سلسلة نصية أو مقبض ملف أو مرجعًا .
المصفوفة@@fooمجموعة مرتبة من الكميات القياسية.
هاش%%fooخريطة من السلاسل النصية إلى القيم العددية؛ تُسمى السلاسل النصية بالمفاتيح ، وتُسمى القيم العددية بالقيم . تُعرف أيضًا باسم المصفوفة الترابطية .
معرّف الملفلا أحد$fooأوFOOتمثيل مبهم لملف مفتوح أو هدف آخر للقراءة أو الكتابة أو كليهما.
روتين فرعيو&fooجزء من التعليمات البرمجية التي يمكن تمرير الوسائط إليها، وتنفيذها، وإرجاع البيانات.
Typeglob**fooإدخال جدول الرموز لجميع الأنواع التي تحمل الاسم 'foo'.

القيم العددية

يجب وضع القيم النصية (القيم الحرفية) بين علامتي اقتباس. يسمح وضع سلسلة نصية بين علامتي اقتباس مزدوجتين باستبدال أسماء المتغيرات التي تظهر أسماؤها في السلسلة تلقائيًا (أو إدراجها ضمن السلسلة). أما وضع سلسلة نصية بين علامتي اقتباس مفردتين فيمنع إدراج المتغيرات.

على سبيل المثال، إذا $nameكان "Jim":

  • ثم print("My name is $name")سيتم طباعة "My name is Jim"(الاستيفاء داخل علامتي اقتباس مزدوجتين)،
  • لكن print('My name is $name')سيتم الطباعة "My name is $name"(بدون استيفاء داخل علامات الاقتباس المفردة).

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

يمكن أيضًا وضع علامات اقتباس حول السلاسل النصية باستخدام عوامل التشغيل qالشبيهة qqبعلامات الاقتباس:

  • 'this'وهما q(this)متطابقان،
  • "$this"وهما qq($this)متطابقان.

وأخيرًا، يمكن تعريف السلاسل متعددة الأسطر باستخدام المستندات المضمنة هنا :

$multilined_string = << EOF ; هذه هي سلسلتي النصية متعددة الأسطر ، لاحظ أنني أنهيها بكلمة "EOF". EOF

لا تحتاج الأرقام (الثوابت العددية) إلى علامات اقتباس. يقوم بيرل بتحويل الأرقام إلى سلاسل نصية والعكس صحيح، وذلك حسب السياق. عند تحويل السلاسل النصية إلى أرقام، تُحذف الأجزاء غير العددية اللاحقة. إذا لم يكن أي جزء بادئ من السلسلة النصية عددًا، فسيتم تحويلها إلى الرقم 0. في المثال التالي، تُعامل السلسلتان النصيتان $nو $mكأرقام. يطبع هذا الكود الرقم '5'. تبقى قيم المتغيرات كما هي. لاحظ أن في بيرل، +هو دائمًا عامل الجمع العددي. أما عامل دمج السلاسل النصية فهو النقطة.

$n = '3 تفاحات' ; $m = '2 برتقالات' ; print $n + $m ;

تُوفّر دوال لتقريب القيم الكسرية إلى قيم صحيحة: intالأولى تحذف الجزء الكسري ، والأخرى تُقرّب نحو الصفر؛ POSIX::ceilوالثانية POSIX::floorتُقرّب دائمًا للأعلى، والثالثة تُقرّب دائمًا للأسفل. أما لتحويل الأرقام إلى سلاسل نصية printf "%f"أو sprintf "%f"تقريبها إلى أعداد صحيحة، فيُستخدم تقريب المصرفيين .

تستخدم لغة بيرل أيضًا سياقًا منطقيًا (boolean context) لتقييم العبارات الشرطية. القيم التالية تُقيّم جميعها على أنها خاطئة في بيرل:

$false = 0 ; # العدد صفر $false = 0.0 ; # العدد صفر كعدد عشري $false = 0b0 ; # العدد صفر في النظام الثنائي $false = 0x0 ; # العدد صفر في النظام الست عشري $false = '0' ; # السلسلة النصية صفر $false = "" ; # السلسلة النصية الفارغة $false = (); # القائمة الفارغة $false = undef ; # القيمة المُعادة من undef $false = 2 - 3 + 1 # تُحسب لتكون 0، والتي تُحوّل إلى "0"، لذا فهي خاطئة

جميع القيم الأخرى (غير الصفرية) تُقيّم إلى "صحيح". يشمل ذلك السلسلة النصية "0 لكن صحيح"، وهي في الواقع صفر كرقم، لكنها "صحيح" عند استخدامها كقيمة منطقية. جميع السلاسل النصية غير الرقمية لها هذه الخاصية أيضًا، لكن هذه السلسلة تحديدًا تُقتطع بواسطة بيرل دون تحذير رقمي. هناك نسخة أقل وضوحًا ولكنها أكثر قابلية للتطبيق من الناحية المفاهيمية لهذه السلسلة وهي ' 0E0 ' أو ' 0e0 '، والتي لا تعتمد على تقييم الأحرف على أنها صفر، لأن '0E0' هي حرفيًا صفر مضروبًا في عشرة أس صفر. التجزئة الفارغة صحيحة أيضًا؛ في هذا السياق، لا تُمثل كتلة فارغة، لأنها تُرجع قيمة فارغة .{}{}perl -e 'print ref {}'HASH

تُعتبر التعبيرات المنطقية المُقَيَّمة قيمًا عددية أيضًا. لا تُحدد الوثائق القيمة المُحددة التي تُرجعها الدالة، سواء كانت صحيحة أو خاطئة. تُرجع العديد من عوامل التشغيل المنطقية القيمة 1 للقيمة الصحيحة، وسلسلة نصية فارغة للقيمة الخاطئة. defined()تُحدد الدالة ما إذا كان للمتغير أي قيمة مُعينة. في الأمثلة السابقة، defined($false)تكون القيمة صحيحة لجميع القيم باستثناء undef.

إذا كانت هناك حاجة محددة إلى 1 أو 0، فيمكن إجراء تحويل صريح باستخدام عامل التشغيل الشرطي :

my $real_result = $boolean_result ? 1 : 0 ;

قيم المصفوفة

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

@scores = ( 32 , 45 , 16 , 5 );

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

@names = ( 'Billy' , 'Joe' , 'Jim-Bob' ); @names = qw(Billy Joe Jim-Bob) ;

تقوم دالة التقسيم بإرجاع قائمة من السلاسل النصية، والتي يتم تقسيمها من تعبير نصي باستخدام سلسلة فاصلة أو تعبير نمطي.

@scores = split ( ',' , '32,45,16,5' );

يُمكن الوصول إلى عناصر القائمة الفردية بتحديد فهرس رقمي بين قوسين مربعين. يجب استخدام رمز المصفوفة . كما يُمكن تحديد القوائم الفرعية (شرائح المصفوفة) باستخدام نطاق أو قائمة من الفهارس الرقمية بين قوسين. في هذه الحالة، يُستخدم رمز المصفوفة. على سبيل المثال، $month[3]يكون "April"العنصر الأول في المصفوفة فهرسه 0، ويكون العنصر الثاني فهرسه @month[4..6]0 ("May", "June", "July").

قيم التجزئة

قد يقوم مبرمجو لغة بيرل بتهيئة جدول تجزئة (أو مصفوفة ترابطية ) من قائمة أزواج المفاتيح والقيم. إذا تم فصل المفاتيح عن القيم باستخدام =>عامل التشغيل (يُسمى أحيانًا فاصلة كبيرة )، بدلاً من الفاصلة العادية، فيمكن استخدام الكلمات غير المقتبسة (كلمات مجردة [ 5 ] ). الأسطر التالية متكافئة:

%favorite = ( 'joe' , "red" , 'sam' , "blue" ); %favorite = ( joe => 'red' , sam => 'blue' );

يُمكن الوصول إلى القيم الفردية في جدول التجزئة (hash) من خلال إدخال المفتاح المقابل، الموجود بين قوسين معقوفين. $يُشير الرمز (sigil) إلى العنصر الذي يتم الوصول إليه كقيمة عددية. على سبيل المثال، $favorite{joe}يساوي 'red'. كما يُمكن تهيئة جدول التجزئة (hash) عن طريق تعيين قيمه بشكل فردي.

$favorite { joe } = 'red' ; $favorite { sam } = 'blue' ; $favorite { oscar } = 'green' ;

يمكن الوصول إلى عناصر متعددة باستخدام @الرمز (مع تحديد النتيجة كقائمة). على سبيل المثال، @favorite{'joe', 'sam'}يساوي ('red', 'blue').

مقابض الملفات

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

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

قيم Typeglob

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

* PI = 3.141592653 ; # إنشاء قيمة عددية ثابتة $PI * this = * that ; # إنشاء أسماء بديلة لجميع أنواع البيانات 'this' لجميع أنواع البيانات 'that '

دوال المصفوفات

يمكن تحديد عدد عناصر المصفوفة إما بتقييم المصفوفة في سياق عددي أو باستخدام الرمز $#. يُعطي الرمز فهرس العنصر الأخير في المصفوفة، وليس عدد العناصر. التعبيران scalar( @array) و ( ) متكافئان.$#array + 1

دوال التجزئة

توجد بعض الدوال التي تعمل على جداول التجزئة الكاملة. تأخذ دالة `keys` جدول تجزئة وتعيد قائمة بمفاتيحه. وبالمثل، تعيد دالة ` values` قيم جدول التجزئة. لاحظ أن المفاتيح والقيم تُعاد بترتيب ثابت ولكنه عشوائي.

# كل استدعاء للدالة each يُعيد زوج المفتاح/القيمة التالي. # ستُعاد جميع القيم في النهاية، ولكن # لا يمكن التنبؤ بترتيبها. while (( $name , $address ) = each %addressbook ) { print "$name lives at $address\n" ; }# مشابه لما سبق، ولكن مُرتب أبجديًا foreach my $next_name ( sort keys %addressbook ) { print "$next_name lives at $addressbook{$next_name}\n" ; }

هياكل التحكم

تحتوي لغة بيرل على عدة أنواع من هياكل التحكم.

يحتوي على هياكل تحكم موجهة نحو الكتل، على غرار تلك الموجودة في لغات البرمجة C و JavaScript و Java . تُحاط الشروط بأقواس، وتُحاط الكتل المتحكم بها بأقواس معقوفة.

label while ( cond ) { ... } label while ( cond ) { ... } continue { ... } label for ( init-expr ; cond-expr ; incr-expr ) { ... } label foreach var ( list ) { ... } label foreach var ( list ) { ... } continue { ... } إذا ( الشرط ) { ... } إذا ( كان الشرط صحيحًا ) { ... } وإلا { ... } إذا ( كان الشرط صحيحًا ) { ... } وإذا ( كان الشرط صحيحًا ) { ... } وإلا { ... }

عندما يتم التحكم في عبارة واحدة فقط، فإن مُعدِّلات العبارات توفر صيغة أكثر إيجازًا:

عبارة if cond ; عبارة unless cond ; عبارة while cond ; عبارة until cond ; عبارة foreach list ;

تُستخدم عوامل التشغيل المنطقية ذات الدائرة القصيرة بشكل شائع للتأثير على تدفق التحكم على مستوى التعبير:

expr و expr expr && expr expr أو expr expr || expr

(تتشابه عوامل التشغيل "و" و "أو" مع عوامل التشغيل && و || ولكن لها أسبقية أقل ، مما يجعل استخدامها أسهل للتحكم في العبارات بأكملها.)

الكلمات الرئيسية للتحكم في التدفق next(المقابلة لـ C's continuelast(المقابلة لـ C's break) return، و redoهي تعبيرات، لذلك يمكن استخدامها مع عوامل التشغيل ذات الدائرة القصيرة.

تحتوي لغة بيرل أيضًا على بنيتين للتكرار الضمني، ولكل منهما شكلان:

النتائج = grep { ... } قائمة النتائج = grep expr ، قائمة النتائج = map { ... } قائمة النتائج = map expr ، قائمة

grepتُعيد هذه الدالة جميع عناصر القائمة التي يكون فيها تقييم الكتلة أو التعبير المُتحكَّم به صحيحًا. mapكما تُقيّم الكتلة أو التعبير المُتحكَّم به لكل عنصر من عناصر القائمة ، وتُعيد قائمة بالقيم الناتجة. تُتيح هذه البنى أسلوب برمجة وظيفية بسيطًا .

حتى إصدار 5.10.0، لم تكن هناك عبارة switch في لغة Perl 5. بدءًا من الإصدار 5.10.0، أصبحت عبارة التفرع متعددة الاتجاهات المسماة given/ whenمتاحة، والتي تأخذ الشكل التالي:

usev5.10;# must be present to import the new 5.10 functions معطى ( التعبير ) { عندما ( الشرط ) { ... } افتراضي { ... } }

من الناحية التركيبية، يتشابه هذا الهيكل مع عبارات switch الموجودة في لغات أخرى، ولكن مع بعض الاختلافات المهمة. أهمها أنه على عكس هياكل switch/case، فإن عبارات given/when توقف التنفيذ بعد أول تفرع ناجح، بدلاً من انتظار أوامر break محددة صراحةً. في المقابل، continueتُعد أوامر s الصريحة ضرورية لمحاكاة سلوك switch.

بالنسبة لمن لا يستخدمون بيرل 5.10، تشرح وثائق بيرل ست طرق لتحقيق نفس النتيجة باستخدام هياكل تحكم أخرى. يوجد أيضًا وحدة Switch، التي توفر وظائف مشابهة لتلك الموجودة في لغة Raku الشقيقة . يتم تنفيذها باستخدام مُرشِّح المصدر ، لذا يُنصح بعدم استخدامها بشكل غير رسمي. [ 6 ]

تتضمن لغة بيرل goto labelعبارة `a`، لكنها نادراً ما تُستخدم. فالحالات التي gotoتتطلب استخدام `a` في لغات أخرى لا تحدث بكثرة في بيرل، وذلك بفضل اتساع خيارات التحكم في التدفق المتاحة فيها.

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

البرامج الفرعية

تُعرَّف الإجراءات الفرعيةsub باستخدام الكلمة المفتاحية ويتم استدعاؤها ببساطة عن طريق تسميتها. إذا لم يتم تعريف الإجراء الفرعي المطلوب بعد، يتطلب استدعاؤه إما أقواسًا بعد اسم الدالة أو علامة العطف ( & ) قبله. ولكن استخدام & بدون أقواس سيؤدي ضمنيًا إلى تمرير وسائط الإجراء الفرعي الحالي إلى الإجراء المُستدعى، بينما استخدام & مع أقواس سيتجاوز النماذج الأولية.

# استدعاء روتين فرعي# الأقواس مطلوبة هنا إذا تم تعريف الروتين الفرعي لاحقًا في الكود foo (); & foo ; # (هذا يعمل أيضًا، ولكن له عواقب أخرى فيما يتعلق بالوسائط التي تم تمريرها إلى الروتين الفرعي)# تعريف روتين فرعي sub foo { }foo ; # هنا لا حاجة للأقواس

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

foo $x , @y , %z ;

لا يلزم تحديد عدد أو نوع معاملات الدالة الفرعية؛ بل قد تختلف من استدعاء لآخر. ويجب إجراء أي تحقق من صحة المعاملات بشكل صريح داخل الدالة الفرعية.

يتم توسيع المصفوفات إلى عناصرها؛ ويتم توسيع التجزئة إلى قائمة من أزواج المفاتيح/القيم؛ ويتم تمرير كل شيء إلى الروتين الفرعي كقائمة مسطحة واحدة من القيم العددية.

تُتاح جميع الوسائط المُمرَّرة للروتين الفرعي في المصفوفة الخاصة @_. عناصر هذه المصفوفة @_هي مراجع للوسائط الفعلية؛ تغيير أي عنصر منها @_يُغيِّر الوسيط المُقابل.

يمكن الوصول إلى عناصرها @_عن طريق كتابة رمزها السفلي بالطريقة المعتادة.

$_ [ 0 ], $_ [ 1 ]

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

من المصطلحات الشائعة تعيين قيمة @_لقائمة من المتغيرات المسماة.

my ( $x , $y , $z ) = @_ ;

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

هناك أسلوب آخر يتمثل في إزاحة المعاملات من @_. وهذا شائع بشكل خاص عندما تأخذ الدالة الفرعية وسيطًا واحدًا فقط أو لمعالجة $selfالوسيط في الوحدات البرمجية الموجهة للكائنات.

my $x = shift ;

قد تقوم الإجراءات الفرعية بتعيين @_قيمة إلى جدول تجزئة لمحاكاة الوسائط المسماة؛ وهذا ما يُوصى به في أفضل ممارسات بيرل للإجراءات الفرعية التي من المحتمل أن تحتوي على أكثر من ثلاثة معلمات. [ 7 ]

sub function1 { my %args = @_ ; print "'x' argument was '$args{x}'\n" ; } function1 ( x => 23 );

قد تُعيد الإجراءات الفرعية قيمًا.

return 42 , $x , @y , %z ;

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

يتم تقييم التعبير المُعاد في سياق استدعاء الروتين الفرعي؛ وهذا قد يفاجئ غير الحذرين.

قائمة فرعية { ( 4 ، 5 ، 6 ) } مصفوفة فرعية { @x = ( 4 ، 5 ، 6 @x }$x = list ; تُرجع 6 - العنصر الأخير في القائمة $x = array ; تُرجع 3 - عدد العناصر في القائمة @x = list ; تُرجع (4, 5, 6) @x = array ; تُرجع (4, 5, 6)

يمكن للروتين الفرعي اكتشاف سياق الاستدعاء الخاص به باستخدام wantarrayالدالة.

sub either { return wantarray ? ( 1 , 2 ) : 'Oranges' ; }$x = either ; تُرجع "برتقال" @x = either ; تُرجع (1، 2)

الوظائف المجهولة

يدعم Perl 5 الدوال المجهولة، [ 8 ] على النحو التالي:

( sub { print "تم استدعائي\n" }) -> (); # 1. مجهول الهوية تمامًا، يتم استدعاؤه عند إنشائهmy $squarer = sub { my $x = shift ; $x * $x }; # 2. تم تعيينه لمتغيردالة فرعية curry { my ( $sub , @args ) = @_ ; return sub { $sub -> ( @args , @_ ) }; # 3. كقيمة إرجاع لدالة أخرى }# مثال على تطبيق تقنية التخصيص الجزئي (currying) في برمجة بيرل: sub sum { my $tot = 0 ; $tot += $_ for @_ ; $tot } # تُعيد مجموع وسيطاتها my $curried = curry \& sum , 5 , 7 , 9 ; print $curried -> ( 1 , 2 , 3 ), "\n" ; # تطبع 27 ( = 5 + 7 + 9 + 1 + 2 + 3 )

تأخذ البنى الأخرى كتلًا مجردة كوسائط، والتي تؤدي وظيفة مشابهة لوظائف لامدا ذات المعلمة الواحدة، ولكنها لا تملك نفس اصطلاح تمرير المعلمات مثل الدوال - لا يتم تعيين @_.

my @squares = map { $_ * $_ } 1 .. 10 ; # لا تستخدم map و grep الكلمة المفتاحية 'sub' my @square2 = map $_ * $_ , 1 .. 10 ; # لا حاجة للأقواس في تعبير واحدmy @bad_example = map { print for @_ } 1 .. 10 ; # القيم لا تُمرر كدالة بيرل عادية

التعبيرات النمطية

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

استُمدّت صيغة التعبيرات النمطية في لغة بيرل في الأصل من التعبيرات النمطية في نظام يونكس الإصدار الثامن. إلا أنها تباينت قبل الإصدار الأول من بيرل، وتطورت منذ ذلك الحين لتشمل ميزات أكثر بكثير. وتتبنى العديد من اللغات والتطبيقات الأخرى الآن التعبيرات النمطية المتوافقة مع بيرل بدلاً من التعبيرات النمطية المتوافقة مع POSIX ، مثل PHP و Ruby و Java وإطار عمل .NET من مايكروسوفت ، [ 9 ] وخادم Apache HTTP .

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

الاستخدامات

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

$x =~ /abc/ ;

تكون النتيجة صحيحة إذا وفقط إذا تطابقت السلسلة $xمع التعبير النمطي abc.

أما عامل s///الاستبدال، من ناحية أخرى، فيحدد عملية البحث والاستبدال:

$x =~ s/abc/aBc/ ; # تحويل الحرف b إلى حرف كبير

ومن الاستخدامات الأخرى للتعبيرات النمطية تحديد الفواصل الخاصة بالدالة split:

@words = split /,/ , $line ;

تُنشئ الدالة splitقائمة بأجزاء السلسلة النصية المفصولة بما يطابق التعبير النمطي. في هذا المثال، يُقسّم السطر إلى قائمة من أجزائه المفصولة بفواصل، ثم تُسند هذه القائمة إلى المصفوفة @words.

بناء الجملة

المُعدِّلات

يمكن أن تأخذ التعابير النمطية في لغة بيرل مُعدِّلات . وهي عبارة عن لواحق من حرف واحد تُعدِّل معنى التعبير:

$x =~ /abc/i ; # مطابقة نمط غير حساسة لحالة الأحرف $x =~ s/abc/aBc/g ; # بحث واستبدال شامل

نظرًا لأنّ الصيغة المختصرة للتعبيرات النمطية قد تجعلها معقدة وغامضة، /xفقد أُضيف المُعدِّل في لغة بيرل لمساعدة المبرمجين على كتابة تعبيرات نمطية أكثر وضوحًا. يسمح هذا المُعدِّل للمبرمجين بوضع مسافات بيضاء وتعليقات داخل التعبيرات النمطية.

$x =~ / a # تطابق الحرف 'a' . # متبوعًا بأي حرف c # ثم متبوعًا بالحرف 'c' /x ;

التقاط

يمكن وضع أجزاء من التعبير النمطي بين قوسين؛ ويتم التقاط الأجزاء المقابلة من السلسلة المطابقة . تُسند السلاسل الملتقطة إلى المتغيرات المضمنة المتسلسلة $1, $2, $3, …، وتُعاد قائمة بالسلاسل الملتقطة كقيمة للمطابقة.

$x =~ /a(.)c/ ; # التقاط الحرف بين 'a' و 'c'

يمكن استخدام السلاسل النصية الملتقطة $1, $2, $3, …لاحقاً في الكود.

تسمح تعابير بيرل النمطية أيضًا بتطبيق الدوال المضمنة أو المعرفة من قبل المستخدم على التطابق الملتقط، وذلك باستخدام /eالمُعدِّل:

$x = "Oranges" ; $x =~ s/(ge)/uc($1)/e ; # OranGEs $x .= $1 ; # أضف إلى $x محتوى التطابق في العبارة السابقة: OranGEsge

أشياء

توجد طرق عديدة لكتابة التعليمات البرمجية الموجهة للكائنات في لغة بيرل. أبسطها استخدام المراجع "المُعَرَّفة" . تعمل هذه الطريقة بتحديد مرجع من أي نوع على أنه ينتمي إلى حزمة معينة، وتوفر هذه الحزمة الدوال اللازمة لهذا المرجع. على سبيل المثال، يمكن تعريف نقطة ثنائية الأبعاد على النحو التالي:

sub Point ::new { # هنا، Point->new(4, 5) ستؤدي إلى أن يكون $class هو 'Point'. # إنه متغير لدعم التوريث (انظر صفحة دليل perloop). my ( $class , $x , $y ) = @_ ; bless [ $x , $y ], $class ; # إرجاع ضمني }دالة فرعية Point ::distance { my ( $self , $from ) = @_ ; my ( $dx , $dy ) = ( $self [ 0 ] - $$from [ 0 ], $$self [ 1 ] - $$from [ 1 ]); sqrt ( $dx * $dx + $dy * $dy ); }

يمكن استخدام هذه الفئة عن طريق الاستدعاء new()لإنشاء مثيلات، والاستدعاء distanceعلى تلك المثيلات.

my $p1 = Point- > new ( 3 , 4 ); my $p2 = Point- > new ( 0 , 0 ); print $p1- > distance ( $p2 ); # يطبع 5

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

فئات موس:

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

أدوار الموظ:

  • الدور هو وظيفة تقوم بها فئة ما، يشبه إلى حد ما وظائف المزج أو الواجهات في لغات البرمجة الكائنية الأخرى. على عكس وظائف المزج والواجهات، يمكن تطبيق الأدوار على مثيلات الكائنات الفردية.
  • يحتوي الدور على صفر أو أكثر من السمات.
  • يحتوي الدور على صفر أو أكثر من الأساليب.
  • يحتوي الدور على صفر أو أكثر من مُعدِّلات الأساليب.
  • يحتوي الدور على صفر أو أكثر من الطرق المطلوبة.

أمثلة

مثال على فئة مكتوبة باستخدام امتداد MooseX::Declare [ 10 ] لـ Moose:

استخدم MooseX::Declare ؛ class Point3D extends Point { has 'z' => ( isa => 'Num' , is => 'rw' ); بعد المسح { $self- > z ( 0 ); } دالة set_to ( العدد $x ، العدد $y ، العدد $z ) { $self- > x ( $x$self- > y ( $y$self- > z ( $z )؛ } } 

هذا صنفٌ يُسمى صنفًا Point3Dآخر يُسمى صنفًا آخر Pointمُوضحًا في أمثلة Moose . يُضيف هذا الصنف إلى صنفه الأساسي سمةً جديدة z، ويُعيد تعريف الدالة set_to، ويُوسّع الدالة clear.

مراجع

  1. أوروانت، جون (2003). الألعاب، والتسلية، وثقافة بيرل: أفضل ما في مجلة بيرل . ISBN 978-0-596-00312-8.
  2. "الصفحة الرئيسية لـ CPAN" . تم الاطلاع عليها بتاريخ 2011-12-09 .
  3. "الميزات" . Perldoc . Perl.org . تم الاطلاع عليه بتاريخ 24 يوليو 2017 .
  4. "perlrun" . perldoc.perl.org - الوثائق الرسمية للغة برمجة بيرل . تم الاطلاع عليها بتاريخ 8 يناير 2011 .
  5. وينرايت، بيتر (2005). برو بيرل . سلسلة من المحترفين إلى الخبراء. أبريس. ص 64. ISBN  978-1-59059-438-4تم الاطلاع عليه بتاريخ 3 أغسطس 2010. [ ...] سلسلة نصية بدون علامات اقتباس، تُعرف باسم سلسلة الكلمات المجردة [...]
  6. باستخدام مفتاح التبديل
  7. داميان كونواي، أفضل ممارسات بيرل، مؤرشف في 18 سبتمبر 2011 على موقع Wayback Machine ، صفحة 182
  8. "perlsub - إجراءات فرعية في لغة بيرل - متصفح بيرلدوك" . perldoc.perl.org . تم الاطلاع عليه بتاريخ 24-11-2020 .
  9. شركة مايكروسوفت، "التعبيرات النمطية في إطار عمل .NET"، دليل مطوري إطار عمل .NET ،
  10. توثيق MooseX::Declare