الفرق بين المراجعتين ل"Node.js/repl"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(القسم الثاني من الصفحة)
ط (تنسيق الكود)
سطر 2: سطر 2:
 
الاستقرار: 2-مستقر  
 
الاستقرار: 2-مستقر  
  
تقدّم الوحدة repl تطبيق قراءة وتقييم وطباعة حلقة تكرار والذي يكون متوافرًا كبرنامج بحد ذاته (مستقل) أو مُتَضمّن في تطبيق آخر. يمكن الوصول إليه باستخدام:<syntaxhighlight lang="javascript">
+
تقدّم الوحدة <code>repl</code> تطبيق قراءة وتقييم وطباعة حلقة تكرار والذي يكون متوافرًا كبرنامج بحد ذاته (مستقل) أو مُتَضمّن في تطبيق آخر. يمكن الوصول إليه باستخدام:<syntaxhighlight lang="javascript">
 
const repl = require('repl');
 
const repl = require('repl');
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
= التصميم والميزات =
 
= التصميم والميزات =
تُصدِّر الوحدة repl الصنف repl.REPLServer أثناء التنفيذ، سوف تقبل نسخ repl.REPLServer أسطرًا مفردةً من دخل المستخدم وتقيّمها تبعًا لدوال تقييم معرّفة من المستخدم ومن ثمّ تخرج الناتج. ربما يكون الدخل والخرج من stdin و stdout، على التوالي، ربما تكون متصلة بأي مجرى (stream) يتبع لبرمجية Node.js.
+
تُصدِّر الوحدة <code>repl</code> الصنف repl.REPLServer أثناء التنفيذ، سوف تقبل نسخ repl.REPLServer أسطرًا مفردةً من دخل المستخدم وتقيّمها تبعًا لدوال تقييم معرّفة من المستخدم ومن ثمّ تخرج الناتج. ربما يكون الدخل والخرج من <code>stdin</code> و <code>stdout</code>، على التوالي، ربما تكون متصلة بأي مجرى (stream) يتبع لبرمجية Node.js.
  
 
تدعم نُسخ repl.REPLServer الإكمال التلقائي للدخل، وتعديل سطري بنمط برمجية Emacs‏ (Emacs-style) البسيط، ودخل متعدد الأسطر، و خرج بأسلوب ANSI-styled، وحفظ واستعادة حالة جلسة REPL الحالية، وإصلاح الأخطاء، ودوال تقييم قابلة للتخصيص.
 
تدعم نُسخ repl.REPLServer الإكمال التلقائي للدخل، وتعديل سطري بنمط برمجية Emacs‏ (Emacs-style) البسيط، ودخل متعدد الأسطر، و خرج بأسلوب ANSI-styled، وحفظ واستعادة حالة جلسة REPL الحالية، وإصلاح الأخطاء، ودوال تقييم قابلة للتخصيص.
سطر 13: سطر 13:
 
= أوامر ومفاتيح خاصة =
 
= أوامر ومفاتيح خاصة =
 
الأوامر الخاصة التالية مدعومة من قبل كل نُسخ  REPL:
 
الأوامر الخاصة التالية مدعومة من قبل كل نُسخ  REPL:
* ‎.break: في عملية إدخال تعبير متعدد الأسطر، سوف يوقف إدخال الأمر ‎.break (أو الضغط على مجموعة المفاتيح ‎<ctrl>‎-‎C‎) الدخل الإضافي أو معالجة ذاك التعبير.
+
* ‎<code>.break</code>: في عملية إدخال تعبير متعدد الأسطر، سوف يوقف إدخال الأمر ‎.break (أو الضغط على مجموعة المفاتيح ‎<code><ctrl>‎-‎C</code>‎) الدخل الإضافي أو معالجة ذاك التعبير.
* ‎.clear: يعيد ضبط قيمة REPL context إلى كائن فارغ ويمسح أي تعابير متعددة الأسطر تُدخل حاليًا.
+
* <code>‎.clear</code>: يعيد ضبط قيمة REPL <code>context</code> إلى كائن فارغ ويمسح أي تعابير متعددة الأسطر تُدخل حاليًا.
* ‎.exit: يغلق مجرى الدخل/الخرج (I/O)، متسبّبًا بخروج REPL.
+
* <code>‎.exit</code>: يغلق مجرى الدخل/الخرج (I/O)، متسبّبًا بخروج REPL.
* ‎.help: يظهر هذه القائمة من الأوامر الخاصة.
+
* <code>‎.help</code>: يظهر هذه القائمة من الأوامر الخاصة.
* ‎.save: يحفظ جلسة REPL الحالية إلى ملف: ‎>‎ ‎.save ./file/to/save.js‎
+
* <code>‎.save</code>: يحفظ جلسة REPL الحالية إلى ملف: <code>‎>‎ ‎.save ./file/to/save.js‎</code>
* ‎.load: يحمّل ملفًا إلى جلسة REPL الحالية. ‎> ‎.‎load ./file/to/load.js‎
+
* <code>‎.load</code>: يحمّل ملفًا إلى جلسة REPL الحالية. <code>‎> ‎.‎load ./file/to/load.js</code>‎
* ‎.editor: يدخل وضع التعديل (للانتهاء ‎<ctrl>‎-‎D‎، \وللإلغاء ‎<ctrl>‎-‎C)
+
* <code>‎.editor</code>: يدخل وضع التعديل (للانتهاء <code>‎<ctrl>‎-‎D</code>‎، وللإلغاء ‎<code><ctrl>‎-‎C</code>)
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
 
> .editor
 
> .editor
سطر 39: سطر 39:
  
 
يملك المزيج التالي من المفاتيح في REPL هذه التأثيرات الخاصة:
 
يملك المزيج التالي من المفاتيح في REPL هذه التأثيرات الخاصة:
* ‎<ctrl>‎‎-‎‎C‎: عندما تُضغط مرّة، فإنها تملك ذات التأثير كأمر ‎.break .عندما تُضغط مرّتين على سطر فارغ، تملك ذات تأثير أمر ‎.exit
+
* ‎<code><ctrl>‎‎-‎‎C</code>‎: عندما تُضغط مرّة، فإنها تملك ذات التأثير كأمر <code>‎.break</code> .عندما تُضغط مرّتين على سطر فارغ، تملك ذات تأثير أمر <code>‎.exit</code>
* ‎<ctrl>‎-‎D: تملك ذات تأثير أمر ‎.exit
+
* ‎<code><ctrl>‎-‎D</code>: تملك ذات تأثير أمر <code>‎.exit</code>
* ‎<tab>‎: عندما تُضغط على سطر فارغ، تعرض المتحولات العامة والمحلية (النطاق). عندما تُضغط أثناء ادخال دخل آخر، تعرض خيارات إكمال تلقائي ذات صلة.
+
* <code>‎<tab></code>‎: عندما تُضغط على سطر فارغ، تعرض المتحولات العامة والمحلية (النطاق). عندما تُضغط أثناء ادخال دخل آخر، تعرض خيارات إكمال تلقائي ذات صلة.
  
 
= التقييم الإفتراضي =
 
= التقييم الإفتراضي =
سطر 57: سطر 57:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
إلّا إذا وسِّع من خلال كتل برمجية أو دوال، يُصرّح عن المتحولات المصرّح عنها في النطاق العام إما بشكل ضمني أو باستخدام الكلمات المفتاحية const أو let أو var.
+
إلّا إذا وسِّع من خلال كتل برمجية أو دوال، يُصرّح عن المتحولات المصرّح عنها في النطاق العام إما بشكل ضمني أو باستخدام الكلمات المفتاحية <code>const</code> أو <code>let</code> أو <code>var</code>.
  
 
== النطاق العام والمحلي ==
 
== النطاق العام والمحلي ==
يوفّر المقيّم الافتراضي وصولًا إلى أي متحول موجود في النطاق العام. من الممكن استخراج متحول إلى REPL بشكل صريح بإسناده إلى كائن context مترافق مع كل REPLServer:<syntaxhighlight lang="javascript">
+
يوفّر المقيّم الافتراضي وصولًا إلى أي متحول موجود في النطاق العام. من الممكن استخراج متحول إلى REPL بشكل صريح بإسناده إلى كائن <code>context</code> مترافق مع كل <code>REPLServer</code>:<syntaxhighlight lang="javascript">
 
const repl = require('repl');
 
const repl = require('repl');
 
const msg = 'message';
 
const msg = 'message';
سطر 66: سطر 66:
 
repl.start('> ').context.m = msg;
 
repl.start('> ').context.m = msg;
  
</syntaxhighlight>تظهر الخاصيات في كائن context كمحلية ضمن REPL:<syntaxhighlight lang="javascript">
+
</syntaxhighlight>تظهر الخاصيات في كائن <code>context</code> كمحلية ضمن REPL:<syntaxhighlight lang="javascript">
 
$ node repl_test.js
 
$ node repl_test.js
 
> m
 
> m
سطر 72: سطر 72:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
خاصيات السياق Context افتراضيًا ليست للقراءة-فقط، لتحديد قراءة-فقط على النطاق العام، يجب أن تُعرّف خاصيات السياق باستخدام Object.defineProperty()‎:<syntaxhighlight lang="javascript">
+
خاصيات السياق Context افتراضيًا ليست للقراءة-فقط، لتحديد قراءة-فقط على النطاق العام، يجب أن تُعرّف خاصيات السياق باستخدام <code>Object.defineProperty()</code>‎:<syntaxhighlight lang="javascript">
 
const repl = require('repl');
 
const repl = require('repl');
 
const msg = 'message';
 
const msg = 'message';
سطر 88: سطر 88:
  
 
=== الوصول إلى نواة وحدات Node.js ===
 
=== الوصول إلى نواة وحدات Node.js ===
سوف يحمّل المقيّم الافتراضي تلقائيًا الوحدات الأساسية في Node.js إلى بيئة REPL عندما تُستخدم. على سبيل المثال، إلّا إذا صرّح عنها كمتحولات عامة أو متحولات نطاق. سوف يُقيّم الدخل fs عند الطلب كما يلي ‎global.fs = require('fs')‎:<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>
سطر 102: سطر 102:
 
سجل التغييرات
 
سجل التغييرات
  
بشكل افتراضي، سوف يسند المقيّم الافتراضي قيمة أحدث تعبير مُقيّم إلى المتحول الخاص _ (شرطة سفلية). ضبط _ بشكل صريح إلى قيمة ما سوف يعطّل هذا السلوك.<syntaxhighlight lang="javascript">
+
بشكل افتراضي، سوف يسند المقيّم الافتراضي قيمة أحدث تعبير مُقيّم إلى المتحول الخاص <code>_</code> (شرطة سفلية). ضبط <code>_</code> بشكل صريح إلى قيمة ما سوف يعطّل هذا السلوك.<syntaxhighlight lang="javascript">
 
> [ 'a', 'b', 'c' ]
 
> [ 'a', 'b', 'c' ]
 
[ 'a', 'b', 'c' ]
 
[ 'a', 'b', 'c' ]
سطر 114: سطر 114:
 
> _
 
> _
 
4
 
4
</syntaxhighlight>بشكل مشابه، سوف يشير ‎_‎error‎ إلى آخر خطأ مُشاهد، إذا وُجِد. ضبط ‎_‎error‎ إلى قيمةٍ ما بشكل صريح سوف يعطّل هذا السلوك.<syntaxhighlight lang="javascript">
+
</syntaxhighlight>بشكل مشابه، سوف يشير <code>‎_‎error</code>‎ إلى آخر خطأ مُشاهد، إذا وُجِد. ضبط <code>‎_‎error‎</code> إلى قيمةٍ ما بشكل صريح سوف يعطّل هذا السلوك.<syntaxhighlight lang="javascript">
 
> throw new Error('foo');
 
> throw new Error('foo');
 
Error: foo
 
Error: foo
سطر 122: سطر 122:
  
 
=== الكلمة المفتاحية await ===
 
=== الكلمة المفتاحية await ===
مع خيار سطر الأوامر المُحدد ‎--experimental‎-repl-await‎ ، مُكّن الدعم التجريبي للكلمة المفتاحية await.<syntaxhighlight lang="javascript">
+
مع خيار سطر الأوامر المُحدد ‎--experimental‎-repl-await‎ ، مُكّن الدعم التجريبي للكلمة المفتاحية <code>await</code>.<syntaxhighlight lang="javascript">
 
> await Promise.resolve(123)
 
> await Promise.resolve(123)
 
123
 
123
سطر 154: سطر 154:
  
 
== أخطاء يمكن إصلاحها ==
 
== أخطاء يمكن إصلاحها ==
بما أنَّ المستخدم يكتب المدخلات ضمن مِحَث REPL، سوف يرسل ضغطُ المفتاح ‎<enter>‎ سطرَ المدخلات الحالية إلى دالة eval. بغية دعم المدخلات متعدد الأسطر، يمكن أن تعيد الدالة evalنسخة من الصنف repl.Recoverable إلى دالة رد النداء المتوافرة:<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) {
 
   let result;
 
   let result;
سطر 177: سطر 177:
  
 
== تخصيص خرج REPL ==
 
== تخصيص خرج REPL ==
افتراضيًا، تنسِّق النسخ repl.REPLServer الخرج باستخدام التابع util.inspect()‎ قبل كتابة الخرج إلى المجرى Writable المُقدّم (يكون process.stdout افتراضيًا). يمكن أن يُحدَّد الخيار useColors المنطقي عند البناء ليأمر الكاتب الافتراضي باستخدام النمط ANSI المستعمل في تنسيق الشيفرات لتلوين خرج التابع util.inspect()‎.
+
افتراضيًا، تنسِّق النسخ repl.REPLServer الخرج باستخدام التابع util.inspect()‎ قبل كتابة الخرج إلى المجرى <code>Writable</code> المُقدّم (يكون <code>process.stdout</code> افتراضيًا). يمكن أن يُحدَّد الخيار <code>useColors</code> المنطقي عند البناء ليأمر الكاتب الافتراضي باستخدام النمط ANSI المستعمل في تنسيق الشيفرات لتلوين خرج التابع <code>util.inspect()‎</code>.
  
من الممكن تخصيص خرج النسخة repl.REPLServer بشكل كامل عن طريق تمرير دالة جديدة إليه باستخدام الخيار writer عند البناء. على سبيل المثال، يحوّل المثال التالي أي نص مدخل إلى حالة الأحرف الكبيرة:<syntaxhighlight lang="javascript">
+
من الممكن تخصيص خرج النسخة repl.REPLServer بشكل كامل عن طريق تمرير دالة جديدة إليه باستخدام الخيار <code>writer</code> عند البناء. على سبيل المثال، يحوّل المثال التالي أي نص مدخل إلى حالة الأحرف الكبيرة:<syntaxhighlight lang="javascript">
 
const repl = require('repl');
 
const repl = require('repl');
  
سطر 196: سطر 196:
 
أضيف في الإصدار: 0.1.91
 
أضيف في الإصدار: 0.1.91
  
يرث الصنف repl.REPLServer من الصنف readline.Interface. تُنشَأ النُسخ repl.REPLServer باستخدام التابع repl.start()‎ ولا ينبغي أن تُنشَأ بشكل مباشر باستخدام كلمة JavaScript المفتاحية new.
+
يرث الصنف <code>repl.REPLServer</code> من الصنف readline.Interface. تُنشَأ النُسخ <code>repl.REPLServer</code> باستخدام التابع <code>repl.start()</code>‎ ولا ينبغي أن تُنشَأ بشكل مباشر باستخدام كلمة JavaScript المفتاحية <code>new</code>.
  
 
== الحدث 'exit' ==
 
== الحدث 'exit' ==
 
أضيف في الإصدار: 0.7.7.
 
أضيف في الإصدار: 0.7.7.
  
يُطلق الحدث 'exit' عندما يُنهَى REPL إمّا باستقبال أمر ‎.exit‎ كدخل، أو بضغط المستخدم على المفتاحين ‎<ctrl>‎-‎C مرتين لإرسال الإشارة SIGINT، أو بضغط المفتاحين ‎<ctrl>‎-‎D لإطلاق الحدث 'end' في مجرى الدخل. سيُستدعى تابع  رد نداء المستمع (listener callback) دون أي وسائط.<syntaxhighlight lang="javascript">
+
يُطلق الحدث <code>'exit'</code> عندما يُنهَى REPL إمّا باستقبال أمر ‎<code>.exit</code>‎ كدخل، أو بضغط المستخدم على المفتاحين ‎<code><ctrl>‎-‎C</code> مرتين لإرسال الإشارة <code>SIGINT</code>، أو بضغط المفتاحين ‎<code><ctrl>‎-‎D</code> لإطلاق الحدث <code>'end'</code> في مجرى الدخل. سيُستدعى تابع  رد نداء المستمع (listener callback) دون أي وسائط.<syntaxhighlight lang="javascript">
 
replServer.on('exit', () => {
 
replServer.on('exit', () => {
 
   console.log('Received "exit" event from repl!');
 
   console.log('Received "exit" event from repl!');
سطر 212: سطر 212:
 
أضيف في الإصدار: 0.11.0
 
أضيف في الإصدار: 0.11.0
  
يُطلق الحدث 'reset' عندما يُعاد ضبط سياق REPL. يحصل هذا عندما يُستقبَل الأمر ‎.clear‎ كدخل إلّا إذا كانت REPL تستخدم المقيّم (evaluator) الإفتراضي وأُنشأَت نسخة من الصنف repl.REPLServer مع ضبط الخيار useGlobal إلى القيمة true. ستُستدعى دالة رد نداء المستمع مع مرجعٍ يشير إلى كائن context، إذ يعدُّ هذا المرجع وسيطها الوحيد.
+
يُطلق الحدث <code>'reset'</code> عندما يُعاد ضبط سياق REPL. يحصل هذا عندما يُستقبَل الأمر <code>‎.clear</code>‎ كدخل إلّا إذا كانت REPL تستخدم المقيّم (evaluator) الإفتراضي وأُنشأَت نسخة من الصنف <code>repl.REPLServer</code> مع ضبط الخيار <code>useGlobal</code> إلى القيمة <code>true</code>. ستُستدعى دالة رد نداء المستمع مع مرجعٍ يشير إلى كائن <code>context</code>، إذ يعدُّ هذا المرجع وسيطها الوحيد.
  
 
يمكن أن يُستخدم هذا في المقام الأول لإعادة تهيئة سياق REPL لبعض الحالات المحددة مسبقًا:<syntaxhighlight lang="javascript">
 
يمكن أن يُستخدم هذا في المقام الأول لإعادة تهيئة سياق REPL لبعض الحالات المحددة مسبقًا:<syntaxhighlight lang="javascript">
سطر 225: سطر 225:
  
 
r.on('reset', initializeContext);
 
r.on('reset', initializeContext);
</syntaxhighlight>عندما تُنفّذ هذه الشيفرة، يمكن أن يُعدَّل المتغير 'm' العام ولكن يعاد بعد ذلك لقيمته الإبتدائية باستخدام الأمر ‎.clear‎:<syntaxhighlight lang="javascript">
+
</syntaxhighlight>عندما تُنفّذ هذه الشيفرة، يمكن أن يُعدَّل المتغير <code>'m'</code> العام ولكن يعاد بعد ذلك لقيمته الإبتدائية باستخدام الأمر <code>‎.clear</code>‎:<syntaxhighlight lang="javascript">
 
$ ./node example.js
 
$ ./node example.js
 
> m
 
> m
سطر 243: سطر 243:
 
== replServer.defineCommand(keyword, cmd)‎ ==
 
== replServer.defineCommand(keyword, cmd)‎ ==
 
أضيف في الإصدار: 0.3.0.
 
أضيف في الإصدار: 0.3.0.
* keyword: ‏‎<string>‎ الكلمة المفتاحية للأمر (دون المحرف . الافتتاحي).
+
* <code>keyword</code>: ‏‎<string>‎ الكلمة المفتاحية للأمر (دون المحرف <code>.</code> الافتتاحي).
* Cmd:‏ ‎<Object>‎ | <Function>‎ الدالة المراد استدعاؤها عندما يُعالَج الأمر.
+
* <code>Cmd</code>:‏ ‎<Object>‎ | <Function>‎ الدالة المراد استدعاؤها عندما يُعالَج الأمر.
يُستخدَم التابع replServer.defineCommand()‎ لإضافة أمر جديد مسبوق بنقطة . إلى نسخة REPL. تُستدعى مثل هذه الأوامر بكتابة . متبوعة بالكلمة keyword. تكون cmd إمّا Function أو Object مع الخاصيات التالية:
+
يُستخدَم التابع <code>replServer.defineCommand()</code>‎ لإضافة أمر جديد مسبوق بنقطة <code>.</code> إلى نسخة REPL. تُستدعى مثل هذه الأوامر بكتابة <code>.</code> متبوعة بالكلمة <code>keyword</code>. تكون <code>cmd</code> إمّا <code>Function</code> أو <code>Object</code> مع الخاصيات التالية:
* help:‏ <string> نص مساعدة المراد عرضه عندما يُكتَب ‎.help (اختياري).
+
* <code>help</code>:‏ <string> نص مساعدة المراد عرضه عندما يُكتَب <code>‎.help</code> (اختياري).
* action:‏ <Function> الدالة المراد تنفيذها. تقبل اختياريًا سلسلة نصية كوسيط وحيد.
+
* <code>action</code>:‏ <Function> الدالة المراد تنفيذها. تقبل اختياريًا سلسلة نصية كوسيط وحيد.
 
يُظهِر المثال التالي أمرين جديدين مضافين إلى نسخة REPL:<syntaxhighlight lang="javascript">
 
يُظهِر المثال التالي أمرين جديدين مضافين إلى نسخة REPL:<syntaxhighlight lang="javascript">
 
const repl = require('repl');
 
const repl = require('repl');
سطر 274: سطر 274:
 
== replServer.displayPrompt([preserveCursor‎]‎)‎ ==
 
== replServer.displayPrompt([preserveCursor‎]‎)‎ ==
 
أضيف في الإصدار: 0.1.91.
 
أضيف في الإصدار: 0.1.91.
* preserveCursor:‏ <boolean>
+
* <code>preserveCursor</code>:‏ <boolean>
يُعِدُّ التابع replServer.displayPrompt()‎ نسخة REPL لاستقبال المدخلات من المستخدم، ثم طباعة prompt بعد ضبطه إلى سطر جديد في الخرج output ثم استئناف الدخل input لقبول مدخلات جديدة.
+
يُعِدُّ التابع <code>replServer.displayPrompt()</code>‎ نسخة REPL لاستقبال المدخلات من المستخدم، ثم طباعة <code>prompt</code> بعد ضبطه إلى سطر جديد في الخرج <code>output</code> ثم استئناف الدخل <code>input</code> لقبول مدخلات جديدة.
  
 
عندما تكون المدخلات متعدد الأسطر، يُطبع علامة الحذف (...) بدلًا من 'prompt'.
 
عندما تكون المدخلات متعدد الأسطر، يُطبع علامة الحذف (...) بدلًا من 'prompt'.
  
عندما تكون قيمة preserveCursor هي true، لن يعاد ضبط موضع المؤشر إلى 0.
+
عندما تكون قيمة <code>preserveCursor</code> هي <code>true</code>، لن يعاد ضبط موضع المؤشر إلى <code>0</code>.
  
الغرض من التابع replServer.displayPrompt في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع replServer.defineCommand()‎.
+
الغرض من التابع <code>replServer.displayPrompt</code> في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع <code>replServer.defineCommand()</code>‎.
  
 
== replServer.clearBufferedCommand()‎ ==
 
== replServer.clearBufferedCommand()‎ ==
 
أضيف في الإصدار: 9.0.0.
 
أضيف في الإصدار: 9.0.0.
  
يمسح التابع replServer.clearBufferedCommand()‎ أي أوامر خُزّنت مؤقتًا ولكنَّها لم تُنفّذ بعد. الغرض من هذا التابع في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع replServer.defineCommand()‎.
+
يمسح التابع <code>replServer.clearBufferedCommand()</code>‎ أي أوامر خُزّنت مؤقتًا ولكنَّها لم تُنفّذ بعد. الغرض من هذا التابع في المقام الأول هو استدعاؤه من داخل دالة الإجراء (action function) لأجل الأوامر المُسجلَة باستخدام التابع <code>replServer.defineCommand()‎</code>.
  
 
== replServer.parseREPLKeyword(keyword[, rest]‎)‎ ==
 
== replServer.parseREPLKeyword(keyword[, rest]‎)‎ ==
سطر 292: سطر 292:
  
 
أضيف في الإصدار: 0.8.9.أهمل منذ الإصدار: 9.0.0.
 
أضيف في الإصدار: 0.8.9.أهمل منذ الإصدار: 9.0.0.
* keyword:‏ <string> الكلمة المفتاحية المرتقبة للتحليل والتنفيذ.
+
* <code>keyword</code>:‏ <string> الكلمة المفتاحية المرتقبة للتحليل والتنفيذ.
* rest:‏ <any> أي معاملات للكلمة المفتاحية keyword.
+
* <code>rest</code>:‏ <any> أي معاملات للكلمة المفتاحية keyword.
 
* القيمة المعادة: ‎<boolean>‎
 
* القيمة المعادة: ‎<boolean>‎
تابع داخلي يُستخدَم لتحليل وتنفيذ كلمات REPLServer المفتاحية. يعيد القيمة  true إذا كانت الكلمة المفتاحية keyword صالحة، وإلّا سيعيد القيمة false.
+
تابع داخلي يُستخدَم لتحليل وتنفيذ كلمات <code>REPLServer</code> المفتاحية. يعيد القيمة  <code>true</code> إذا كانت الكلمة المفتاحية <code>keyword</code> صالحة، وإلّا سيعيد القيمة <code>false</code>.
  
 
= repl.start([options]‎)‎ =
 
= repl.start([options]‎)‎ =
 
سجل التغييرات
 
سجل التغييرات
* options:‏ ‎ <Object>‎ | <string>‎‎
+
* <code>options</code>:‏ ‎ <Object>‎ | <string>‎‎
** prompt:‏ <string> مِحثّ الإدخال المراد إظهاره. القيمة الإفتراضية: ‎'‎>‎ '‎‎ (مع مسافة زائدة)
+
** <code>prompt</code>:‏ <string> مِحثّ الإدخال المراد إظهاره. القيمة الإفتراضية: <code>‎'‎>‎ '‎‎</code> (مع مسافة زائدة)
** input:‏ <stream.Readable> المجرى Readable الذي سيُقرأ منه دخل REPL. القيمة الإفتراضية هي: process.stdin.
+
** <code>input</code>:‏ <stream.Readable> المجرى <code>Readable</code> الذي سيُقرأ منه دخل REPL. القيمة الإفتراضية هي: <code>process.stdin</code>.
** output:‏ <stream.Writable> المجرى Writable الذي سيكتب إليه خرج REPL. القيمة الافتراضية: process.stdout.
+
** <code>output</code>:‏ <stream.Writable> المجرى <code>Writable</code> الذي سيكتب إليه خرج REPL. '''القيمة الافتراضية:''' <code>process.stdout</code>.
** terminal:‏ <boolean> قيمة منطقية إذا كانت true، تحدِّد أنّ output ينبغي أن يُعامل كطرفية TTY، ويمتلك شيفرات هروب ANSI/VT100 مكتوبة له. القيمة الافتراضية له تعتمد على قيمة الخاصية isTTY على المجرى output.
+
** <code>terminal</code>:‏ <boolean> قيمة منطقية إذا كانت <code>true</code>، تحدِّد أنّ <code>output</code> ينبغي أن يُعامل كطرفية TTY، ويمتلك شيفرات هروب ANSI/VT100 مكتوبة له. القيمة الافتراضية له تعتمد على قيمة الخاصية <code>isTTY</code> على المجرى <code>output</code>.
** eval:‏ <Function> الدالة التي ستُستخدم عند تقييم كل سطر مُعطَى من الدخل. القيمة الإفتراضية هي: مغلف (wrapper) غير متزامن للدالة eval()‎ الموجودة في JavaScript. يمكن أن تخطئ دالة eval مع repl.Recoverable لتشير إلى أنَّ الدخل غير مُكتمل وتُظهر أسطر إضافية.
+
** <code>eval</code>:‏ <Function> الدالة التي ستُستخدم عند تقييم كل سطر مُعطَى من الدخل. القيمة الإفتراضية هي: مغلف (wrapper) غير متزامن للدالة <code>eval()‎</code> الموجودة في JavaScript. يمكن أن تخطئ دالة eval مع <code>repl.Recoverable</code> لتشير إلى أنَّ الدخل غير مُكتمل وتُظهر أسطر إضافية.
** useColors:‏ <boolean> قيمة منطقية إذا كانت true، تشير إلى أنَّ الدالة writer الافتراضية ينبغي أن تتضمن نمط الألوان ANSI في خرج REPL. إذا أعطيت دالة writer مُخصَّصة، فليس لهذا الخيار عند ذلك أي تأثير. القيمة الإفتراضية هي: قيمة النُسَخ terminal في REPL.
+
** <code>useColors</code>:‏ <boolean> قيمة منطقية إذا كانت <code>true</code>، تشير إلى أنَّ الدالة <code>writer</code> الافتراضية ينبغي أن تتضمن نمط الألوان ANSI في خرج REPL. إذا أعطيت دالة writer مُخصَّصة، فليس لهذا الخيار عند ذلك أي تأثير. القيمة الإفتراضية هي: قيمة النُسَخ <code>terminal</code> في REPL.
** useGlobal:‏ <boolean> قيمة منطقية إذا كانت true، فستشير إلى أنّ تابع التقييم الافتراضي سيستخدم global التي تخص JavaScript كسياق في مقابل إنشاء سياق منفصل جديد لنسخة REPL. تضبط العقدة CLI REPL هذه القيمة إلى true. القيمة الافتراضية هي: false.
+
** <code>useGlobal</code>:‏ <boolean> قيمة منطقية إذا كانت <code>true</code>، فستشير إلى أنّ تابع التقييم الافتراضي سيستخدم global التي تخص JavaScript كسياق في مقابل إنشاء سياق منفصل جديد لنسخة REPL. تضبط العقدة CLI REPL هذه القيمة إلى <code>true</code>. '''القيمة الافتراضية''' هي: <code>false</code>.
** ignoreUndefined:‏ <boolean> قيمة منطقية إذا كانت true، فستشير إلى أنَّ الكاتب الافتراضي لن يُظهِر قيمة الأمر المُعادة إذا قُيّمت على أنَّها غير معرّفة (undefined). القيمة الافتراضية هي: false.
+
** <code>ignoreUndefined</code>:‏ <boolean> قيمة منطقية إذا كانت <code>true</code>، فستشير إلى أنَّ الكاتب الافتراضي لن يُظهِر قيمة الأمر المُعادة إذا قُيّمت على أنَّها غير معرّفة (<code>undefined</code>). القيمة الافتراضية هي: <code>false</code>.
** writer:‏ <Function> دالة يراد استدعاؤها لتنسيق المخرجات لكل أمر قبل كتابته إلى الخرج output.القيمة الافتراضية هي: util.inspect()‎.
+
** <code>writer</code>:‏ <Function> دالة يراد استدعاؤها لتنسيق المخرجات لكل أمر قبل كتابته إلى الخرج <code>output</code>.'''القيمة الافتراضية''' هي: util.inspect()‎.
** completer:‏ <Function> دالة اختيارية تُستخدم للإكمال التلقائي عبر المفتاح Tap. انظر التابع readline.InterfaceCompleter على سبيل المثال.
+
** <code>completer</code>:‏ <Function> دالة اختيارية تُستخدم للإكمال التلقائي عبر المفتاح Tap. انظر التابع readline.InterfaceCompleter على سبيل المثال.
** replMode:‏ <symbol> راية تحدِّد فيما اذا كان المقيّم الافتراضي ينفذ كل أوامر JavaScript في النمط الصارم أو النمط الافتراضي (المتساهل). القيم المقبولة لاستعمالها مع الخيار هي:
+
** <code>replMode</code>:‏ <symbol> راية تحدِّد فيما اذا كان المقيّم الافتراضي ينفذ كل أوامر JavaScript في النمط الصارم أو النمط الافتراضي (المتساهل). القيم المقبولة لاستعمالها مع الخيار هي:
*** repl.‎REPL_MODE_SLOPPY‎: تقيّم التعابير في النمط المتساهل.
+
*** <code>repl.‎REPL_MODE_SLOPPY‎</code>: تقيّم التعابير في النمط المتساهل.
*** repl.‎REPL_MODE_STRICT‎: تقيّم التعابير في النمط الصارم. هذا مكافئ لاستهلال كل عبارة repl بالعبارة 'use strict'.
+
*** <code>repl.‎REPL_MODE_STRICT</code>‎: تقيّم التعابير في النمط الصارم. هذا مكافئ لاستهلال كل عبارة repl بالعبارة <code>'use strict'</code>.
** breakEvalOnSigint‎: يوقف تقييم القطعة الحالية من الشيفرة عند استقبال الإشارة SIGINT، أي ضُغِطَ المفتاحان Ctrl+C. لايمكن أن يُستخدَم هذا الخيار في نفس الوقت مع الخيار eval. القيمة الافتراضية هي: false.
+
** <code>breakEvalOnSigint</code>‎: يوقف تقييم القطعة الحالية من الشيفرة عند استقبال الإشارة <code>SIGINT</code>، أي ضُغِطَ المفتاحان <code>Ctrl+C</code>. لايمكن أن يُستخدَم هذا الخيار في نفس الوقت مع الخيار <code>eval</code>. '''القيمة الافتراضية''' هي: <code>false</code>.
يُنشئ التابع repl.start()‎ ويبدأ النسخة repl.REPLServer.
+
يُنشئ التابع <code>repl.start()</code>‎ ويبدأ النسخة repl.REPLServer.
  
إذا كان المعامل options سلسلةً نصيةً (string)، فسيُحدِّد محثّ الإدخال:<syntaxhighlight lang="javascript">
+
إذا كان المعامل <code>options</code> سلسلةً نصيةً (string)، فسيُحدِّد محثّ الإدخال:<syntaxhighlight lang="javascript">
 
const repl = require('repl');
 
const repl = require('repl');
  
سطر 325: سطر 325:
  
 
== الوحدة REPL في Node.js  ==
 
== الوحدة REPL في Node.js  ==
تستخدم Node.js بحدِّ ذاتها الوحدة repl لتوفير واجهة تفاعلية لها لتنفيذ JavaScript. يمكن أن يستخدم هذا عن طريق تنفيذ شيفرة Node.js التنفيذية دون تمرير أي وسائط (أو بتمرير الوسيط ‎-i‎):<syntaxhighlight lang="javascript">
+
تستخدم Node.js بحدِّ ذاتها الوحدة <code>repl</code> لتوفير واجهة تفاعلية لها لتنفيذ JavaScript. يمكن أن يستخدم هذا عن طريق تنفيذ شيفرة Node.js التنفيذية دون تمرير أي وسائط (أو بتمرير الوسيط <code>‎-i‎</code>):<syntaxhighlight lang="javascript">
 
$ node
 
$ node
 
> const a = [1, 2, 3];
 
> const a = [1, 2, 3];
سطر 342: سطر 342:
 
=== خيارات متحولات البيئة ===
 
=== خيارات متحولات البيئة ===
 
يمكن تخصيص سلوكيات الوحدة REPL في Node.js باستخدام متغيرات البيئة التالية:
 
يمكن تخصيص سلوكيات الوحدة REPL في Node.js باستخدام متغيرات البيئة التالية:
* NODE_REPL_HISTORY: عندما يُعطى مسار صالح، سيُحفظ تاريخ REPL الدائم إلى الملف الذي يشير إليه هذا المسار بدلًا من حفظه في المجلد ‎‎.‎node_repl_history‎ في المجلد home للمستخدم. ضبط هذه القيمة إلى ' ' سوف يعطّل تاريخ REPL الدائم. ستُزال المسافات البيضاء من القيمة.
+
* <code>NODE_REPL_HISTORY</code>: عندما يُعطى مسار صالح، سيُحفظ تاريخ REPL الدائم إلى الملف الذي يشير إليه هذا المسار بدلًا من حفظه في المجلد <code>‎‎.‎node_repl_history‎</code> في المجلد home للمستخدم. ضبط هذه القيمة إلى <code>' '</code> سوف يعطّل تاريخ REPL الدائم. ستُزال المسافات البيضاء من القيمة.
* NODE_REPL_HISTORY_SIZE: يتحكم بعدد أسطر التاريخ (history) التي ستُحفَظ اذا كان التاريخ متوافرًا. يجب أن تكون عددًا موجبًا. القيمة الافتراضية هي: 1000
+
* <code>NODE_REPL_HISTORY_SIZE</code>: يتحكم بعدد أسطر التاريخ (history) التي ستُحفَظ اذا كان التاريخ متوافرًا. يجب أن تكون عددًا موجبًا. '''القيمة الافتراضية''' هي: <code>1000</code>
* NODE_REPL_MODE: إمّا أن تكون 'sloppy' أو 'strict'. القيمة الافتراضية هي: 'sloppy'، والتي ستسمح بتنفيذ شيفرات النمط غير الصارم.
+
* <code>NODE_REPL_MODE</code>: إمّا أن تكون <code>'sloppy'</code> أو <code>'strict'</code>. القيمة الافتراضية هي: <code>'sloppy'</code>، والتي ستسمح بتنفيذ شيفرات النمط غير الصارم.
  
 
=== التاريخ الدائم ===
 
=== التاريخ الدائم ===
افتراضيًّا، ستبقي Node.js REPL التاريخ بين جلسات node REPL عن طريق حفظ المدخلات إلى المف ‎.‎node_repl_history المتوضع في المجلد home للمستخدم. يمكن أن يُعطَّل ذلك بضبط متغير البيئة بالشكل NODE_REPL_HISTORY‎=‎<nowiki>''</nowiki>‎.
+
افتراضيًّا، ستبقي 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 مع متغير البيئة NODE_NO_READLINE=1 . هذا سوف يبدأ main والمنقّح (debugger)‏ الذي يخص REPL في إعدادات طرفية معيارية، والتي ستسمح بالاستخدام مع rlwrap.
+
من أجل محررات الأسطر المتقدّمة، ابدأ Node.js مع متغير البيئة <code>NODE_NO_READLINE=1</code> . هذا سوف يبدأ main والمنقّح (debugger)‏ الذي يخص REPL في إعدادات طرفية معيارية، والتي ستسمح بالاستخدام مع <code>rlwrap</code>.
  
فمثلًا، يمكن أن يُضاف السطر التالي إلى الملف ‎.‎bashrc‎:<syntaxhighlight lang="javascript">
+
فمثلًا، يمكن أن يُضاف السطر التالي إلى الملف ‎<code>.‎bashrc‎</code>:<syntaxhighlight lang="javascript">
 
alias node="env NODE_NO_READLINE=1 rlwrap node"
 
alias node="env NODE_NO_READLINE=1 rlwrap node"
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 
=== بدء عدّة نسخ REPL مقابل نسخة شغالة وحيدة ===
 
=== بدء عدّة نسخ REPL مقابل نسخة شغالة وحيدة ===
من الممكن إنشاء وتشغيل عدة نُسخ REPL مقابل نسخة Node.js شغّالة وحيدة والتي تشارك كائن global وحيد ولكن تمتلك عدة واجهات دخل/خرج (I/O).
+
من الممكن إنشاء وتشغيل عدة نُسخ REPL مقابل نسخة Node.js شغّالة وحيدة والتي تشارك كائن <code>global</code> وحيد ولكن تمتلك عدة واجهات دخل/خرج (I/O).
  
على سبيل المثال، يوفر المثال التالي وحدات REPL مستقلة على مجرى الدخل القياسي، ومقبس يونكس والمقبس TCP:<syntaxhighlight lang="javascript">
+
على سبيل المثال، يوفر المثال التالي وحدات REPL مستقلة على مجرى الدخل القياسي <code>stdin</code>، ومقبس يونكس والمقبس TCP:<syntaxhighlight lang="javascript">
 
const net = require('net');
 
const net = require('net');
 
const repl = require('repl');
 
const repl = require('repl');
سطر 394: سطر 394:
 
</syntaxhighlight>تشغيل هذا التطبيق من موجه الأوامر يؤدي إلى بدء REPL على مجرى الدخل القياسي (stdin). يمكن أيضًا أن يتصل عملاء REPL الآخرون عبر مقبس يونكس أو المقبس TCP.
 
</syntaxhighlight>تشغيل هذا التطبيق من موجه الأوامر يؤدي إلى بدء REPL على مجرى الدخل القياسي (stdin). يمكن أيضًا أن يتصل عملاء REPL الآخرون عبر مقبس يونكس أو المقبس TCP.
  
على سبيل المثال، يفيد telnet في الاتصال بمقابس TCP، بينما يمكن أن يُستخدم socat للاتصال بمقبس يونكس ومقبس TCP كلاهما.
+
على سبيل المثال، يفيد <code>telnet</code> في الاتصال بمقابس TCP، بينما يمكن أن يُستخدم <code>socat</code> للاتصال بمقبس يونكس ومقبس TCP كلاهما.
  
 
ببدء REPL من خادم يعتمد على مقبس يونكس بدلًا من مجرى الدخل القياسي، يمكن الاتصال بعملية Node.js شغالة لمدة طويلة دون إعادة تشغيلها.
 
ببدء REPL من خادم يعتمد على مقبس يونكس بدلًا من مجرى الدخل القياسي، يمكن الاتصال بعملية Node.js شغالة لمدة طويلة دون إعادة تشغيلها.
  
مثالٌ عن تشغيل طرفية REPL‎ "كاملة المواصفات" عبر النسخة net.Server والنسخة net.Socket، تجده في هذه الصفحة. مثالٌ آخر عن تشغيل نسخة REPL عبر curl(1)‎، تجده في هذه الصفحة.
+
مثالٌ عن تشغيل طرفية<code>terminal</code>) ‎)  '''ةةة'''  REPL"كاملة المواصفات" عبر النسخة <code>net.Server</code> والنسخة <code>net.Socket</code>، تجده في هذه الصفحة. مثالٌ آخر عن تشغيل نسخة REPL عبر curl(1)‎، تجده في هذه الصفحة.
  
 
== مصادر ==
 
== مصادر ==
 
[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 الرسمي.]

مراجعة 16:41، 19 نوفمبر 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: يعيد ضبط قيمة REPL context إلى كائن فارغ ويمسح أي تعابير متعددة الأسطر تُدخل حاليًا.
  • ‎.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


دخول وضع التعديل (للانتهاء D^ وللإلغاء C^ )//

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)

سجل التغييرات

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

> [ '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]‎)‎

سجل التغييرات

  • 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 شغالة لمدة طويلة دون إعادة تشغيلها.

مثالٌ عن تشغيل طرفيةterminal) ‎) ةةة REPL"كاملة المواصفات" عبر النسخة net.Server والنسخة net.Socket، تجده في هذه الصفحة. مثالٌ آخر عن تشغيل نسخة REPL عبر curl(1)‎، تجده في هذه الصفحة.

مصادر

صفحة REPL في توثيق Node.js الرسمي.