اذهب إلى المحتوى

استكشاف لغة روبي باستخدام البرنامج التفاعلي IRB


Hassan Hedr

يوفر برنامج روبي التفاعلي Interactive Ruby -أو اختصارًا IRB طريقةً سريعةً لاستكشاف لغة برمجة روبي وتجربة الشيفرات البرمجية دون الحاجة لإنشاء ملفات جديدة وتنفيذها، إذ يُعد برنامج IRB حلقة قراءة-تقييم-طباعة Read-Eval-Print Loop -أو ما يعرف اختصارًا REPL- وهي أداة توفرها العديد من لغات البرمجة الحديثة لتوفير طريقة سهلة للعب واستكشاف لغة البرمجة، ولاستخدامها نُنفذ الأمر irb ثم نكتب مباشرةً كود روبي ليترجم IRB الشيفرة المدخلة ويقيّمها ويعرض النتيجة.

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

تشغيل وإيقاف IRB

يكفي تثبيت لغة روبي على الجهاز ليكون IRB مثبتًا وجاهزًا للاستخدام، ويمكننا تشغيله مباشرةً بتنفيذ الأمر irb من سطر الأوامر على النحو التالي:

$ irb

ليظهر لنا نافذة IRB:

irb(main):001:0>

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

2.4.0 :001 >

وللحصول على نفس نافذة الـ IRB ضمن الأمثلة في هذا المقال يمكن تشغيل IRB باستخدام الأمر التالي:

irb --prompt inf-ruby

يمكن ضمن IRB إدخال التعليمات بصيغة لغة برمجة روبي مباشرةً لنختبر ذلك بإضافة عددين معًا:

irb(main):001:0> 2 + 2

نضغط على مفتاح "Enter" ليعرض IRB نتيجة تنفيذ تلك التعليمة:

=> 4

يشير الرمز <= في بداية السطر بأن هذه هي قيمة هي نتيجة تنفيذ عبارة روبي البرمجية السابقة، وللخروج من IRB ننفذ التعليمة exit أو نضغط على المفتاحين "CTRL+D" لنعود بذلك إلى واجهة سطر الأوامر. سنتعمق في الفقرة التالية في IRB وسنستخدمه لاستكشاف الشيفرات البرمجية.

تنفيذ الشيفرات البرمجية ضمن جلسة IRB

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

irb(main):001:0> puts "Hello World"

عند الضغط على "Enter" سنرى نتيجتين من IRB:

Hello World
=> nil

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

irb(main):001:0> puts "Hello World"
Hello World
=> nil
irb(main):002:0>

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

irb(main):002:0> birth_year = 1868

لنرى القيمة التي تعيدها تلك التعليمة البرمجية:

=> 1868

يحتوي المتغير birth_year على تلك القيمة. بما أن معظم الأوامر في روبي تُرجع قيمًا، فسيعرض IRB لنا القيمة التي تعيدها تعليمة الإسناد هنا أيضًا.

لنعرف متغيرًا آخرًا بالاسم death_year على النحو التالي:

irb(main):003:0> death_year = 1921

ثم نعرف المتغير age_at_death عن طريق طرح قيمة birth_year من قيمة المتغير death_year:

irb(main):004:0> age_at_death = death_year - birth_year

يسند IRB القيمة للمتغير الجديد ويعرض النتيجة:

=> 53

نلاحظ عدم حاجتنا للاستعادة بالتوابع puts أو print ضمن جلسة IRB، إذ تُطبع تلقائيًا القيم التي تعيدها التعليمات البرمجية المُنفذة.

يدعم IRB كتابة الشيفرات البرمجية التي تمتد على عدة أسطر، إذ يُنفذ تلك الشيفرات البرمجية بعد اكتمال صياغتها بصورةٍ صحيحة، ففي الشيفرة البرمجية التالية نستخدم مصفوفة من أسماء الأسماك ونستدعي منها التابع select لإرجاع أسماء الأسماك التي تحتوي على الحرف "a" في اسمها، ولكتابة هذه الشفرة على عدة أسطر ضمن جلسة IRB نضغط مفتاح "Enter" بعد كل سطر منها:

["Tiger", "Great White", "Angel"].select do |shark|
shark.include?("a")
end

سينفذ IRB الشيفرة البرمجية فقط عند اكتمال صحة صياغتها، ونلاحظ ظهور رمز النجمة * في بداية الأسطر دلالةً على عدم تنفيذ IRB للشيفرات السابقة بعد، وتتغيير القيمة صفر في نهاية اسم السطر إلى واحد للدلالة على الدخول في سياق جديد مختلف:

irb(main):005:0> ["Tiger", "Great White", "Angel"].select do |shark|
irb(main):006:1* shark.include?("a")
irb(main):007:1> end

بما أن السطر الأول يحتوي على الكلمة المفتاحية do، فإن IRB لا ينفذ أي تعليمة لاحقة حتى يصل إلى الكلمة المفتاحية end، ومن ثم سيعرض النتيجة:

=> ["Great White"]

يمكن باستخدام IRB اختبار الشيفرات البرمجية الصغيرة لاستكشاف طريقة عملها قبل اعتمادها ضمن البرامج التي نعمل على تطويرها، كما يمكن استخدام IRB لاستدعاء المكتبات الخارجية والتعامل معها وهو ما سنتعرف عليه في الفقرة التالية.

استخدام المكتبات والأمر Gem

يمكنك استيراد المكتبات إلى جلسة IRB باستخدام تعليمة require تمامًا كما نفعل في برنامج روبي، ويمكن أن تكون أحد المكتبات القياسية ضمن مكتبة روبي، أو مكتبات خاصة بنا، أو مكتبات Gems وهي مكتبات روبي المنشورة ضمن المستودع Rubygems.org، والتي يمكننا تثبيتها باستخدام أمر gem؛ إذ تتضمن مكتبة روبي القياسية وحدات تمكننا من إرسال الطلبات عبر الويب مثلًا واستقبال نتائجها، ويمكن استخدام تلك المكتبة من داخل جلسة IRB تمامًا كما نفعل في برنامج روبي؛ إذ تُستخدم التعليمة require لاستيراد المكتبة Net/HTTP من مكتبة روبي القياسية بإدخال السطر التالي ضمن جلسة IRB والضغط على ENTER:

require 'net/http'

يعيد تنفيذ هذا السطر في IRB القيمة true، مما يدل نجاح تحميل المكتبة، ويمكننا الآن استخدامها لكتابة الشيفرة التالية لإرسال طلب إلى موقع مثلًا icanhazip.com لمعرفة عنوان IP الخارجي الخاص بنا:

uri = URI.parse("http://icanhazip.com")
response = Net::HTTP.get_response uri
response.body

بعد إدخال كل سطر من الأسطر السابقة سيعرض IRB القيمة التي تعيدها كل تعليمة منها، ونستفيد من ذلك لتصحيح الأخطاء في كل خطوة في حال حدوثها:

irb(main):010:0> uri = URI.parse("http://icanhazip.com")
=> #<URI::HTTP http://icanhazip.com>
irb(main):011:0> response = Net::HTTP.get_response uri
=> #<Net::HTTPOK 200 OK readbody=true>
irb(main):012:0> response.body
=> 203.0.113.52\n

فمثلًا في حال لم يعثر على المكتبة المطلوبة، ستكون القيمة التي تعيدها التعليمة مختلفة. لنختبر ذلك باستيراد مكتبة HTTParty، والتي توفر طريقة أسهل للتعامل مع طلبات HTTP:

require 'httparty'

نلاحظ ظهور هذه الرسالة:

LoadError: cannot load such file -- httparty

والتي تخبرنا بأن المكتبة التي نريدها غير متاحة، إذ أن مكتبة HTTParty منشورةٌ على أنها مكتبة gem، لذلك نحتاج لتثبيتها قبل الاستخدام، لذا نخرج من جلسة IRB باستخدام المفتاحين "CTRL+D"، أو نكتب exit للعودة إلى سطر الأوامر، ثم ننفذ الأمر gem لتثبيت مكتبة httparty:

$ gem install httparty

الآن، نعود لجلسة irb مرةً أخرى:

$ irb

ونحاول تحميل وحدة المكتبة مرةً أخرى على النحو التالي:

require 'httparty`

نلاحظ أن قيمة تنفيذ تلك التعليمة هذه المرة هي true، مما يدل على نجاح تحميل المكتبة. لنستخدمها الآن كما يلي:

response = HTTParty.get("http://icanhazip.com")
response.body

سنرى نتيجة قيمة رد الطلب المرسل على النحو التالي:

=> 203.0.113.52\n

بعد أن تعرفنا على طريقة استدعاء واستخدام أي نوع من المكتبات ضمن IRB، لنتعرف على طريقة استخدامه لاستكشاف واختبار شيفرات روبي البرمجية في الفقرة التالية.

تحميل الشيفرات البرمجية ضمن IRB

يمكن استخدام الخيار r- عند إنشاء جلسة IRB جديدة لتحديد المكتبات أو Gems التي نريد تحميلها مباشرةً عند بدء جلسة IRB، فمثلًا يمكن تنفيذ الأمر irb -r httparty، الذي سيبدأ جلسة IRB جديدة مع تحميل مكتبة httparty مباشرةً، ما يعني عدم الحاجة لتنفيذ التعليمة require httparty ضمن الجلسة لاستيراد المكتبة، ويمكن استخدام هذا الخيار أيضًا لتحميل شيفرة برمجية خاصة بنا ضمن الجلسة الجديدة مما يفيد عند الحاجة لاستكشاف تلك الشيفرات أو اختبارها.

ننهي جلسة IRB الحالية بكتابة exit أو بالضغط على المفتاحين "CTRL+D"، ثم ننشئ ملف روبي جديد بالاسم "ip_grabber.rb"، والذي سنعرف ضمنه كائنًا IPGrabber مع تابع get الذي يعيد عنوان IP الخارجي للجهاز. سنستعين بالمكتبة HTTParty لإرسال طلب HTTP وجلب قيمة العنوان من الموقع icanhazip.com، إذ يمكننا استخدام الكائن IPGrabber ضمن برامجنا الأخرى لعزل الشيفرة الخاصة بالبرنامج عن أي تغييرات خارجية، وسنتمكن من استخدام هذا الكائن حتى بعد تبديل المكتبة التي يستخدمها لإرسال طلبات HTTP أو تغيير الموقع الذي يستخدمه لجلب عنوان IP دون الحاجة إلى تعديل أي شيفرة ضمن البرامج الأخرى.

نبدأ بإضافة الشيفرة التالية إلى الملف لتعريف الصنف الجديد:

require 'httparty'
class IPGrabber

def initialize()
@url = "http://icanhazip.com"
end

def get
response = HTTParty.get(@url)
response.body.chomp # remove the \n if it exists
end
end

نحفظ الملف ونبدأ جلسة IRB ونحمل ذلك الملف ضمنها، وبما أنه ملف محلي وليس مكتبة خارجية أو مدمجة فيجب تحديد مسار هذا الملف عند تحميله ولا حاجة لكتابة اللاحقة rb. في نهاية اسم الملف:

$ irb -r ./ip_grabber

يمكننا الآن -بعد انتهاء تحميل جلسة IRB الجديدة- استخدام هذا الكائن مباشرةً في الجلسة على النحو التالي:

ip = IPGrabber.new
ip.get

نلاحظ ظهور النتيجة وهي العنوان:

=> 203.0.113.52

تمكّننا خاصية تحميل الشيفرات الخاصة بنا ضمن جلسة IRB من فحصها أو استدعائها للعمل بها واختبارها قبل دمجها في البرامج التي نعمل على تطويرها. الآن، بعد أن تعرفنا على طريقة تحميل والعمل مع الشيفرات في جلسة IRB، سنتعرف على طريقة تخصيص جلسة IRB وإعدادها لتناسب حاجتنا.

تخصيص جلسة IRB

يمكننا عبر إنشاء ملف الإعدادات بالاسم "irbrc." تخصيص جلسة IRB، مثل إضافة ميزة دعم الإكمال التلقائي والمسافات وتحديد سجل تاريخ الأوامر. لنبدأ بإنشاء هذا الملف ضمن مجلد المستخدم:

$ nano ~/.irbrc

نبدأ بتفعيل ميزة الإكمال التلقائي في IRB، إذ يتيح لنا ذلك ميزة استخدام المفتاح "TAB" ضمن الجلسة لإكمال أسماء الكائنات والمتغيرات وأسماء التوابع:

require 'irb/completion'

نضيف بعدها تفعيل ميزة حفظ تاريخ الأوامر المدخلة في ملف خارجي:

IRB.conf[:SAVE_HISTORY] = 1000

بذلك ستُسجل آخر 1000 عبارة برمجية ندخلها ضمن ملف بالاسم "irb_history." في مجلد المستخدم. إضافةً لذلك، عند فتح جلسة IRB جديدة، سيُحمل تاريخ هذه التعليمات تلقائيًا، ويمكننا استخدام مفاتيح الأسهم للأعلى أو الأسفل للتنقل بين هذه التعليمات، أو استخدام CTRL+R للبحث ضمنها تمامًا كما نفعل في صدفة باش bash، ويمكننا أيضًا تحديد ملف لحفظ تاريخ التعليمات مختلف بإضافة السطر التالي لملف الإعدادات:

IRB.conf[:HISTORY_FILE] = '~/your_history_filename'

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

IRB.conf[:AUTO_INDENT] = true

يمكن لملف الإعدادات أن يحتوي شيفرات برمجية بلغة روبي، ما يعني إمكانية تعريف التوابع المساعدة أو استخدام require لتحميل المكتبات الإضافية، فمثلًا يمكننا تعريف التابع المساعد history إلى جلسة IRB لعرض التاريخ بإضافته على النحو ضمن ملف الإعدادات "irbrc.":

def history
history_array = Readline::HISTORY.to_a
print history_array.join("\n")
end

يمكننا بعد إنشاء جلسة IRB جديدة كتابة history لعرض تاريخ IRB، وقد يحتوي التاريخ على عدد كبير من السجلات لذا يمكننا التعديل على الأمر history ليأخذ عددًا اختياريًا يعبر عن عدد الأسطر التي نود عرضها، لذا نستبدل الشيفرة الخاصة به لتأخذ معاملًا اختياريًا يسمى count وتستخدمه لتحديد عدد السجلات التي يعرضها:

# history command
def history(count = 0)

# Get history into an array
history_array = Readline::HISTORY.to_a

# if count is > 0 we'll use it.
# otherwise set it to 0
count = count > 0 ? count : 0

if count > 0
from = history_array.length - count
history_array = history_array[from..-1]
end

print history_array.join("\n")
end

نحفظ الملف وننشئ جلسة IRB جديدة ثم نكتب history 2 لنرى فقط آخر سطرين من سجل التاريخ الموجود. يجب التذكر أنه وبالرغم من إمكانية استخدام ملف الإعدادات "irbrc." لتحميل المكتبات التي نستخدمها بصورةٍ متكررة ضمن جلسات IRB إلا أن كل مكتبة منها ستزيد وقت تحميل كل جلسة جديدة، ولتجنب ذلك يُفضّل تحميل تلك المكتبات يدويًا باستخدام require عند الحاجة إليها ضمن كل جلسة على حدى.

الخاتمة

يوفر لنا IRB مكانًا لاستكشاف وتجربة شيفرات روبي البرمجية بسهولة، وهو وسيلة رائعة لاستخدامها لتطوير أجزاء من البرنامج الذي نعمل عليه قبل اعتماده وحفظه ضمن ملف. الآن، بعد أن تعرفنا على IRB، يمكنك استخدامه لاستكشاف أنواع البيانات المختلفة المتاحة في روبي أو استكشاف أي مزايا أخرى واستخدام وتجربة المكتبات والتعرف عليها.

ترجمة -وبتصرف- للمقال How To Use IRB to Explore Ruby لصاحبه Brian Hogan.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...