الفرق بين المراجعتين لصفحة: «Node.js/repl»
رهف-النجار (نقاش | مساهمات) ط تنسيق الكود |
رهف-النجار (نقاش | مساهمات) ط تنسيق |
||
(4 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:REPL}}</noinclude> | <noinclude>{{DISPLAYTITLE:الوحدة REPL في Node.js}}</noinclude> | ||
الاستقرار: 2-مستقر | الاستقرار: 2-مستقر | ||
سطر 6: | سطر 6: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= التصميم والميزات = | === التصميم والميزات === | ||
تُصدِّر الوحدة <code>repl</code> الصنف repl.REPLServer أثناء التنفيذ، سوف تقبل نسخ repl.REPLServer أسطرًا مفردةً من دخل المستخدم وتقيّمها تبعًا لدوال تقييم معرّفة من المستخدم ومن ثمّ تخرج الناتج. ربما يكون الدخل والخرج من <code>stdin</code> و <code>stdout</code>، على التوالي، ربما تكون متصلة بأي مجرى (stream) يتبع لبرمجية Node.js. | تُصدِّر الوحدة <code>repl</code> الصنف [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] أثناء التنفيذ، سوف تقبل نسخ [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] أسطرًا مفردةً من دخل المستخدم وتقيّمها تبعًا لدوال تقييم معرّفة من المستخدم ومن ثمّ تخرج الناتج. ربما يكون الدخل والخرج من <code>stdin</code> و <code>stdout</code>، على التوالي، ربما تكون متصلة بأي مجرى ([[Node.js/stream|stream]]) يتبع لبرمجية Node.js. | ||
تدعم نُسخ repl.REPLServer الإكمال التلقائي للدخل، وتعديل سطري بنمط برمجية Emacs (Emacs-style) البسيط، ودخل متعدد الأسطر، و خرج بأسلوب ANSI-styled، وحفظ واستعادة حالة جلسة REPL الحالية، وإصلاح الأخطاء، ودوال تقييم قابلة للتخصيص. | تدعم نُسخ [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] الإكمال التلقائي للدخل، وتعديل سطري بنمط برمجية Emacs (Emacs-style) البسيط، ودخل متعدد الأسطر، و خرج بأسلوب ANSI-styled، وحفظ واستعادة حالة جلسة REPL الحالية، وإصلاح الأخطاء، ودوال تقييم قابلة للتخصيص. | ||
= أوامر ومفاتيح خاصة = | ==== أوامر ومفاتيح خاصة ==== | ||
الأوامر الخاصة التالية مدعومة من قبل كل نُسخ REPL: | الأوامر الخاصة التالية مدعومة من قبل كل نُسخ REPL: | ||
* <code>.break</code>: في عملية إدخال تعبير متعدد الأسطر، سوف يوقف إدخال الأمر .break (أو الضغط على مجموعة المفاتيح <code><ctrl>-C</code>) الدخل الإضافي أو معالجة ذاك التعبير. | * <code>.break</code>: في عملية إدخال تعبير متعدد الأسطر، سوف يوقف إدخال الأمر .break (أو الضغط على مجموعة المفاتيح <code><ctrl>-C</code>) الدخل الإضافي أو معالجة ذاك التعبير. | ||
سطر 24: | سطر 24: | ||
دخول وضع التعديل (للانتهاء | //( ^C وللإلغاء ^D دخول وضع التعديل (للانتهاء | ||
function welcome(name) { | function welcome(name) { | ||
سطر 43: | سطر 43: | ||
* <code><tab></code>: عندما تُضغط على سطر فارغ، تعرض المتحولات العامة والمحلية (النطاق). عندما تُضغط أثناء ادخال دخل آخر، تعرض خيارات إكمال تلقائي ذات صلة. | * <code><tab></code>: عندما تُضغط على سطر فارغ، تعرض المتحولات العامة والمحلية (النطاق). عندما تُضغط أثناء ادخال دخل آخر، تعرض خيارات إكمال تلقائي ذات صلة. | ||
= التقييم الإفتراضي = | ==== التقييم الإفتراضي ==== | ||
بشكل افتراضي، تستخدم كل نسخ repl.REPLServer دالة تقييم والتي تقيّم تعابير JavaScript وتوفّر وصول إلى وحدات Node.js مُدمجة. يمكن أن يُعاد تعريف هذا السلوك الافتراضي بتمرير دالة تقييم بديلة عندما تُنشأ نسخة repl.REPLServer. | بشكل افتراضي، تستخدم كل نسخ [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] دالة تقييم والتي تقيّم تعابير JavaScript وتوفّر وصول إلى وحدات Node.js مُدمجة. يمكن أن يُعاد تعريف هذا السلوك الافتراضي بتمرير دالة تقييم بديلة عندما تُنشأ نسخة [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]]. | ||
== تعابير JavaScript == | ===== تعابير JavaScript ===== | ||
يدعم المقيّم الافتراضي تقييم مباشر لتعابير JavaScript:<syntaxhighlight lang="javascript"> | يدعم المقيّم الافتراضي تقييم مباشر لتعابير JavaScript:<syntaxhighlight lang="javascript"> | ||
> 1 + 1 | > 1 + 1 | ||
سطر 59: | سطر 59: | ||
إلّا إذا وسِّع من خلال كتل برمجية أو دوال، يُصرّح عن المتحولات المصرّح عنها في النطاق العام إما بشكل ضمني أو باستخدام الكلمات المفتاحية <code>const</code> أو <code>let</code> أو <code>var</code>. | إلّا إذا وسِّع من خلال كتل برمجية أو دوال، يُصرّح عن المتحولات المصرّح عنها في النطاق العام إما بشكل ضمني أو باستخدام الكلمات المفتاحية <code>const</code> أو <code>let</code> أو <code>var</code>. | ||
== النطاق العام والمحلي == | ===== النطاق العام والمحلي ===== | ||
يوفّر المقيّم الافتراضي وصولًا إلى أي متحول موجود في النطاق العام. من الممكن استخراج متحول إلى REPL بشكل صريح بإسناده إلى كائن <code>context</code> مترافق مع كل <code>REPLServer</code>:<syntaxhighlight lang="javascript"> | يوفّر المقيّم الافتراضي وصولًا إلى أي متحول موجود في النطاق العام. من الممكن استخراج متحول إلى REPL بشكل صريح بإسناده إلى كائن <code>context</code> مترافق مع كل <code>REPLServer</code>:<syntaxhighlight lang="javascript"> | ||
const repl = require('repl'); | const repl = require('repl'); | ||
سطر 87: | سطر 87: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== الوصول إلى نواة وحدات Node.js === | ===== الوصول إلى نواة وحدات Node.js ===== | ||
سوف يحمّل المقيّم الافتراضي تلقائيًا الوحدات الأساسية في Node.js إلى بيئة REPL عندما تُستخدم. على سبيل المثال، إلّا إذا صرّح عنها كمتحولات عامة أو متحولات نطاق. سوف يُقيّم الدخل <code>fs</code> عند الطلب كما يلي <code>global.fs = require('fs')</code>:<syntaxhighlight lang="javascript"> | سوف يحمّل المقيّم الافتراضي تلقائيًا الوحدات الأساسية في Node.js إلى بيئة REPL عندما تُستخدم. على سبيل المثال، إلّا إذا صرّح عنها كمتحولات عامة أو متحولات نطاق. سوف يُقيّم الدخل <code>fs</code> عند الطلب كما يلي <code>global.fs = require('fs')</code>:<syntaxhighlight lang="javascript"> | ||
> fs.createReadStream('./some/file'); | > fs.createReadStream('./some/file'); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== الاستثناءات العامة غير الملتقطة === | ===== الاستثناءات العامة غير الملتقطة ===== | ||
يستخدم REPL وحدة domain لإلتقاط كل الاستثناءات غير المُلتقطة من أجل جلسة REPL تلك. | يستخدم REPL وحدة [[Node.js/domain|domain]] لإلتقاط كل الاستثناءات غير المُلتقطة من أجل جلسة REPL تلك. | ||
يشتمل استخدام وحدة domain في REPL على هذه الآثار الجانبية: | يشتمل استخدام وحدة [[Node.js/domain|domain]] في REPL على هذه الآثار الجانبية: | ||
* الاستثناءات غير الملتقطة لا تطلق حدث 'uncaughtException'. | * الاستثناءات غير الملتقطة لا تطلق حدث [[Node.js/process#.D8.A7.D9.84.D8.AD.D8.AF.D8.AB .27uncaughtException.27|'uncaughtException']]. | ||
* ترمي محاولة استخدام process.setUncaughtExceptionCaptureCallback() الخطأ ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE. | * ترمي محاولة استخدام [[Node.js/process#process.setUncaughtExceptionCaptureCallback.28fn.E2.80.8E.29.E2.80.8E|process.setUncaughtExceptionCaptureCallback()]] الخطأ [[Node.js/errors#ERR DOMAIN CANNOT SET UNCAUGHT EXCEPTION CAPTURE.E2.80.8E|ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE]]. | ||
=== إسناد المتحول '_' (underscore) === | ===== إسناد المتحول '_' (underscore) ===== | ||
سجل التغييرات | سجل التغييرات | ||
{| class="wikitable" | |||
!الإصدار | |||
!التغييرات | |||
! | |||
! | |||
|- | |||
|التغييرات | |||
|أضيف دعم <code>_error</code> | |||
| | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
| | |||
| | |||
| | |||
| | |||
|} | |||
بشكل افتراضي، سوف يسند المقيّم الافتراضي قيمة أحدث تعبير مُقيّم إلى المتحول الخاص <code>_</code> (شرطة سفلية). ضبط <code>_</code> بشكل صريح إلى قيمة ما سوف يعطّل هذا السلوك.<syntaxhighlight lang="javascript"> | بشكل افتراضي، سوف يسند المقيّم الافتراضي قيمة أحدث تعبير مُقيّم إلى المتحول الخاص <code>_</code> (شرطة سفلية). ضبط <code>_</code> بشكل صريح إلى قيمة ما سوف يعطّل هذا السلوك.<syntaxhighlight lang="javascript"> | ||
> [ 'a', 'b', 'c' ] | > [ 'a', 'b', 'c' ] | ||
سطر 121: | سطر 141: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== الكلمة المفتاحية await === | ===== الكلمة المفتاحية <code>await</code> ===== | ||
مع خيار سطر الأوامر المُحدد --experimental-repl-await ، مُكّن الدعم التجريبي للكلمة المفتاحية <code>await</code>.<syntaxhighlight lang="javascript"> | مع خيار سطر الأوامر المُحدد [[Node.js/cli#.E2.80.8E--experimental-repl-await|--experimental-repl-await]] ، مُكّن الدعم التجريبي للكلمة المفتاحية <code>await</code>.<syntaxhighlight lang="javascript"> | ||
> await Promise.resolve(123) | > await Promise.resolve(123) | ||
123 | 123 | ||
سطر 136: | سطر 156: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== دوال تقييم مُخصصة == | ==== دوال تقييم مُخصصة ==== | ||
عندما تُنشأ نسخة جديدة من الكائن repl.REPLServer جديدة، ربما تُقدّم دوال تقييم مخصصة. يمكن أن يستخدم هذا على سبيل المثال، لتنفيذ تطبيقات REPL مخصصة بشكل كامل. | عندما تُنشأ نسخة جديدة من الكائن [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] جديدة، ربما تُقدّم دوال تقييم مخصصة. يمكن أن يستخدم هذا على سبيل المثال، لتنفيذ تطبيقات REPL مخصصة بشكل كامل. | ||
يشرح التالي مثال REPL نظري والذي ينجز ترجمةً لنص من لغة إلى أخرى:<syntaxhighlight lang="javascript"> | يشرح التالي مثال REPL نظري والذي ينجز ترجمةً لنص من لغة إلى أخرى:<syntaxhighlight lang="javascript"> | ||
سطر 153: | سطر 173: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== أخطاء يمكن إصلاحها == | ===== أخطاء يمكن إصلاحها ===== | ||
بما أنَّ المستخدم يكتب المدخلات ضمن مِحَث REPL، سوف يرسل ضغطُ المفتاح <code><enter></code> سطرَ المدخلات الحالية إلى دالة <code>eval</code>. بغية دعم المدخلات متعدد الأسطر، يمكن أن تعيد الدالة evalنسخة من الصنف <code>repl.Recoverable</code> إلى دالة رد النداء المتوافرة:<syntaxhighlight lang="javascript"> | بما أنَّ المستخدم يكتب المدخلات ضمن مِحَث REPL، سوف يرسل ضغطُ المفتاح <code><enter></code> سطرَ المدخلات الحالية إلى دالة <code>eval</code>. بغية دعم المدخلات متعدد الأسطر، يمكن أن تعيد الدالة evalنسخة من الصنف <code>repl.Recoverable</code> إلى دالة رد النداء المتوافرة:<syntaxhighlight lang="javascript"> | ||
function myEval(cmd, context, filename, callback) { | function myEval(cmd, context, filename, callback) { | ||
سطر 176: | سطر 196: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== تخصيص خرج REPL == | ==== تخصيص خرج REPL ==== | ||
افتراضيًا، تنسِّق النسخ repl.REPLServer الخرج باستخدام التابع util.inspect() قبل كتابة الخرج إلى المجرى <code>Writable</code> المُقدّم (يكون <code>process.stdout</code> افتراضيًا). يمكن أن يُحدَّد الخيار <code>useColors</code> المنطقي عند البناء ليأمر الكاتب الافتراضي باستخدام النمط ANSI المستعمل في تنسيق الشيفرات لتلوين خرج التابع <code>util.inspect()</code>. | افتراضيًا، تنسِّق النسخ [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] الخرج باستخدام التابع [[Node.js/util#util.inspect.28object.5B.2Coptions.5D.29.E2.80.8E .D9.88 util.inspect.28object.5B.2C showHidden.5B.2C depth.5B.2C colors.5D.5D.5D.29.E2.80.8E|util.inspect()]] قبل كتابة الخرج إلى المجرى <code>Writable</code> المُقدّم (يكون <code>process.stdout</code> افتراضيًا). يمكن أن يُحدَّد الخيار <code>useColors</code> المنطقي عند البناء ليأمر الكاتب الافتراضي باستخدام النمط ANSI المستعمل في تنسيق الشيفرات لتلوين خرج التابع <code>util.inspect()</code>. | ||
من الممكن تخصيص خرج النسخة repl.REPLServer بشكل كامل عن طريق تمرير دالة جديدة إليه باستخدام الخيار <code>writer</code> عند البناء. على سبيل المثال، يحوّل المثال التالي أي نص مدخل إلى حالة الأحرف الكبيرة:<syntaxhighlight lang="javascript"> | من الممكن تخصيص خرج النسخة [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]] بشكل كامل عن طريق تمرير دالة جديدة إليه باستخدام الخيار <code>writer</code> عند البناء. على سبيل المثال، يحوّل المثال التالي أي نص مدخل إلى حالة الأحرف الكبيرة:<syntaxhighlight lang="javascript"> | ||
const repl = require('repl'); | const repl = require('repl'); | ||
سطر 193: | سطر 213: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= الصنف REPLServer = | === الصنف <code>REPLServer</code> === | ||
أضيف في الإصدار: 0.1.91 | أضيف في الإصدار: 0.1.91 | ||
يرث الصنف <code>repl.REPLServer</code> من الصنف readline.Interface. تُنشَأ النُسخ <code>repl.REPLServer</code> باستخدام التابع <code>repl.start()</code> ولا ينبغي أن تُنشَأ بشكل مباشر باستخدام كلمة JavaScript المفتاحية <code>new</code>. | يرث الصنف <code>repl.REPLServer</code> من الصنف [[Node.js/readline#.D8.A7.D9.84.D8.B5.D9.86.D9.81: Interface|readline.Interface]]. تُنشَأ النُسخ <code>repl.REPLServer</code> باستخدام التابع <code>repl.start()</code> ولا ينبغي أن تُنشَأ بشكل مباشر باستخدام كلمة JavaScript المفتاحية <code>new</code>. | ||
== الحدث 'exit' == | ==== الحدث <code>'exit'</code> ==== | ||
أضيف في الإصدار: 0.7.7. | أضيف في الإصدار: 0.7.7. | ||
سطر 209: | سطر 229: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== الحدث: 'reset' == | ==== الحدث: <code>'reset'</code> ==== | ||
أضيف في الإصدار: 0.11.0 | أضيف في الإصدار: 0.11.0 | ||
سطر 241: | سطر 261: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== replServer.defineCommand(keyword, cmd) == | ==== <code>replServer.defineCommand(keyword, cmd)</code> ==== | ||
أضيف في الإصدار: 0.3.0. | أضيف في الإصدار: 0.3.0. | ||
* <code>keyword</code>: <string> الكلمة المفتاحية للأمر (دون المحرف <code>.</code> الافتتاحي). | * <code>keyword</code>: [[JavaScript/String|<string>]] الكلمة المفتاحية للأمر (دون المحرف <code>.</code> الافتتاحي). | ||
* <code>Cmd</code>: <Object> | <Function> الدالة المراد استدعاؤها عندما يُعالَج الأمر. | * <code>Cmd</code>: [[JavaScript/Object|<Object>]] | [[JavaScript/Function|<Function>]] الدالة المراد استدعاؤها عندما يُعالَج الأمر. | ||
يُستخدَم التابع <code>replServer.defineCommand()</code> لإضافة أمر جديد مسبوق بنقطة <code>.</code> إلى نسخة REPL. تُستدعى مثل هذه الأوامر بكتابة <code>.</code> متبوعة بالكلمة <code>keyword</code>. تكون <code>cmd</code> إمّا <code>Function</code> أو <code>Object</code> مع الخاصيات التالية: | يُستخدَم التابع <code>replServer.defineCommand()</code> لإضافة أمر جديد مسبوق بنقطة <code>.</code> إلى نسخة REPL. تُستدعى مثل هذه الأوامر بكتابة <code>.</code> متبوعة بالكلمة <code>keyword</code>. تكون <code>cmd</code> إمّا <code>Function</code> أو <code>Object</code> مع الخاصيات التالية: | ||
* <code>help</code>: <string> نص مساعدة المراد عرضه عندما يُكتَب <code>.help</code> (اختياري). | * <code>help</code>: [[JavaScript/String|<string>]] نص مساعدة المراد عرضه عندما يُكتَب <code>.help</code> (اختياري). | ||
* <code>action</code>: <Function> الدالة المراد تنفيذها. تقبل اختياريًا سلسلة نصية كوسيط وحيد. | * <code>action</code>: [[JavaScript/Function|<Function>]] الدالة المراد تنفيذها. تقبل اختياريًا سلسلة نصية كوسيط وحيد. | ||
يُظهِر المثال التالي أمرين جديدين مضافين إلى نسخة REPL:<syntaxhighlight lang="javascript"> | يُظهِر المثال التالي أمرين جديدين مضافين إلى نسخة REPL:<syntaxhighlight lang="javascript"> | ||
const repl = require('repl'); | const repl = require('repl'); | ||
سطر 272: | سطر 292: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== replServer.displayPrompt([preserveCursor]) == | ==== <code>replServer.displayPrompt([preserveCursor])</code> ==== | ||
أضيف في الإصدار: 0.1.91. | أضيف في الإصدار: 0.1.91. | ||
* <code>preserveCursor</code>: <boolean> | * <code>preserveCursor</code>: [[JavaScript/Boolean|<boolean>]] | ||
يُعِدُّ التابع <code>replServer.displayPrompt()</code> نسخة REPL لاستقبال المدخلات من المستخدم، ثم طباعة <code>prompt</code> بعد ضبطه إلى سطر جديد في الخرج <code>output</code> ثم استئناف الدخل <code>input</code> لقبول مدخلات جديدة. | يُعِدُّ التابع <code>replServer.displayPrompt()</code> نسخة REPL لاستقبال المدخلات من المستخدم، ثم طباعة <code>prompt</code> بعد ضبطه إلى سطر جديد في الخرج <code>output</code> ثم استئناف الدخل <code>input</code> لقبول مدخلات جديدة. | ||
سطر 283: | سطر 303: | ||
الغرض من التابع <code>replServer.displayPrompt</code> في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع <code>replServer.defineCommand()</code>. | الغرض من التابع <code>replServer.displayPrompt</code> في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع <code>replServer.defineCommand()</code>. | ||
== replServer.clearBufferedCommand() == | ==== <code>replServer.clearBufferedCommand()</code> ==== | ||
أضيف في الإصدار: 9.0.0. | أضيف في الإصدار: 9.0.0. | ||
يمسح التابع <code>replServer.clearBufferedCommand()</code> أي أوامر خُزّنت مؤقتًا ولكنَّها لم تُنفّذ بعد. الغرض من هذا التابع في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع <code>replServer.defineCommand()</code>. | يمسح التابع <code>replServer.clearBufferedCommand()</code> أي أوامر خُزّنت مؤقتًا ولكنَّها لم تُنفّذ بعد. الغرض من هذا التابع في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع <code>replServer.defineCommand()</code>. | ||
== replServer.parseREPLKeyword(keyword[, rest]) == | ==== <code>replServer.parseREPLKeyword(keyword[, rest])</code> ==== | ||
الاستقرار: 0-مهمل. | الاستقرار: 0-مهمل. | ||
أضيف في الإصدار: 0.8.9.أهمل منذ الإصدار: 9.0.0. | أضيف في الإصدار: 0.8.9.أهمل منذ الإصدار: 9.0.0. | ||
* <code>keyword</code>: <string> الكلمة المفتاحية المرتقبة للتحليل والتنفيذ. | * <code>keyword</code>: [[JavaScript/String|<string>]] الكلمة المفتاحية المرتقبة للتحليل والتنفيذ. | ||
* <code>rest</code>: <any> أي معاملات للكلمة المفتاحية keyword. | * <code>rest</code>: [[dfgsgf|<any>]] أي معاملات للكلمة المفتاحية keyword. | ||
* القيمة المعادة: <boolean> | * القيمة المعادة: [[JavaScript/Boolean|<boolean>]] | ||
تابع داخلي يُستخدَم لتحليل وتنفيذ كلمات <code>REPLServer</code> المفتاحية. يعيد القيمة <code>true</code> إذا كانت الكلمة المفتاحية <code>keyword</code> صالحة، وإلّا سيعيد القيمة <code>false</code>. | تابع داخلي يُستخدَم لتحليل وتنفيذ كلمات <code>REPLServer</code> المفتاحية. يعيد القيمة <code>true</code> إذا كانت الكلمة المفتاحية <code>keyword</code> صالحة، وإلّا سيعيد القيمة <code>false</code>. | ||
= repl.start([options]) = | === <code>repl.start([options])</code> === | ||
سجل التغييرات | سجل التغييرات | ||
* <code>options</code>: <Object> | <string> | {| class="wikitable" | ||
** <code>prompt</code>: <string> مِحثّ الإدخال المراد إظهاره. القيمة الإفتراضية: <code>'> '</code> (مع مسافة زائدة) | !الإصدار | ||
** <code>input</code>: <stream.Readable> المجرى <code>Readable</code> الذي سيُقرأ منه دخل REPL. القيمة الإفتراضية | !التغييرات | ||
** <code>output</code>: <stream.Writable> المجرى <code>Writable</code> الذي سيكتب إليه خرج REPL. '''القيمة الافتراضية:''' <code>process.stdout</code>. | ! | ||
** <code>terminal</code>: <boolean> قيمة منطقية إذا كانت <code>true</code>، تحدِّد أنّ <code>output</code> ينبغي أن يُعامل كطرفية TTY، ويمتلك شيفرات هروب ANSI/VT100 مكتوبة له. القيمة الافتراضية له تعتمد على قيمة الخاصية <code>isTTY</code> على المجرى <code>output</code>. | ! | ||
** <code>eval</code>: <Function> الدالة التي ستُستخدم عند تقييم كل سطر مُعطَى من الدخل. القيمة الإفتراضية هي: مغلف (wrapper) غير متزامن للدالة <code>eval()</code> الموجودة في JavaScript. يمكن أن تخطئ دالة eval مع <code>repl.Recoverable</code> لتشير إلى أنَّ الدخل غير مُكتمل وتُظهر أسطر إضافية. | |- | ||
** <code>useColors</code>: <boolean> قيمة منطقية إذا كانت <code>true</code>، تشير إلى أنَّ الدالة <code>writer</code> الافتراضية ينبغي أن تتضمن نمط الألوان ANSI في خرج REPL. إذا أعطيت دالة writer مُخصَّصة، فليس لهذا الخيار عند ذلك أي تأثير. القيمة الإفتراضية | |10.0.0 | ||
** <code>useGlobal</code>: <boolean> قيمة منطقية إذا كانت <code>true</code>، فستشير إلى أنّ تابع التقييم الافتراضي سيستخدم global التي تخص JavaScript كسياق في مقابل إنشاء سياق منفصل جديد لنسخة REPL. تضبط العقدة CLI REPL هذه القيمة إلى <code>true</code>. '''القيمة الافتراضية''' | |أزيل الخيار <code>REPL_MAGIC_MODE replMode</code> | ||
** <code>ignoreUndefined</code>: <boolean> قيمة منطقية إذا كانت <code>true</code>، فستشير إلى أنَّ الكاتب الافتراضي لن يُظهِر قيمة الأمر المُعادة إذا قُيّمت على أنَّها غير معرّفة (<code>undefined</code>). القيمة الافتراضية | | | ||
** <code>writer</code>: <Function> دالة يراد استدعاؤها لتنسيق المخرجات لكل أمر قبل كتابته إلى الخرج <code>output</code>.'''القيمة الافتراضية''' | | | ||
** <code>completer</code>: <Function> دالة اختيارية تُستخدم للإكمال التلقائي عبر المفتاح Tap. انظر التابع readline.InterfaceCompleter على سبيل المثال. | |- | ||
** <code>replMode</code>: <symbol> راية تحدِّد فيما اذا كان المقيّم الافتراضي ينفذ كل أوامر JavaScript في النمط الصارم أو النمط الافتراضي (المتساهل). القيم المقبولة لاستعمالها مع الخيار هي: | |5.8.0 | ||
|أصبح المعامل <code>options</code> اختياريًا الآن. | |||
| | |||
| | |||
|- | |||
|0.1.91 | |||
|أُضيف هذا التابع. | |||
| | |||
| | |||
|} | |||
* <code>options</code>: [[JavaScript/Object|<Object>]] | [[JavaScript/String|<string>]] | |||
** <code>prompt</code>: [[JavaScript/String|<string>]] مِحثّ الإدخال المراد إظهاره. '''القيمة الإفتراضية:''' <code>'> '</code> (مع مسافة زائدة) | |||
** <code>input</code>: [[dfgfgds|<stream.Readable>]] المجرى <code>Readable</code> الذي سيُقرأ منه دخل REPL. '''القيمة الإفتراضية:''' <code>process.stdin</code>. | |||
** <code>output</code>: [[dfzdsg|<stream.Writable>]] المجرى <code>Writable</code> الذي سيكتب إليه خرج REPL. '''القيمة الافتراضية:''' <code>process.stdout</code>. | |||
** <code>terminal</code>: [[JavaScript/Boolean|<boolean>]] قيمة منطقية إذا كانت <code>true</code>، تحدِّد أنّ <code>output</code> ينبغي أن يُعامل كطرفية TTY، ويمتلك شيفرات هروب ANSI/VT100 مكتوبة له. '''القيمة الافتراضية''' له تعتمد على قيمة الخاصية <code>isTTY</code> على المجرى <code>output</code>. | |||
** <code>eval</code>: [[JavaScript/Function|<Function>]] الدالة التي ستُستخدم عند تقييم كل سطر مُعطَى من الدخل. القيمة الإفتراضية هي: مغلف (wrapper) غير متزامن للدالة <code>eval()</code> الموجودة في JavaScript. يمكن أن تخطئ دالة eval مع <code>repl.Recoverable</code> لتشير إلى أنَّ الدخل غير مُكتمل وتُظهر أسطر إضافية. | |||
** <code>useColors</code>: [[JavaScript/Boolean|<boolean>]] قيمة منطقية إذا كانت <code>true</code>، تشير إلى أنَّ الدالة <code>writer</code> الافتراضية ينبغي أن تتضمن نمط الألوان ANSI في خرج REPL. إذا أعطيت دالة writer مُخصَّصة، فليس لهذا الخيار عند ذلك أي تأثير. '''القيمة الإفتراضية''': قيمة النُسَخ <code>terminal</code> في REPL. | |||
** <code>useGlobal</code>: [[JavaScript/Boolean|<boolean>]] قيمة منطقية إذا كانت <code>true</code>، فستشير إلى أنّ تابع التقييم الافتراضي سيستخدم global التي تخص JavaScript كسياق في مقابل إنشاء سياق منفصل جديد لنسخة REPL. تضبط العقدة CLI REPL هذه القيمة إلى <code>true</code>. '''القيمة الافتراضية:''' <code>false</code>. | |||
** <code>ignoreUndefined</code>: [[JavaScript/Boolean|<boolean>]] قيمة منطقية إذا كانت <code>true</code>، فستشير إلى أنَّ الكاتب الافتراضي لن يُظهِر قيمة الأمر المُعادة إذا قُيّمت على أنَّها غير معرّفة (<code>undefined</code>). '''القيمة الافتراضية:''' <code>false</code>. | |||
** <code>writer</code>: [[JavaScript/Function|<Function>]] دالة يراد استدعاؤها لتنسيق المخرجات لكل أمر قبل كتابته إلى الخرج <code>output</code>.'''القيمة الافتراضية:''' [[Node.js/util#util.inspect.28object.5B.2Coptions.5D.29.E2.80.8E .D9.88 util.inspect.28object.5B.2C showHidden.5B.2C depth.5B.2C colors.5D.5D.5D.29.E2.80.8E|util.inspect()]]. | |||
** <code>completer</code>: [[JavaScript/Function|<Function>]] دالة اختيارية تُستخدم للإكمال التلقائي عبر المفتاح Tap. انظر التابع [[sdkfl\lfkjs|readline.InterfaceCompleter]] على سبيل المثال. | |||
** <code>replMode</code>: [[JavaScript/symbol|<symbol>]] راية تحدِّد فيما اذا كان المقيّم الافتراضي ينفذ كل أوامر JavaScript في النمط الصارم أو النمط الافتراضي (المتساهل). القيم المقبولة لاستعمالها مع الخيار هي: | |||
*** <code>repl.REPL_MODE_SLOPPY</code>: تقيّم التعابير في النمط المتساهل. | *** <code>repl.REPL_MODE_SLOPPY</code>: تقيّم التعابير في النمط المتساهل. | ||
*** <code>repl.REPL_MODE_STRICT</code>: تقيّم التعابير في النمط الصارم. هذا مكافئ لاستهلال كل عبارة repl بالعبارة <code>'use strict'</code>. | *** <code>repl.REPL_MODE_STRICT</code>: تقيّم التعابير في النمط الصارم. هذا مكافئ لاستهلال كل عبارة repl بالعبارة <code>'use strict'</code>. | ||
** <code>breakEvalOnSigint</code>: يوقف تقييم القطعة الحالية من الشيفرة عند استقبال الإشارة <code>SIGINT</code>، أي ضُغِطَ المفتاحان <code>Ctrl+C</code>. لايمكن أن يُستخدَم هذا الخيار في نفس الوقت مع الخيار <code>eval</code>. '''القيمة الافتراضية''' هي: <code>false</code>. | ** <code>breakEvalOnSigint</code>: يوقف تقييم القطعة الحالية من الشيفرة عند استقبال الإشارة <code>SIGINT</code>، أي ضُغِطَ المفتاحان <code>Ctrl+C</code>. لايمكن أن يُستخدَم هذا الخيار في نفس الوقت مع الخيار <code>eval</code>. '''القيمة الافتراضية''' هي: <code>false</code>. | ||
يُنشئ التابع <code>repl.start()</code> ويبدأ النسخة repl.REPLServer. | يُنشئ التابع <code>repl.start()</code> ويبدأ النسخة [[Node.js/repl#.D8.A7.D9.84.D8.B5.D9.86.D9.81 REPLServer|repl.REPLServer]]. | ||
إذا كان المعامل <code>options</code> سلسلةً نصيةً (string)، فسيُحدِّد محثّ الإدخال:<syntaxhighlight lang="javascript"> | إذا كان المعامل <code>options</code> سلسلةً نصيةً (string)، فسيُحدِّد محثّ الإدخال:<syntaxhighlight lang="javascript"> | ||
سطر 324: | سطر 365: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== الوحدة REPL في Node.js == | === الوحدة REPL في Node.js === | ||
تستخدم Node.js بحدِّ ذاتها الوحدة <code>repl</code> لتوفير واجهة تفاعلية لها لتنفيذ JavaScript. يمكن أن يستخدم هذا عن طريق تنفيذ شيفرة Node.js التنفيذية دون تمرير أي وسائط (أو بتمرير الوسيط <code>-i</code>):<syntaxhighlight lang="javascript"> | تستخدم Node.js بحدِّ ذاتها الوحدة <code>repl</code> لتوفير واجهة تفاعلية لها لتنفيذ JavaScript. يمكن أن يستخدم هذا عن طريق تنفيذ شيفرة Node.js التنفيذية دون تمرير أي وسائط (أو بتمرير الوسيط <code>-i</code>):<syntaxhighlight lang="javascript"> | ||
$ node | $ node | ||
سطر 340: | سطر 381: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== خيارات متحولات البيئة === | ==== خيارات متحولات البيئة ==== | ||
يمكن تخصيص سلوكيات الوحدة REPL في Node.js باستخدام متغيرات البيئة التالية: | يمكن تخصيص سلوكيات الوحدة REPL في Node.js باستخدام متغيرات البيئة التالية: | ||
* <code>NODE_REPL_HISTORY</code>: عندما يُعطى مسار صالح، سيُحفظ تاريخ REPL الدائم إلى الملف الذي يشير إليه هذا المسار بدلًا من حفظه في المجلد <code>.node_repl_history</code> في المجلد home للمستخدم. ضبط هذه القيمة إلى <code>' '</code> سوف يعطّل تاريخ REPL الدائم. ستُزال المسافات البيضاء من القيمة. | * <code>NODE_REPL_HISTORY</code>: عندما يُعطى مسار صالح، سيُحفظ تاريخ REPL الدائم إلى الملف الذي يشير إليه هذا المسار بدلًا من حفظه في المجلد <code>.node_repl_history</code> في المجلد home للمستخدم. ضبط هذه القيمة إلى <code>' '</code> سوف يعطّل تاريخ REPL الدائم. ستُزال المسافات البيضاء من القيمة. | ||
* <code>NODE_REPL_HISTORY_SIZE</code>: يتحكم بعدد أسطر التاريخ (history) التي ستُحفَظ اذا كان التاريخ متوافرًا. يجب أن تكون عددًا موجبًا. '''القيمة الافتراضية''' هي: <code>1000</code> | * <code>NODE_REPL_HISTORY_SIZE</code>: يتحكم بعدد أسطر التاريخ (history) التي ستُحفَظ اذا كان التاريخ متوافرًا. يجب أن تكون عددًا موجبًا. '''القيمة الافتراضية''' هي: <code>1000</code> | ||
* <code>NODE_REPL_MODE</code>: إمّا أن تكون <code>'sloppy'</code> أو <code>'strict'</code>. القيمة الافتراضية | * <code>NODE_REPL_MODE</code>: إمّا أن تكون <code>'sloppy'</code> أو <code>'strict'</code>. '''القيمة الافتراضية:''' <code>'sloppy'</code>، والتي ستسمح بتنفيذ شيفرات النمط غير الصارم. | ||
=== التاريخ الدائم === | ==== التاريخ الدائم ==== | ||
افتراضيًّا، ستبقي Node.js REPL التاريخ بين جلسات <code>node</code> REPL عن طريق حفظ المدخلات إلى المف <code>.node_repl_history</code> المتوضع في المجلد home للمستخدم. يمكن أن يُعطَّل ذلك بضبط متغير البيئة بالشكل <code>NODE_REPL_HISTORY=<nowiki>''</nowiki></code>. | افتراضيًّا، ستبقي Node.js REPL التاريخ بين جلسات <code>node</code> REPL عن طريق حفظ المدخلات إلى المف <code>.node_repl_history</code> المتوضع في المجلد home للمستخدم. يمكن أن يُعطَّل ذلك بضبط متغير البيئة بالشكل <code>NODE_REPL_HISTORY=<nowiki>''</nowiki></code>. | ||
=== استخدام Node.js REPL مع محرر سطري متقدم === | ==== استخدام Node.js REPL مع محرر سطري متقدم ==== | ||
من أجل محررات الأسطر المتقدّمة، ابدأ Node.js مع متغير البيئة <code>NODE_NO_READLINE=1</code> . هذا سوف يبدأ main والمنقّح (debugger) الذي يخص REPL في إعدادات طرفية معيارية، والتي ستسمح بالاستخدام مع <code>rlwrap</code>. | من أجل محررات الأسطر المتقدّمة، ابدأ Node.js مع متغير البيئة <code>NODE_NO_READLINE=1</code> . هذا سوف يبدأ main والمنقّح (debugger) الذي يخص REPL في إعدادات طرفية معيارية، والتي ستسمح بالاستخدام مع <code>rlwrap</code>. | ||
سطر 356: | سطر 397: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== بدء عدّة نسخ REPL مقابل نسخة شغالة وحيدة === | ==== بدء عدّة نسخ REPL مقابل نسخة شغالة وحيدة ==== | ||
من الممكن إنشاء وتشغيل عدة نُسخ REPL مقابل نسخة Node.js شغّالة وحيدة والتي تشارك كائن <code>global</code> وحيد ولكن تمتلك عدة واجهات دخل/خرج (I/O). | من الممكن إنشاء وتشغيل عدة نُسخ REPL مقابل نسخة Node.js شغّالة وحيدة والتي تشارك كائن <code>global</code> وحيد ولكن تمتلك عدة واجهات دخل/خرج (I/O). | ||
سطر 398: | سطر 439: | ||
ببدء REPL من خادم يعتمد على مقبس يونكس بدلًا من مجرى الدخل القياسي، يمكن الاتصال بعملية Node.js شغالة لمدة طويلة دون إعادة تشغيلها. | ببدء REPL من خادم يعتمد على مقبس يونكس بدلًا من مجرى الدخل القياسي، يمكن الاتصال بعملية Node.js شغالة لمدة طويلة دون إعادة تشغيلها. | ||
مثالٌ عن تشغيل | مثالٌ عن تشغيل طرفيةREPL (<code>terminal</code>) "كاملة المواصفات" عبر النسخة <code>net.Server</code> والنسخة <code>net.Socket</code>، تجده في [https://gist.github.com/TooTallNate/2209310 هذه] الصفحة. مثالٌ آخر عن تشغيل نسخة REPL عبر [http://man7.org/linux/man-pages/man1/curl.1.html curl(1)]، تجده في [https://gist.github.com/TooTallNate/2053342 هذه] الصفحة. | ||
== مصادر == | === مصادر === | ||
[https://nodejs.org/dist/latest-v10.x/docs/api/repl.html صفحة REPL في توثيق Node.js الرسمي.] | [https://nodejs.org/dist/latest-v10.x/docs/api/repl.html صفحة REPL في توثيق Node.js الرسمي.] | ||
[[تصنيف:Node.js]] |
المراجعة الحالية بتاريخ 04:05، 27 نوفمبر 2018
الاستقرار: 2-مستقر
تقدّم الوحدة repl
تطبيق قراءة وتقييم وطباعة حلقة تكرار والذي يكون متوافرًا كبرنامج بحد ذاته (مستقل) أو مُتَضمّن في تطبيق آخر. يمكن الوصول إليه باستخدام:
const repl = require('repl');
التصميم والميزات
تُصدِّر الوحدة repl
الصنف repl.REPLServer أثناء التنفيذ، سوف تقبل نسخ repl.REPLServer أسطرًا مفردةً من دخل المستخدم وتقيّمها تبعًا لدوال تقييم معرّفة من المستخدم ومن ثمّ تخرج الناتج. ربما يكون الدخل والخرج من stdin
و stdout
، على التوالي، ربما تكون متصلة بأي مجرى (stream) يتبع لبرمجية Node.js.
تدعم نُسخ repl.REPLServer الإكمال التلقائي للدخل، وتعديل سطري بنمط برمجية Emacs (Emacs-style) البسيط، ودخل متعدد الأسطر، و خرج بأسلوب ANSI-styled، وحفظ واستعادة حالة جلسة REPL الحالية، وإصلاح الأخطاء، ودوال تقييم قابلة للتخصيص.
أوامر ومفاتيح خاصة
الأوامر الخاصة التالية مدعومة من قبل كل نُسخ REPL:
-
.break
: في عملية إدخال تعبير متعدد الأسطر، سوف يوقف إدخال الأمر .break (أو الضغط على مجموعة المفاتيح <ctrl>-C
) الدخل الإضافي أو معالجة ذاك التعبير. .clear
: يعيد ضبط قيمة REPLcontext
إلى كائن فارغ ويمسح أي تعابير متعددة الأسطر تُدخل حاليًا..exit
: يغلق مجرى الدخل/الخرج (I/O)، متسبّبًا بخروج REPL..help
: يظهر هذه القائمة من الأوامر الخاصة..save
: يحفظ جلسة REPL الحالية إلى ملف:> .save ./file/to/save.js
.load
: يحمّل ملفًا إلى جلسة REPL الحالية.> .load ./file/to/load.js
.editor
: يدخل وضع التعديل (للانتهاء<ctrl>-D
، وللإلغاء <ctrl>-C
)
> .editor
//( ^C وللإلغاء ^D دخول وضع التعديل (للانتهاء
function welcome(name) {
return `Hello ${name}!`;
}
welcome('Node.js User');
// ^D
'Hello Node.js User!'
>
يملك المزيج التالي من المفاتيح في REPL هذه التأثيرات الخاصة:
-
<ctrl>-C
: عندما تُضغط مرّة، فإنها تملك ذات التأثير كأمر.break
.عندما تُضغط مرّتين على سطر فارغ، تملك ذات تأثير أمر.exit
-
<ctrl>-D
: تملك ذات تأثير أمر.exit
<tab>
: عندما تُضغط على سطر فارغ، تعرض المتحولات العامة والمحلية (النطاق). عندما تُضغط أثناء ادخال دخل آخر، تعرض خيارات إكمال تلقائي ذات صلة.
التقييم الإفتراضي
بشكل افتراضي، تستخدم كل نسخ repl.REPLServer دالة تقييم والتي تقيّم تعابير JavaScript وتوفّر وصول إلى وحدات Node.js مُدمجة. يمكن أن يُعاد تعريف هذا السلوك الافتراضي بتمرير دالة تقييم بديلة عندما تُنشأ نسخة repl.REPLServer.
تعابير JavaScript
يدعم المقيّم الافتراضي تقييم مباشر لتعابير JavaScript:
> 1 + 1
2
> const m = 2
undefined
> m + 1
3
إلّا إذا وسِّع من خلال كتل برمجية أو دوال، يُصرّح عن المتحولات المصرّح عنها في النطاق العام إما بشكل ضمني أو باستخدام الكلمات المفتاحية const
أو let
أو var
.
النطاق العام والمحلي
يوفّر المقيّم الافتراضي وصولًا إلى أي متحول موجود في النطاق العام. من الممكن استخراج متحول إلى REPL بشكل صريح بإسناده إلى كائن context
مترافق مع كل REPLServer
:
const repl = require('repl');
const msg = 'message';
repl.start('> ').context.m = msg;
تظهر الخاصيات في كائن context
كمحلية ضمن REPL:
$ node repl_test.js
> m
'message'
خاصيات السياق Context افتراضيًا ليست للقراءة-فقط، لتحديد قراءة-فقط على النطاق العام، يجب أن تُعرّف خاصيات السياق باستخدام Object.defineProperty()
:
const repl = require('repl');
const msg = 'message';
const r = repl.start('> ');
Object.defineProperty(r.context, 'm', {
configurable: false,
enumerable: true,
value: msg
});
الوصول إلى نواة وحدات Node.js
سوف يحمّل المقيّم الافتراضي تلقائيًا الوحدات الأساسية في Node.js إلى بيئة REPL عندما تُستخدم. على سبيل المثال، إلّا إذا صرّح عنها كمتحولات عامة أو متحولات نطاق. سوف يُقيّم الدخل fs
عند الطلب كما يلي global.fs = require('fs')
:
> fs.createReadStream('./some/file');
الاستثناءات العامة غير الملتقطة
يستخدم REPL وحدة domain لإلتقاط كل الاستثناءات غير المُلتقطة من أجل جلسة REPL تلك.
يشتمل استخدام وحدة domain في REPL على هذه الآثار الجانبية:
- الاستثناءات غير الملتقطة لا تطلق حدث 'uncaughtException'.
- ترمي محاولة استخدام process.setUncaughtExceptionCaptureCallback() الخطأ ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE.
إسناد المتحول '_' (underscore)
سجل التغييرات
الإصدار | التغييرات | ||
---|---|---|---|
التغييرات | أضيف دعم _error
|
||
بشكل افتراضي، سوف يسند المقيّم الافتراضي قيمة أحدث تعبير مُقيّم إلى المتحول الخاص _
(شرطة سفلية). ضبط _
بشكل صريح إلى قيمة ما سوف يعطّل هذا السلوك.
> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
Expression assignment to _ now disabled.
4
> 1 + 1
2
> _
4
بشكل مشابه، سوف يشير _error
إلى آخر خطأ مُشاهد، إذا وُجِد. ضبط _error
إلى قيمةٍ ما بشكل صريح سوف يعطّل هذا السلوك.
> throw new Error('foo');
Error: foo
> _error.message
'foo'
الكلمة المفتاحية await
مع خيار سطر الأوامر المُحدد --experimental-repl-await ، مُكّن الدعم التجريبي للكلمة المفتاحية await
.
> await Promise.resolve(123)
123
> await Promise.reject(new Error('REPL await'))
Error: REPL await
at repl:1:45
> const timeout = util.promisify(setTimeout);
undefined
> const old = Date.now(); await timeout(1000); console.log(Date.now() - old);
1002
undefined
دوال تقييم مُخصصة
عندما تُنشأ نسخة جديدة من الكائن repl.REPLServer جديدة، ربما تُقدّم دوال تقييم مخصصة. يمكن أن يستخدم هذا على سبيل المثال، لتنفيذ تطبيقات REPL مخصصة بشكل كامل.
يشرح التالي مثال REPL نظري والذي ينجز ترجمةً لنص من لغة إلى أخرى:
const repl = require('repl');
const { Translator } = require('translator');
const myTranslator = new Translator('en', 'fr');
function myEval(cmd, context, filename, callback) {
callback(null, myTranslator.translate(cmd));
}
repl.start({ prompt: '> ', eval: myEval });
أخطاء يمكن إصلاحها
بما أنَّ المستخدم يكتب المدخلات ضمن مِحَث REPL، سوف يرسل ضغطُ المفتاح <enter>
سطرَ المدخلات الحالية إلى دالة eval
. بغية دعم المدخلات متعدد الأسطر، يمكن أن تعيد الدالة evalنسخة من الصنف repl.Recoverable
إلى دالة رد النداء المتوافرة:
function myEval(cmd, context, filename, callback) {
let result;
try {
result = vm.runInThisContext(cmd);
} catch (e) {
if (isRecoverableError(e)) {
return callback(new repl.Recoverable(e));
}
}
callback(null, result);
}
function isRecoverableError(error) {
if (error.name === 'SyntaxError') {
return /^(Unexpected end of input|Unexpected token)/.test(error.message);
}
return false;
}
تخصيص خرج REPL
افتراضيًا، تنسِّق النسخ repl.REPLServer الخرج باستخدام التابع util.inspect() قبل كتابة الخرج إلى المجرى Writable
المُقدّم (يكون process.stdout
افتراضيًا). يمكن أن يُحدَّد الخيار useColors
المنطقي عند البناء ليأمر الكاتب الافتراضي باستخدام النمط ANSI المستعمل في تنسيق الشيفرات لتلوين خرج التابع util.inspect()
.
من الممكن تخصيص خرج النسخة repl.REPLServer بشكل كامل عن طريق تمرير دالة جديدة إليه باستخدام الخيار writer
عند البناء. على سبيل المثال، يحوّل المثال التالي أي نص مدخل إلى حالة الأحرف الكبيرة:
const repl = require('repl');
const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter });
function myEval(cmd, context, filename, callback) {
callback(null, cmd);
}
function myWriter(output) {
return output.toUpperCase();
}
الصنف REPLServer
أضيف في الإصدار: 0.1.91
يرث الصنف repl.REPLServer
من الصنف readline.Interface. تُنشَأ النُسخ repl.REPLServer
باستخدام التابع repl.start()
ولا ينبغي أن تُنشَأ بشكل مباشر باستخدام كلمة JavaScript المفتاحية new
.
الحدث 'exit'
أضيف في الإصدار: 0.7.7.
يُطلق الحدث 'exit'
عندما يُنهَى REPL إمّا باستقبال أمر .exit
كدخل، أو بضغط المستخدم على المفتاحين <ctrl>-C
مرتين لإرسال الإشارة SIGINT
، أو بضغط المفتاحين <ctrl>-D
لإطلاق الحدث 'end'
في مجرى الدخل. سيُستدعى تابع رد نداء المستمع (listener callback) دون أي وسائط.
replServer.on('exit', () => {
console.log('Received "exit" event from repl!');
process.exit();
});
الحدث: 'reset'
أضيف في الإصدار: 0.11.0
يُطلق الحدث 'reset'
عندما يُعاد ضبط سياق REPL. يحصل هذا عندما يُستقبَل الأمر .clear
كدخل إلّا إذا كانت REPL تستخدم المقيّم (evaluator) الإفتراضي وأُنشأَت نسخة من الصنف repl.REPLServer
مع ضبط الخيار useGlobal
إلى القيمة true
. ستُستدعى دالة رد نداء المستمع مع مرجعٍ يشير إلى كائن context
، إذ يعدُّ هذا المرجع وسيطها الوحيد.
يمكن أن يُستخدم هذا في المقام الأول لإعادة تهيئة سياق REPL لبعض الحالات المحددة مسبقًا:
const repl = require('repl');
function initializeContext(context) {
context.m = 'test';
}
const r = repl.start({ prompt: '> ' });
initializeContext(r.context);
r.on('reset', initializeContext);
عندما تُنفّذ هذه الشيفرة، يمكن أن يُعدَّل المتغير 'm'
العام ولكن يعاد بعد ذلك لقيمته الإبتدائية باستخدام الأمر .clear
:
$ ./node example.js
> m
'test'
> m = 1
1
> m
1
> .clear
Clearing context...
> m
'test'
>
replServer.defineCommand(keyword, cmd)
أضيف في الإصدار: 0.3.0.
keyword
: <string> الكلمة المفتاحية للأمر (دون المحرف.
الافتتاحي).Cmd
: <Object> | <Function> الدالة المراد استدعاؤها عندما يُعالَج الأمر.
يُستخدَم التابع replServer.defineCommand()
لإضافة أمر جديد مسبوق بنقطة .
إلى نسخة REPL. تُستدعى مثل هذه الأوامر بكتابة .
متبوعة بالكلمة keyword
. تكون cmd
إمّا Function
أو Object
مع الخاصيات التالية:
help
: <string> نص مساعدة المراد عرضه عندما يُكتَب.help
(اختياري).action
: <Function> الدالة المراد تنفيذها. تقبل اختياريًا سلسلة نصية كوسيط وحيد.
يُظهِر المثال التالي أمرين جديدين مضافين إلى نسخة REPL:
const repl = require('repl');
const replServer = repl.start({ prompt: '> ' });
replServer.defineCommand('sayhello', {
help: 'Say hello',
action(name) {
this.clearBufferedCommand();
console.log(`Hello, ${name}!`);
this.displayPrompt();
}
});
replServer.defineCommand('saybye', function saybye() {
console.log('Goodbye!');
this.close();
});
يمكن أن تُستخدم هذه التعليمات من داخل النسخة REPL نفسها:
> .sayhello Node.js User
Hello, Node.js User!
> .saybye
Goodbye!
replServer.displayPrompt([preserveCursor])
أضيف في الإصدار: 0.1.91.
preserveCursor
: <boolean>
يُعِدُّ التابع replServer.displayPrompt()
نسخة REPL لاستقبال المدخلات من المستخدم، ثم طباعة prompt
بعد ضبطه إلى سطر جديد في الخرج output
ثم استئناف الدخل input
لقبول مدخلات جديدة.
عندما تكون المدخلات متعدد الأسطر، يُطبع علامة الحذف (...) بدلًا من 'prompt'.
عندما تكون قيمة preserveCursor
هي true
، لن يعاد ضبط موضع المؤشر إلى 0
.
الغرض من التابع replServer.displayPrompt
في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع replServer.defineCommand()
.
replServer.clearBufferedCommand()
أضيف في الإصدار: 9.0.0.
يمسح التابع replServer.clearBufferedCommand()
أي أوامر خُزّنت مؤقتًا ولكنَّها لم تُنفّذ بعد. الغرض من هذا التابع في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع replServer.defineCommand()
.
replServer.parseREPLKeyword(keyword[, rest])
الاستقرار: 0-مهمل.
أضيف في الإصدار: 0.8.9.أهمل منذ الإصدار: 9.0.0.
keyword
: <string> الكلمة المفتاحية المرتقبة للتحليل والتنفيذ.rest
: <any> أي معاملات للكلمة المفتاحية keyword.- القيمة المعادة: <boolean>
تابع داخلي يُستخدَم لتحليل وتنفيذ كلمات REPLServer
المفتاحية. يعيد القيمة true
إذا كانت الكلمة المفتاحية keyword
صالحة، وإلّا سيعيد القيمة false
.
repl.start([options])
سجل التغييرات
الإصدار | التغييرات | ||
---|---|---|---|
10.0.0 | أزيل الخيار REPL_MAGIC_MODE replMode
|
||
5.8.0 | أصبح المعامل options اختياريًا الآن.
|
||
0.1.91 | أُضيف هذا التابع. |
options
: <Object> | <string>prompt
: <string> مِحثّ الإدخال المراد إظهاره. القيمة الإفتراضية:'> '
(مع مسافة زائدة)input
: <stream.Readable> المجرىReadable
الذي سيُقرأ منه دخل REPL. القيمة الإفتراضية:process.stdin
.output
: <stream.Writable> المجرىWritable
الذي سيكتب إليه خرج REPL. القيمة الافتراضية:process.stdout
.terminal
: <boolean> قيمة منطقية إذا كانتtrue
، تحدِّد أنّoutput
ينبغي أن يُعامل كطرفية TTY، ويمتلك شيفرات هروب ANSI/VT100 مكتوبة له. القيمة الافتراضية له تعتمد على قيمة الخاصيةisTTY
على المجرىoutput
.eval
: <Function> الدالة التي ستُستخدم عند تقييم كل سطر مُعطَى من الدخل. القيمة الإفتراضية هي: مغلف (wrapper) غير متزامن للدالةeval()
الموجودة في JavaScript. يمكن أن تخطئ دالة eval معrepl.Recoverable
لتشير إلى أنَّ الدخل غير مُكتمل وتُظهر أسطر إضافية.useColors
: <boolean> قيمة منطقية إذا كانتtrue
، تشير إلى أنَّ الدالةwriter
الافتراضية ينبغي أن تتضمن نمط الألوان ANSI في خرج REPL. إذا أعطيت دالة writer مُخصَّصة، فليس لهذا الخيار عند ذلك أي تأثير. القيمة الإفتراضية: قيمة النُسَخterminal
في REPL.useGlobal
: <boolean> قيمة منطقية إذا كانتtrue
، فستشير إلى أنّ تابع التقييم الافتراضي سيستخدم global التي تخص JavaScript كسياق في مقابل إنشاء سياق منفصل جديد لنسخة REPL. تضبط العقدة CLI REPL هذه القيمة إلىtrue
. القيمة الافتراضية:false
.ignoreUndefined
: <boolean> قيمة منطقية إذا كانتtrue
، فستشير إلى أنَّ الكاتب الافتراضي لن يُظهِر قيمة الأمر المُعادة إذا قُيّمت على أنَّها غير معرّفة (undefined
). القيمة الافتراضية:false
.writer
: <Function> دالة يراد استدعاؤها لتنسيق المخرجات لكل أمر قبل كتابته إلى الخرجoutput
.القيمة الافتراضية: util.inspect().completer
: <Function> دالة اختيارية تُستخدم للإكمال التلقائي عبر المفتاح Tap. انظر التابع readline.InterfaceCompleter على سبيل المثال.replMode
: <symbol> راية تحدِّد فيما اذا كان المقيّم الافتراضي ينفذ كل أوامر JavaScript في النمط الصارم أو النمط الافتراضي (المتساهل). القيم المقبولة لاستعمالها مع الخيار هي:repl.REPL_MODE_SLOPPY
: تقيّم التعابير في النمط المتساهل.repl.REPL_MODE_STRICT
: تقيّم التعابير في النمط الصارم. هذا مكافئ لاستهلال كل عبارة repl بالعبارة'use strict'
.
breakEvalOnSigint
: يوقف تقييم القطعة الحالية من الشيفرة عند استقبال الإشارةSIGINT
، أي ضُغِطَ المفتاحانCtrl+C
. لايمكن أن يُستخدَم هذا الخيار في نفس الوقت مع الخيارeval
. القيمة الافتراضية هي:false
.
يُنشئ التابع repl.start()
ويبدأ النسخة repl.REPLServer.
إذا كان المعامل options
سلسلةً نصيةً (string)، فسيُحدِّد محثّ الإدخال:
const repl = require('repl');
// نمط محث يونيكس
repl.start('$ ');
الوحدة REPL في Node.js
تستخدم Node.js بحدِّ ذاتها الوحدة repl
لتوفير واجهة تفاعلية لها لتنفيذ JavaScript. يمكن أن يستخدم هذا عن طريق تنفيذ شيفرة Node.js التنفيذية دون تمرير أي وسائط (أو بتمرير الوسيط -i
):
$ node
> const a = [1, 2, 3];
undefined
> a
[ 1, 2, 3 ]
> a.forEach((v) => {
... console.log(v);
... });
1
2
3
خيارات متحولات البيئة
يمكن تخصيص سلوكيات الوحدة REPL في Node.js باستخدام متغيرات البيئة التالية:
NODE_REPL_HISTORY
: عندما يُعطى مسار صالح، سيُحفظ تاريخ REPL الدائم إلى الملف الذي يشير إليه هذا المسار بدلًا من حفظه في المجلد.node_repl_history
في المجلد home للمستخدم. ضبط هذه القيمة إلى' '
سوف يعطّل تاريخ REPL الدائم. ستُزال المسافات البيضاء من القيمة.NODE_REPL_HISTORY_SIZE
: يتحكم بعدد أسطر التاريخ (history) التي ستُحفَظ اذا كان التاريخ متوافرًا. يجب أن تكون عددًا موجبًا. القيمة الافتراضية هي:1000
NODE_REPL_MODE
: إمّا أن تكون'sloppy'
أو'strict'
. القيمة الافتراضية:'sloppy'
، والتي ستسمح بتنفيذ شيفرات النمط غير الصارم.
التاريخ الدائم
افتراضيًّا، ستبقي Node.js REPL التاريخ بين جلسات node
REPL عن طريق حفظ المدخلات إلى المف .node_repl_history
المتوضع في المجلد home للمستخدم. يمكن أن يُعطَّل ذلك بضبط متغير البيئة بالشكل NODE_REPL_HISTORY=''
.
استخدام Node.js REPL مع محرر سطري متقدم
من أجل محررات الأسطر المتقدّمة، ابدأ Node.js مع متغير البيئة NODE_NO_READLINE=1
. هذا سوف يبدأ main والمنقّح (debugger) الذي يخص REPL في إعدادات طرفية معيارية، والتي ستسمح بالاستخدام مع rlwrap
.
فمثلًا، يمكن أن يُضاف السطر التالي إلى الملف .bashrc
:
alias node="env NODE_NO_READLINE=1 rlwrap node"
بدء عدّة نسخ REPL مقابل نسخة شغالة وحيدة
من الممكن إنشاء وتشغيل عدة نُسخ REPL مقابل نسخة Node.js شغّالة وحيدة والتي تشارك كائن global
وحيد ولكن تمتلك عدة واجهات دخل/خرج (I/O).
على سبيل المثال، يوفر المثال التالي وحدات REPL مستقلة على مجرى الدخل القياسي stdin
، ومقبس يونكس والمقبس TCP:
const net = require('net');
const repl = require('repl');
let connections = 0;
repl.start({
prompt: 'Node.js via stdin> ',
input: process.stdin,
output: process.stdout
});
net.createServer((socket) => {
connections += 1;
repl.start({
prompt: 'Node.js via Unix socket> ',
input: socket,
output: socket
}).on('exit', () => {
socket.end();
});
}).listen('/tmp/node-repl-sock');
net.createServer((socket) => {
connections += 1;
repl.start({
prompt: 'Node.js via TCP socket> ',
input: socket,
output: socket
}).on('exit', () => {
socket.end();
});
}).listen(5001);
تشغيل هذا التطبيق من موجه الأوامر يؤدي إلى بدء REPL على مجرى الدخل القياسي (stdin). يمكن أيضًا أن يتصل عملاء REPL الآخرون عبر مقبس يونكس أو المقبس TCP.
على سبيل المثال، يفيد telnet
في الاتصال بمقابس TCP، بينما يمكن أن يُستخدم socat
للاتصال بمقبس يونكس ومقبس TCP كلاهما.
ببدء REPL من خادم يعتمد على مقبس يونكس بدلًا من مجرى الدخل القياسي، يمكن الاتصال بعملية Node.js شغالة لمدة طويلة دون إعادة تشغيلها.
مثالٌ عن تشغيل طرفيةREPL (terminal
) "كاملة المواصفات" عبر النسخة net.Server
والنسخة net.Socket
، تجده في هذه الصفحة. مثالٌ آخر عن تشغيل نسخة REPL عبر curl(1)، تجده في هذه الصفحة.