في قذيفة إرلانج ، كيف يمكنني قراءة جميع رؤوس تعريف السجل تلقائيًا
-
28-09-2019 - |
سؤال
بدأ هذا السؤال:
في كل مرة تقريبًا عندما أستخدم قذيفة Erlang ، أود تشغيل بعض الأوامر على بدء تشغيل Shell ، على سبيل المثال شيء مثل
rr("*.hrl").
أو مشابه. حاليًا يجب أن أكتبها في كل مرة أبدأ فيها قذيفة إرلانج وأنا سئمت من ذلك وأنسى ذلك طوال الوقت.
ولكن كان هذا في الواقع السؤال الخاطئ! لأن ما أردت فعله بالفعل هو قراءة رؤوس تعريف السجل الخاصة بي في كل وظيفة قذيفة. لا تستخدم لأخرى من الأوامر المدمجة في Shell لتشغيلها عند بدء التشغيل. لذلك قمت بتغيير رأس السؤال لإظهار السؤال كيف كان ينبغي طرحه.
المحلول
أثناء تجربة الحل مع .erlang ، تعثرت على حل لاستخدام RR/1 المحدد:
من صفحة الرجل القذيفة:
هناك بعض الدعم لسجلات القراءة والطباعة في الصدفة. أثناء ترجمة تعبيرات سجل التجميع ، تتم ترجمة تعبيرات tuple. في وقت التشغيل ، لا يُعرف ما إذا كان tuple يمثل بالفعل سجلًا. كما أن تعريفات السجلات المستخدمة بواسطة برنامج التحويل البرمجي المتاح في وقت التشغيل. لذلك من أجل قراءة بناء جملة السجل وطباعة tuples كسجلات عند الإمكان ، يجب الحفاظ على تعريفات السجلات بواسطة shell نفسها. تم وصف أوامر Shell للقراءة ، والتعريف ، والنسيان ، والإدراج ، والطباعة أدناه. لاحظ أن كل وظيفة لها مجموعة من تعريفات السجل الخاصة بها. لتسهيل تعريفات السجلات في المسائل في الوحدات النمطية shell_default و user_default (إذا تم تحميلها) تتم قراءة في كل مرة يتم فيها بدء مهمة جديدة. على سبيل المثال ، إضافة الخط
-include_lib("kernel/include/file.hrl").
إلى user_default يجعل تعريف file_info متاحًا بسهولة في shell.
للتوضيح ، أضيف بعض الأمثلة:
ملف foo.hrl
:
-record(foo, {bar, baz=5}).
ملف: user_default.erl
:
-module(user_default).
-compile(export_all).
-include("foo.hrl"). % include all relevant record definition headers here
%% more stuff probably ...
لنجرب في القشرة:
$ erl
Erlang R13B04 (erts-5.7.5) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.5 (abort with ^G)
1> #foo{}.
#foo{bar = undefined,baz = 5}
→ تعرف القشرة عن السجل من foo.hrl
نصائح أخرى
الملف .erlang
يتم تقييمه عند بدء تشغيل القشرة ، لكنه كذلك ليس تقييم في سياق الصدفة. هذا يعني أنه يمكن أن يحتوي فقط على تعبيرات عامة يتم تقييمها وليس أوامر shell. للأسف rr()
هو أمر shell (يقوم بتهيئة بيانات shell المحلية للتعرف على السجلات) بحيث لا يمكن استخدامها في .erlang
ملف.
بينما يحدد المستخدم الوحدة النمطية user_default
, ، والتي يجب تحميلها مسبقًا ، يمكن أن تتضمن ملفات تحتوي على تعريفات سجل باستخدام -include
أو -include_lib
, ، ستكون تعريفات السجلات هذه متاحة فقط للوظائف المحددة في الداخل user_default
. user_default
هي الوحدة النمطية المترجمة العادية والوظائف التي تم تصديرها فيها تسمى أي وظائف أخرى بحيث لا تكون تعريفات السجل مرئية داخل القشرة. user_default
يسمح للمستخدم بتحديد وظائف أكثر تعقيدًا يمكن استدعاؤها من داخل shell كأوامر shell.
تعديل:
كنت مخطئا جزئيا هنا. بينما كنت على صواب بشأن كيف .erlang
يتم تقييمه وكيف تعمل في user_default
يطلق عليهم فاتني كيف user_default.erl
تم مسحه ضوئيًا عند بدء تشغيل Shell لتسجيل التعريفات التي تتوفر بعد ذلك داخل القشرة. شكرا @بير Stritzinger لإشارة هذا.
ضعه في ملف يسمى .erlang
في الدليل المنزلي الخاص بك (انظر الفقرة 1.7.1 في http://www.erlang.org/documentation/doc-5.2/doc/getting_started/getting_started.html).