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

التحويل بين أنواع البيانات في لغة روبي


Hassan Hedr

يحتوي كل برنامج على العديد من أنواع البيانات، إذ يجب أن تكون العمليات على البيانات بين نفس النوع من البيانات دومًا، مثل العمليات الرياضية على الأرقام، أو دمج السلاسل النصية معًا، ويمكن أن تكون هذه البيانات من مصادر خارجية، مثل لوحة المفاتيح أو استجابة لواجهة برمجة تطبيقات API أو قاعدة بيانات، إذ سنحتاج في هذه الحالة إلى التحويل بين أنواع البيانات قبل تنفيذ العمليات عليها، ولذلك الغرض توفر لغة روبي Ruby العديد من الطرق لتحويل القيم من نوع بيانات إلى آخر، لذلك سنتعرف في هذا المقال على طرق تحويل السلاسل النصية إلى أعداد، والكائنات إلى سلاسل نصية، والسلاسل النصية إلى مصفوفات، والتحويل بين السلاسل النصية والرموز.

تحويل السلاسل النصية إلى أعداد

توفر روبي التابعين to_i و to_f لتحويل السلاسل النصية إلى أعداد، إذ يحوّل to_i السلسلة النصية إلى عدد صحيح، ويحول التابع to_f السلسلة النصية إلى عدد عشري:

"5".to_i       # 5
"55.5".to_i    # 55
"55.5".to_f    # 55.5

لتوضيح ذلك، سننشئ برنامجًا صغيرًا يطلب من المستخدم إدخال عددين ويعرض مجموعهما، لذا ننشئ ملف جديد نسميه adder.rb ونضيف إليه الشيفرة التالية:

print "What is the first number? "
first_number = gets.chop

print "What is the second number? "
second_number = gets.chop

sum = first_number + second_number

print sum

عند تشغيل البرنامج:

$ ruby adder.rb

سنحصل على الإجابة التالية:

What is the first number? 5
What is the second number? 5
55

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

print "What is the first number? "
first_number = gets.chop

print "What is the second number? "
second_number = gets.chop

# convert strings to numbers
first_number = first_number.to_f
second_number = second_number.to_f

sum = first_number + second_number

print sum

ننفذ البرنامج مجددًا:

$ ruby adder.rb

لنلاحظ جمع الأعداد حسابيًا وإظهار النتيجة الصحيحة:

What is the first number? 5
What is the second number? 5
10.0

عند محاولة تحويل سلسلة نصية غير قابلة للتحويل إلى عدد باستخدام أحد التابعين to_i و to_f على النحو التالي:

"123-abc".to_i

سيكون الخرج:

123

نلاحظ تحويل السلسلة النصية "123-abc" إلى العدد الصحيح 123 باستخدام التابع to_i، إذ يتوقف ذلك التابع عندما يصل إلى أول محرف غير رقمي ويعيد النتيجة. يستغل مطورو الويب هذه الخاصية في روبي لإنشاء روابط URL مثل 15-sammy-shark، إذ يدل الرقم 15 في ذلك النص على معرف داخلي للبحث ضمن سجل قاعدة البيانات، أما القسمsammy-shark هو وصف نصي للرابط ليسهل قراءته، وعند تحويل القيمة 15-sammy-shark إلى عدد صحيح باستخدام التابع to_i، سيتجاهل التابع الجزء النصي -sammy-shark ويعيد العدد الصحيح 15 الذي يمكن استخدامه للبحث ضمن سجل قاعدة البيانات، وفيما يلي مثال آخر عن تحويل سلسلة نصية غير عددية:

"abc".to_i

سيكون الخرج:

0

نلاحظ أن التابع to_i يعيد القيمة 0، إذ لا يمكن تحويل أي من المحارف في تلك السلسلة النصية إلى عدد صحيح، وقد يسبب ذلك مشاكل فإذا أدخل المستخدم بإدخال القيمة "abc" ضمن برنامج ما وحولنا هذه القيمة إلى عدد صحيح ثم أجرينا عملية القسمة على ذلك العدد سيحدث خطأ لعدم إمكانية القسمة على الصفر، ولحل تلك المشكلة توفّر روبي طريقةً أخرى لتحويل البيانات إلى أعداد باستخدام أحد التابعينInteger أوFloat للتحويل:

Integer("123")

والخرج:

123

عند محاولة تحويل قيمة غير صالحة للتحويل باستخدام التابع Integer سيرمي خطأ في حال لم تكن كل السلسلة النصية قابلة للتحويل:

Integer("123abc")

سيكون الخرج في هذه الحالة على النحو التالي:

ArgumentError: invalid value for Integer(): "123abc"

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

تحويل البيانات إلى سلاسل نصية

توفر لغة روبي التابع to_s لتحويل أي نوع من البيانات إلى سلسلة نصية:

25.to_s                    # "25"
(25.5).to_s                # "25.5"
["Sammy", "Shark"].to_s    # "[\"Sammy\", \"Shark\"]"

نحتاج غالبًا قبل عرض البيانات للمستخدم إلى تحويل البيانات إلى سلاسل نصية، ففي المثال التالي سنحاول طباعة قيمة من نوع سلسلة نصية وقيمة عددية. نبدأ بإنشاء ملف بالاسم calories.rb يحتوي على التالي:

user = "Sammy"
calories = 100

print "Congratulations, " + user + "! You just burned " + calories + " calories during this workout."

أضفنا قيم المتغيرات في المثال السابق يدويًا، ولكن عادة ما سنستقبل تلك القيم من مصدر خارجي مثل مدخلات المستخدم أو من قاعدة البيانات أو غيرها، والآن ننفذ البرنامج:

$ ruby calories.rb

ليظهر لنا رسالة الخطأ التالية:

...
TypeError: no implicit conversion of Integer into String (TypeError)

لا يمكن إضافة المتغير calories إلى باقي النص الذي نحاول طباعته لأنه يحتوي على قيمة من نوع عدد صحيح لا يمكن تحويلها إلى سلسلة نصية بإضافة علامات تنصيص حولها بل باستخدام التابع to_s قبل دمجها مع بقية النص المطبوع. لحل المشكلة: نعدّل السطر الذي يحتوي على النتيجة ونحول قيمة المتغير calories إلى سلسلة نصية باستخدام التابع to_s على النحو التالي:

user = "Sammy"
calories = 100

print "Congratulations, " + user + "! You just burned " + calories.to_s + " calories during this workout."

نُنفذ البرنامج مجددًا ونلاحظ اختفاء الخطأ السابقة وظهور النتيجة المطلوبة:

Congratulations, Sammy! You just burned 100 calories during this workout.

يمكن أيضًا استخدام خاصية استيفاء النص interpolation المتوفرة في لغة روبي، والتي تحول الكائنات إلى سلاسل نصية تلقائيًا دون الحاجة لأي عمليات تحويل إضافية، لنحاول استخدامها في المثال السابق على النحو التالي:

print "Congratulations, #{user}! You just burned #{calories} calories during this workout."

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

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

تحويل السلاسل النصية إلى مصفوفات

يمكن تحويل أي سلسلة نصية إلى مصفوفة باستخدام التابع split على النحو التالي:

"one two three".split

ويكون الخرج على النحو التالي:

["one", "two", "three"]

يمكن تحديد المحرف الذي نريد استخدامه مثل محدد لفصل السلسلة النصية إلى عناصر بتمريره بمثابة معامل إلى التابع split. سنحوّل في المثال التالي سلسلة نصية تحتوي على قيم مفصولة بفواصل إلى مصفوفة ثم سنرتبها ونطبع قيمة كل عنصر منها على الشاشة، ونبدأ بإنشاء ملف بالاسم "data_import.rb" يحتوي على الشيفرة التالية:

data = "Tiger,Great White,Hammerhead,Whale,Bullhead"

# Convert data to an array by splitting on commas
sharks = data.split(",")

# Sort the sharks alphabetically
sharks = sharks.sort!

# Print out the sharks by iterating through the array
sharks.each{|shark| puts shark }

ننفذ البرنامج:

$ ruby data_import.rb

لنحصل على الخرج التالي:

Bullhead
Great White
Hammerhead
Tiger
Whale

نلاحظ مدى قوة المصفوفات في لغة روبي والاستخدامات المتعددة لها. سنتعلم في الفقرة التالية طريقة التحويل بين السلاسل النصية والرموز.

التحويل بين السلاسل النصية والرموز

يمكن تحويل رمز إلى سلسلة نصية لنتمكن من طباعته، وقد نحتاج أحيانًا لتحويل سلسلة نصية إلى رمز لاستخدامه للبحث ضمن جدول Hash، إذ يمكن للتابع to_s تحويل الرموز إلى سلاسل نصية مباشرةً:

:language.to_s

ويكون الخرج:

"language"

يمكننا التعديل على الشكل النهائي للسلسلة النصية المُعبرة عن الرمز، ففي المثال التالي سنحول الرمز first_name: إلى السلسلة النصية الأوضح والأسهل بالقراءة "First name" كالتالي:

string = :first_name.to_s

# replace underscore with a space and capitalize
string = string.gsub("_"," ").capitalize

يمكن تحويل السلاسل النصية إلى رموز باستخدام التابع to_sym كما يلي:

"first_name".to_sym

وبذلك يكون الخرج:

:first_name

لتحويل السلسلة النصية "First name" إلى الرمز first_name: مجددًا، يجب أولًا تحويل جميع الأحرف إلى الحالة الصغيرة واستبدال المسافات بشرطات سفلية على النحو التالي:

string = "First name"

# replace spaces with underscores and convert to lowercase
string = string.gsub(" ","_").downcase

# Convert to symbol
symbol = string.to_sym

نحتاج كثيرًا للتحويل بين الرموز والسلاسل النصية، سواءٌ لعرض رمز ما بشكلٍ سهل القراءة للمستخدم أو لاستخدام السلسلة النصية للبحث عن مفتاح محدد ضمن جدول Hash الذي يستخدم الرموز من أجل مفاتيحه.

الخاتمة

تعرفنا في هذا المقال على طرق تحويل بعض أنواع البيانات الأساسية إلى أنواع بيانات أخرى باستخدام التوابع التي توفرها لغة روبي ضمن الكائنات، مثل تحويل الأرقام إلى سلاسل نصية، والسلاسل النصية إلى مصفوفات، والتحويل بين الرموز والسلاسل النصية، إذ من المهم التعرف على طرق التحويل تلك للتعامل مع أنواع البيانات المختلفة وتنفيذ العمليات عليها.

ترجمة -وبتصرف- للمقال How To Convert Data Types in 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.


×
×
  • أضف...