docs:لماذا_بايثون
اختلافات
عرض الاختلافات بين النسخة المختارة و النسخة الحالية من الصفحة.
جانبي المراجعة السابقةالمراجعة السابقة | |||
docs:لماذا_بايثون [2010/02/13 13:08] – تدقيق djilani | docs:لماذا_بايثون [2015/04/23 03:19] (حالي) – تحرير خارجي 127.0.0.1 | ||
---|---|---|---|
سطر 1: | سطر 1: | ||
+ | {{tag> | ||
+ | |||
+ | ====== لماذا بايثون ؟ ====== | ||
+ | ===== حول هذه الوثيقة ===== | ||
+ | هذا مقال مترجم يتحدث عن أهمية لغة بايثون (ولا يشرح طريقة البدء بتعلمها) وما تمتاز بها مقابل لغات أخرى من وجهة نظر شخص يجيد عدد كبير من لغات بل كتب بنفسه عددا منها. | ||
+ | * تأليف: إريك ريموند Eric Raymond المعروف اختصاراً ESR وهو مؤيد ناشط لنظام لينكس ومؤلف The Cathedral & The Bazaar يمكن مراسلته على [[esr@thyrsus.com]] | ||
+ | * المقال الأصلي نشرته عدة مواقع منها | ||
+ | * http:// | ||
+ | * www.linuxjournal.com/ | ||
+ | |||
+ | |||
+ | ===== مقدمة ===== | ||
+ | |||
+ | نظرتي الأولى للغة بايثون كانت مصادفة، ولم أحب ما رأيته في ذاك الوقت كثيراً. وكان ذلك في بداية 1997، وقتها كان كتاب برمجة بايثون Programming Python لمؤلفه مارك لوتز Mark Lutz من أورالي قد صدر تواً. وكتب اورالي تأتي عتبتي من حين لآخر ينتقيها لي من بين إصداراتهم متبرع غامض داخل المؤسسة من خلال عملية عشوائية يأست من فهمها. | ||
+ | |||
+ | أحدها (كتاب من أورالي) كانت برمجة بايثون Programming Python. وقد وجدت هذا ممتعاً بطريقة ما، حيث أني أجمع لغات الحاسوب. فأنا أعرف أكثر من دزينتين من اللغات عامة الأغراض، وأكتب عدداً من المصنفات compilers والمفسرات interpreters للمتعة، وقد صممت أي عدد من اللغات خاصة الأهداف وأشكال الإرقام markup formalisms بنفسي. | ||
+ | آخر مشاريعي المكتملة أثناء كتابة هذه المقالة، لغة خاصة الأهداف اسمها SNG للتعامل مع ملفات صور PNG. إذا كنت مهتماً انظر للصفحة الرئيسية www.catb.org/ | ||
+ | |||
+ | \\ | ||
+ | \\ لقد سمعت بالفعل عن بايثون بما يكفي أن أعرف أنها -كما يسمى في وقتنا الحاضر- لغة نصية " | ||
+ | \\ | ||
+ | \\ | ||
+ | بيرل بالطبع ؛ هي عملاق برمجة السكربت الحديثة ، وقد حلت إلى حد كبير- محل لغة برمجة شل سكربت ، كخيار لمديري النظام . وذلك | ||
+ | \\ " | ||
+ | |||
+ | |||
+ | |||
+ | في ذلك الوقت ، كنت | ||
+ | |||
+ | وعلى الفور تعثرت بأول سمة من سمات بايثون الغريبة والتي يمكن للجميع ملاحظتها : وهي أن المسافات الفارغة (أو " | ||
+ | |||
+ | وأنا كبير بما يكفي أن أكون قد أمضيت شهورا من سبعينات القرن العشرين على فورتران. بعكس معظم الهاكرز هذه الأيام (الذين لم يتعاملوا مع فورتران). ومع ذلك يبدو أن ثقافتنا تميل -إلى حد ما- إلى الإبقاء على ذكرى دقيقة عن هذا الطراز القديم والكريه ذي الحقول الثابتة في لغات البرمجة((في فورتران 77 فإن أول 5 محارف إما أن تكون رقم العبارة أو مسافات ثم تليها في المحرف رقم 6 علامة متابعة السطر السابق ويبدأ الكود من المحرف السابع ولا يجوز أن يزيد عن المحرف رقم 72)). والواقع أن مصطلح " | ||
+ | |||
+ | وهذا بالتأكيد ما شعرت به. تصفحت شرح هذه اللغة على عجل دونما اهتمام كبير. ولم أر ما يمكن أن يزكي بايثون، عدا ما يبدو من كونها أنظف في الصياغة اللغوية من بيرل ، والتسهيلات التي تقدمها للعناصر الأساسية في الواجهة الرسومية للمستخدم مثل الأزرار والقوائم، والتي -بأمانة-تبدو جميلة. | ||
+ | |||
+ | أعدت الكتب إلى الرّف ملصقاً ملاحظة على عقلي بأن علي أن أكتب بعض الكود لبرنامج ذو واجهة رسومية GUI بلغة بايثون في وقت ما، لا لشيء إلا لأثبت أني فهمت اللغة. | ||
+ | لكني لم أكن مقتنعا أن ما رأيته منها يمكن أن ينافس بيرل. | ||
+ | |||
+ | ===== تكشف بيرل ===== | ||
+ | |||
+ | |||
+ | ولقد تآمرت كثير من الأمور الأخرى لإبقاء تلك الفكرة في ذيل قائمة أولوياتي لعدة أشهر. وقد كان ما تبقى من عام 1997 حافلا بالأحداث بالنسبة لي ، ومن ضمن الأمور الأخرى أنه العام الذي كتبت ونشرت فيه النص الأصلي لكتاب " | ||
+ | |||
+ | كتابة هذه البرامج ترك فيّ تدريجياً عدم رضى عن بيرل. كلما كبر حجم المشروع فإن المنغصات في بيرل تتضخم إلى مشاكل جدية ومستمرة. الصياغة التي بدت سلسة عند مئة سطر بدأت تصبح سياجاً منيعاً من الأشواك عند الألف. " | ||
+ | الذي يعطيني شعور بأنه هش ومتكلف وبني دون أساس. | ||
+ | |||
+ | |||
+ | هذه المشاكل مجتمعة تعطي أكواما كبيرة من كود بيرل صعب القراءة أو الفهم ككل دون مبرر حتى لو غبت عنه أيام قليلة من تاريخ كتابته. | ||
+ | كذلك وجدت أني أضيع الكثير من الوقت مصارعا اللغة أكثر مما أنفق من وقتي على التركيز في حل مشاكل التطبيق البرمجي. وأسوأ من كل هذا أنك تحصل على كود بشع " | ||
+ | |||
+ | وحيث أن جعبتي تحوي أكثر من دزينتين من اللغات وحيث أني قادر على اكتشاف كل ما ترويه علامات تصميم اللغة إن دفعت إلى أقصى حافة ما تنطوي عليه من وظائف. في منتصف العام الميلادي 1997 كنت أفكر "لا بد أن هناك طريقة أفضل" | ||
+ | |||
+ | ما لم يكن بحسباني هو العودة إلى سي كي تكون لغتي التلقائية. | ||
+ | لقد ولت الأيام التي كنت فيها تدير الذاكرة في برامجك بنفسك إلا مجالات متخصصة بعينها مثل النواة والحوسبة العلمية والرسم ثلاثي الأبعاد، تلكم الأماكن التي ينبغي عليك فيها الحصول على أقصى سرعة وأن تتحكم بدقائق استخدام الذاكرة حيث عليك أن تدفع بالعتاد بأقصى ما يمكن. | ||
+ | |||
+ | في أغلب الحالات على أجهزة اليوم فإنه من الجنون أن نقبل عبء التمحيص في زلاّت تجاوز حدود ذاكرة buffer | ||
+ | |||
+ | وبمجرد أن داعبت لغة Tcl اكتشفت بسرعة أنها لا تناسب المشاريع الكبيرة بطريقة أسوأ من بيرل. ولأني مبرمج LISP قديم فقد ألقيت نظرة على العديد من " | ||
+ | |||
+ | |||
+ | |||
+ | ===== إعادة النظر في بايثون ===== | ||
+ | |||
+ | نظرتي الثانية لبايثون كانت تقريبا صدفة كالصدفة الأولى. في تشرين الأول من عام 1997, حيث أظهرت سلسلة من الأسئلة على قائمة أصدقاء | ||
+ | | ||
+ | |||
+ | LISTING 1: fetchmail Configuration File | ||
+ | < | ||
+ | set postmaster " | ||
+ | set daemon 300 | ||
+ | poll imap.ccil.org with proto IMAP and options no dns | ||
+ | aka snark.thyrsus.com locke.ccil.org ccil.org | ||
+ | user esr there is esr here options fetchall dropstatus warnings 3600 | ||
+ | poll imap.netaxs.com with proto IMAP | ||
+ | user " | ||
+ | skip imap.21cn.com with proto IMAP | ||
+ | user esr here is tranxww there options fetchall | ||
+ | skip pop.tems.com with proto POP3: | ||
+ | user esr here is ed there options fetchall | ||
+ | skip mail.frequentis.com with proto IMAP: | ||
+ | user esr here is imaptest there with options fetchall | ||
+ | </ | ||
+ | |||
+ | قررت أن أهاجم المشكلة بكتابة محرر إعدادات صديق للمستخدم اسمه fetchmailconf. | ||
+ | وكان هدف التصميم واضحا: أن يخفي تماما تعقيدات صيغة ملف التحكم (الإعدادات) خلف واجهة رسومية أنيقة مزودة بأزرار التحديد والشرائط المنزلقة والنماذج التي يمكن ملؤها. | ||
+ | |||
+ | وفكرة تضمين هذا كله في بيرل لم أتحمس لها مطلقا. فقد رأيت كود الواجهة الرسومية في بيرل، وكان خليطا متنافرا بين بيرل وTcl. وبدا أبشع بكثير من كود بيرل الخالص الذي كتبته. وعند هذه النقطة تذكرت الجزء الذي كنت وضعته منذ أكثر من ستة شهور قبل ذلك. قد تكون هذه فرصة سانحة للحصول على بعض الخبرة العملية في بايثون. | ||
+ | |||
+ | وقطعا هذا أعادني وجها لوجه مرة أخرى إلى كون المسافة البادئة مهمة في بايثون. لكن هذه المرة استبقت ذلك بالتهام بعض الكود لبعض الأمثلة لعناصر من الواجهة الرسومية. الغريب أن استخدام بايثون للمسافات لم يعد غير طبيعي في أقل من 20 دقيقة. كل ما علي هو أن أنسق الكود كما كنت أفعل أنا بطبعي في سي بأي حال (مع أن سي لا تشترط ذلك) وكان الكود يعمل. | ||
+ | |||
+ | كانت تلك أول مفاجئة لي. الثانية جاءت بعد بضع ساعات في المشروع عندما لاحظت (وهذا سمح بوقفات لازمة كي أطّلع على مزايا جديدة في بايثون) أني كنت أكتب كودا يعمل تقريبا بالقدر الذي تسعفني فيه سرعتي في الطباعة. عندما أدركت هذا ذهلت. إن من أهم مقاييس الجهد اللازم لكتابة كود برنامج هو المقدار الذي تتكرر فيه حالة أن تكتب شيء ثم تدرك أنه لا يتطابق مع تصورك للمسألة وتحتاج أن تتراجع مدركا أن ما كتبته لم يخبر اللغة ما كنت تفكر فيه. وأما مقياس التصميم الجيد للغة هو أنه كلما وقع هفوات مثل هذه تكسب خبرة أكثر في اللغة. | ||
+ | |||
+ | فعندما تكتب كود بالقدر ذاته من سرعة طباعتك وعندما تكون الهفوات قريبة من الصفر فإن هذا يعني أنك أصبحت أستاذا في تلك اللغة. لكن هذا غير منطقي فهذا يومي الأول معها وأنا لا زلت أتوقف لأنظر في هذه اللغة الجديدة ومكتبتها! | ||
+ | |||
+ | كان هذا أول علامة دلتني على أني أمام تصميم استثنائي جيد في بايثون. | ||
+ | أغلب اللغات بها طاقة احتكاك تعرقل سرعتك وغرابة مزروعة في تصميمها تحتاج أن تتعلمها قبل أن ينخفض معدل هفواتك لرقم قريب من الصفر. | ||
+ | بايثون كان أول لغة برمجة عامة الأغراض شاهدتها قط عكست تلك العملية. | ||
+ | |||
+ | فأنا لم أستغرق وقتا في تعلم مزاياها. وها أنا ذا أكتب برنامج fetchmailconf عامل وفعّال بواجهة رسومية في 6 أيام عمل منها ما يقدر يومي عمل أمضيتهما في تعلم بايثون. | ||
+ | |||
+ | وهذا يعكس ميزة أخرى مفيدة لهذه اللغة: أنها مختزلة compact يمكنك أن تحتفظ في ذهنك بكل طاقم مزاياها (أو على الأقل بفهرس المفاهيم في مكتبتها). هذه أيضا من مزايا سي أما بيرل فقطعا لا لأن ذلك هو ثمن شعارها " | ||
+ | |||
+ | |||
+ | ===== حفراً إلى الأعماق ===== | ||
+ | أكبر لحظات الاكتشاف دراماتيكية تقع أمامنا. كان في تصميمي مشكلة: حيث من السهل أن أولد ملفات الإعدادات من الواجهة الرسومية GUI لكن تحريرها كان مسألة أصعب. بل تحديدا قراءة تلك الملفات إلى هيئة يمكن تحريرها تلك هي المشكلة. | ||
+ | برنامج الإعراب parser لهيئة ملفات إعدادات fetchmail دقيق جدا. كتب تحديدا على YACC و Lex أداتي يونكس الكلاسيكيتين لتوليد كود سي لإعراب اللغات. | ||
+ | من أجل أن يتمكن fetchmailconf من تحرير الإعدادات الحالية كنت أظن أنه علي أن أكرر كود الإعراب الدقيق في لغة بايثون. | ||
+ | لكني كنت أكره هذه الفكرة لأنها تتطلب الكثير من العمل ولأني لم أكن واثقا أن برنامجي إعراب منفصلتين في لغتين منفصلتين سينسجمان. آخر شيء قد أرغب به هو أن أضيف على نفسي تعب مواكبة البرنامجين لبعضهما البعض أثناء تطور لغة الإعدادات! | ||
+ | |||
+ | هذه المشكلة أربكتني لفترة. ثم فُتح علي: سأترك fetchmailconf | ||
+ | يستخدم نفس الإعراب الموجود داخل fetchmail! حيث أضفت خيارا اسمه --configdump إلى fetchmail يقوم فيه fetchmail بإعراب ملف الإعدادات | ||
+ | |||
+ | Listing 2: fetchmailrc | ||
+ | < | ||
+ | fetchmailrc = { | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | # List of server entries begins here | ||
+ | ' | ||
+ | # Entry for site `imap.ccil.org' | ||
+ | { | ||
+ | " | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | , ] | ||
+ | } | ||
+ | , | ||
+ | # Entry for site `imap.netaxs.com' | ||
+ | { | ||
+ | " | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | , ] | ||
+ | } | ||
+ | , | ||
+ | # Entry for site `imap.21cn.com' | ||
+ | { | ||
+ | " | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | , ] | ||
+ | } | ||
+ | , | ||
+ | # Entry for site `pop.tems.com' | ||
+ | { | ||
+ | " | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | , ] | ||
+ | } | ||
+ | , | ||
+ | # Entry for site `mail.frequentis.com' | ||
+ | { | ||
+ | " | ||
+ | ' | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | " | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | , ] | ||
+ | } | ||
+ | ] | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | عندها كل ما على بايثون أن تحسب evaluate تلك المخرجات وعندها ستكون الإعدادات هي قيمة المتغير fetchmail. | ||
+ | |||
+ | لم تكن هذه آخر خطوة في " | ||
+ | المثال كان عبارة عن 5 كائنات لمواقع يرتبط بكل واحد مستخدم. | ||
+ | |||
+ | لقد صممت وكتبت صنوف classes للكائنات الثلاثة (هذا ما استهلك 4 أيام أمضيت أغلبها أحاذي الودجات widgets). كل منها لها طريقة (أي دالة) تؤدي إلى إظهار لوحة تحرير تسمح بتحرير بيانات ذاك الكائن الفرد. أي أن كل ما بقي علي هو نقل البيانات المينة من استهلال متغير بايثون إلى كائنات حية. | ||
+ | |||
+ | لقد فكرت في كتابة كود يعلم صراحة بُنية الصنوف الثلاثة ويستخدم ما يعلمه عنها حتى يزحف داخل القيمة الاستهلالية وبناءً على ما يجد فيها ينشئ الكائنات. لكني رفضت تلك الفكرة لأنه من الوارد جدا ظهور عناصر جديدة في الصنوف مع مرور الوقت وزيادة المزايا في لغة الإعدادات. إن عملت كود إنشاء الكائنات بالطريقة البدهية ستكون هشة وتتقادم (تصبح أقدم وغير متزامنة) عند تغيير تعريف الصنوف أو بنية القيمة الاستهلالية. | ||
+ | |||
+ | ما كنت أريده كود يحلل استهلال المتغير شكلا ومضمونا، يستعلم عن تعريفات الصنوف أنفسها وعناصرها ويضبط قيمها لتطابق المجموعتين. | ||
+ | |||
+ | هذا النوع من الأشياء اسمه الصنوف الماورائية metaclass hacking وهو من الأسرار الرهيبة التي تقتصر على علية المبرمجين وكأنها السحر الأسود. | ||
+ | أغلب لغات البرمجة الكينونية لا تدعمها وتلك التي تدعمها (مثل بيرل) تكون معقدة وهشة وغير متعهدة بالعناية. | ||
+ | لقد أدهشتني بايثون بقلة الاحتكاك فيها (يقصد الإعاقة من طرف اللغة لانسياب الأفكار) | ||
+ | وها قد آن أوان اختبار حقيقي لها. كم من الجهد علي أن أبذل في مصارعة اللغة حتى أجعلها تقوم بذلك. | ||
+ | أعلم من خبرتي السابقة أن القتال سيكون مؤلما حتى لو كنت أنا الفائز، لكن ما أن غصت في الكتاب وقرأت عن تسهيلات الصنوف الماورائية في بايثون حتى كتبت الدالة في اللائحة 3 واستدعاءها في اللائحة 4. | ||
+ | |||
+ | Listing 3: Metaclass Function | ||
+ | <code python> | ||
+ | def copy_instance(toclass, | ||
+ | # Initialize a class object of given type from a conformant dictionary. | ||
+ | class_sig = toclass.__dict__.keys(); | ||
+ | dict_keys = fromdict.keys(); | ||
+ | common = intersect(class_sig, | ||
+ | if ' | ||
+ | class_sig.remove(' | ||
+ | if tuple(class_sig) != tuple(dict_keys): | ||
+ | print " | ||
+ | # print "Class signature: " + `class_sig` | ||
+ | # print " | ||
+ | print "Not matched in class signature: " + `setdiff(class_sig, | ||
+ | print "Not matched in dictionary keys: " + `setdiff(dict_keys, | ||
+ | sys.exit(1) | ||
+ | else: | ||
+ | for x in dict_keys: | ||
+ | setattr(toclass, | ||
+ | </ | ||
+ | |||
+ | Listing 4: Code that Calls Metaclass Function | ||
+ | <code python> | ||
+ | # The tricky part--initializing objects from the | ||
+ | # | ||
+ | # `Configuration' | ||
+ | # tree we're going to mung | ||
+ | Configuration = Controls() | ||
+ | copy_instance(Configuration, | ||
+ | Configuration.servers = []; | ||
+ | for server in configuration[`servers' | ||
+ | Newsite = Server() | ||
+ | copy_instance(Newsite, | ||
+ | Configuration.servers.append(Newsite) | ||
+ | Newsite.users = []; | ||
+ | for user in server[' | ||
+ | Newuser = User() | ||
+ | copy_instance(Newuser, | ||
+ | Newsite.users.append(Newuser) | ||
+ | </ | ||
+ | |||
+ | هذا لا يبدو سيئا لحيل السحر الأسود أليس كذلك ؟ | ||
+ | خلال 32 سطرا بما فيها التعليقات. من خلال معرفتي لما قلته عن تركيب الصنف لاحظ إن كود الاستدعاء مقروء. ليس حجم الكود هو الصدمة فحسب بل إنه يستحق عناقا! هذا الكود استغرقت في كتابته حوالي 90 دقيقة وقد عمل من أول تجربة لتنفيذه | ||
+ | |||
+ | |||
+ | ===== الخلاصة ===== | ||
+ | إن قلت أني ذهلت سيكون ذلك استهانة وتقليل من شأن بايثون. | ||
+ | من الجدير بالملاحظة أن تطبيق مهارات بسيطة تعمل تماما كما نتوقع من أول مرة. لكن أن تعمل معي metaclass hack في لغة جديدة علي من أول مرة خلال أقل 6 أيام من بدء تعلمي للغة؟ حتى لو افترضنا أني خارق/ | ||
+ | |||
+ | لا يوجد طريقة بسيطة كان يمكن أن أستل مثل تلك النتائج في بيرل مع خبرتي الطويلة فيها. كانت هذه النقطة التي أدركت فيها أن علي أن أترك لغة بيرل ورائي. | ||
+ | |||
+ | كانت تلك أكثر اللحظات دراماتيكية مع بايثون. لكن، بعد أن قلنا ذلك وانتهينا، كانت تلك حركة خرقة خاطفة ذكية. إلا أن فائدة أي لغة على المدى الطويل لا تأتي من دعمها للحيل الخارقة الخاطفة الذكية بل من جودة وبروز الأعمال الرتيبة اليومية التي يحتاجها المبرمج. | ||
+ | إن أعمال البرمجة الراتبة لا تتألف من كتابة برامج جديدة بل إن أغلبها من قراءة وتعديل برامج موجودة. | ||
+ | |||
+ | هذه هي الضربة الحقيقية لهذه القصة: بعد أسابيع وشهور من كتابة fetchmailconf، لا زلت أستطيع قراءة الكود واستيعاب ما كان الكود يعمل دون أي جهد عقلي جدي. | ||
+ | والسبب الحقيقي أني لم أعد أكتب برامج بلغة بيرل (إلا مشاريع متناهية الصغر) مع أني كنت اكتب أطنان من كود بيرل. أنا أهاب أن أجد نفسي في المستقبل مضطرا لتعديل كود | ||
+ | | ||
+ | |||
+ | لا زال هناك مكان للغة بيرل للمشاريع مفرطة الصغر (دون 100 سطر) | ||
+ | التي تتضمن الكثير من مطابقة أنماط النصوص حيث أني سأفضل حل عبر الأنماط القياسية في بيرل Perl-regexp مقابل بايثون. | ||
+ | من أمثلة ذلك ما كتبته مؤخرا كجزء من fetchmail مثل timeseries و growthplot. | ||
+ | في الحقيقة هذه الأشياء هي التي كانت تقوم بها بيرل منذ انطلاقتها كمزيج بين awk/ | ||
+ | |||