আপনি একটি ইন্টিজারের সাথে কাজ করছেন কিন্তু আপনি স্ট্রিং মেথড (যেমন gsub) ব্যবহার করতে চান।
আপনি কী করতে পারেন?
এটিকে একটি স্ট্রিং-এ কনভার্ট করুন (to_s দিয়ে) তারপর আবার ইন্টিজার-এ কনভার্ট করুন (to_i দিয়ে)।
উদাহরণস্বরূপ:
আপনি Integer 1 কে String “1”-এ কনভার্ট করতে পারেন।
তারপর আপনি নতুন ক্লাসের মেথডগুলো ব্যবহার করতে পারেন, যা আপনাকে কিছু করতে সাহায্য করে যা আগে সম্ভব নয়।
মনে রাখুন রুবিতে…
প্রতিটি অবজেক্ট একটি ক্লাসের সাথে asosiatеd, এবং প্রতিটি ক্লাসের একটি নির্দিষ্ট সেট মেথড আছে।
এই আর্টিকেলে, আপনি শিখবেন:
- রুবিতে কোন কনভারশন মেথডগুলো উপলব্ধ
- তাদের মধ্যে পার্থক্য কী!
- বিভিন্ন পরিস্থিতিতে সঠিকটি কীভাবে বেছে নেবেন
শুরু করা যাক!
সংক্ষিপ্ত কনভারশন মেথড (to_s, to_i)
আপনি সম্ভবত এই প্রথম গ্রুপের কনভারশন মেথডগুলোর সাথে পরিচিত।
মেথডগুলো যেন:
- to_i
- to_s
- to_a
এই মেথডগুলো একটি নির্দিষ্ট ক্লাসের নতুন অবজেক্ট রিটার্ন করে যা বর্তমান অবজেক্টকে রিপ্রেজেন্ট করে।
উদাহরণস্বরূপ:
(1..10).to_a # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
এটি বলে:
“আমি
Range1..10 কে একটিArray-এ কনভার্ট করতে চাই যা সেই রেঞ্জকে রিপ্রেজেন্ট করে।”
রুবি এই কনভারশন মেথডগুলো আপনার জন্য ইমপ্লিসিটলি কল করে কিছু জায়গায়।
স্ট্রিং ইন্টারপোলেশনের মত:
"#{1}"
এটি আপনার জন্য 1.to_s কল করে, আপনি যদি এটিকে দেখে না থাকেন।
আপনি নিজে চেক করতে পারেন এই কোড দিয়ে:
module Log def to_s puts "to_s called" super end end class Integer prepend Log end puts "#{1}" # "to_s called"
নোট: আপনাকে
Fixnumব্যবহার করতে হবেInteger-এর বদলে আপনি যদি রুবি ২.৩ বা পুরনো ভার্সনে থাকেন। নয়তো, আপনার রুবি ভার্সন আপডেট করুন 🙂
এই মেথডগুলো বেশ পারমিসিভ এবং সেগুলো এক্সেপশন রেইজ করার জন্য ডিজাইন করা হয়নি।
উদাহরণস্বরূপ:
"aaaaaa".to_i # 0
এই 0 আপনাকে বিস্মিত করতে পারে।
কিন্তু আপনি কোনো ইন্টিজার ছাড়া স্ট্রিং-এ to_i কল করলে আপনি এটি পাবেন।
আপনি পরে এই আর্টিকেলে দেখবেন এই মেথডের একটি অধিক স্ট্রিক্ট ভার্সন আছে।
দীর্ঘ কনভারশন মেথড (to_str, to_int)
এখন:
আমাদের যেহেতু সেই সংক্ষিপ্ত কনভারশন মেথডগুলো আছে, কেন আমাদের to_str, বা to_int এর মত মেথড দরকার?
পার্থক্য কী?
পার্থক্য হলো তাদের উদ্দেশ্যে।
প্রতিটি রুবি ক্লাস (BasicObject বাদে) to_s মেথড ইমপ্লিমেন্ট করে নিজেকে কোনো টাইপের স্ট্রিং রিপ্রেজেন্টেশন হিসেবে রিটার্ন করার জন্য।
কিন্তু শুধু কারণ একটি ক্লাস একটি স্ট্রিং রিটার্ন করে সেটি মানে সেটি স্ট্রিংর মত behave করে না!
একটি উদাহরণ দেখি:
"" + 1 # TypeError: no implicit conversion of Fixnum into String
এটি চিন্তা করুন:
একটি খালি স্ট্রিং প্লাস ইন্টিজার কী রিটার্ন করা উচিত?
আমি নही জানি।
আপনি বলতে পারেন “1” (নাম্বার ওয়ান সহ একটি স্ট্রিং)।
কেন?
আমার এই কেসে অধিকাংশ মানুষ যা এক্সপেক্ট করে সেটি নয়।
এগুলো যোগ করা смыস্লফুল নয়… সেজন্য আমরা এই TypeError পাই।
এবং এমনকি যদি এটিকে অনুমতি দিয়া হত।
এটি কী:
"" + {}
এই খালি স্ট্রিং প্লাস একটি খালি হ্যাশ।
এটিও смыস্লফুল নয়!
তাই রুবি অন্য অবজেক্টটি স্ট্রিং কিনা চেক করার বদলে (যেটি পলিমরফিজমের জন্য ভালো নয়), এটি চেক করে এটি স্ট্রিংর মতো act করে কিনা।
সেইখানেই to_str মেথডটি আসে।
রুবি ২.৫-এ শুধু এই ক্লাসগুলো to_str ইমপ্লিমেন্ট করে:
StringNameError::messageWarning::buffer
আপনার নিজস্ব কনভারশন মেথড কীভাবে ইমপ্লিমেন্ট করবেন
আপনি যেকোনো ক্লাসে to_str ইমপ্লিমেন্ট করতে পারেন।
তब আপনি এটিকে স্ট্রিংর মত ব্যবহার করতে পারবেন।
এখানে একটি উদাহরণ:
class Cat def to_str "meow" end end "" + Cat.new # "meow"
কিন্তু যদি না আপনার ক্লাস স্ট্রিংর সমতুল্য হয় তবে আপনাকে এটি করা উচিত নয়।
to_s ব্যবহার করুন।
বি.টি.ডাব্লিউ, এটি শুধু + মেথডের জন্য নয়।
এটি অন্যান্য জায়গায়ও ব্যবহার হয় যেখানে শুধু একটি স্ট্রিং-লাইক অবজেক্ট смыস্লফুল।
যেমন:
[1,2,3].join(",")
অন্য দীর্ঘ কনভারশন মেথড যেন to_int এবং to_hash একই লজিক ফলো করে।
সেজন্য আমাদের এই বিভিন্ন মেথডগুলো আছে।
কনভারশন র্যাপার কীভাবে ব্যবহার করবেন
আপনি যদি এখনও পর্যাপ্ত কনভারশন মেথড পেয়ে নাই… চিন্তা করবেন না কারণ আমার কাছে আপনার জন্য আরও কয়েকটি আছে!
আমি এগুলাকে “Conversion Wrappers” বলতে পছন্দ করি।
তারা হলো:
- Array()
- Integer()
- Hash[]
খুব অস্বাভাবিক দেখানোর মেথড!
প্যারেনথেসিস এবং স্কোয়ার ব্র্যাকেট…
…এটি একমাত্র জিনিস যা এই মেথডগুলকে তাদের ক্লাস নাম থেকে আলাদা করে।
এইগুলোর উদ্দেশ্য কী?
Array() যেকোনো জিনিসকে অ্যারে-এ কনভার্ট করবে।
এখানে আপনার জন্য কিছু উদাহরণ:
Array(nil) # [] Array([]) # [] Array(1) # [1] Array("") # [""]
এটি কী ধরনের লজিক???
বা, এই মেথড একটি খুব নির্দিষ্ট নিয়ম সেট ফলো করে:
- যদি অবজেক্টটি
to_ary, বাto_a-এ রেসপন্ড করে তবে সেটি সেটি কল করবে এবং ভ্যালু রিটার্ন করবে - অন্যথায়, এটি অবজেক্টটিকে একটি খালি অ্যারেতে রাখবে এবং সেটি রিটার্ন করবে
এটি উপরের আচরণ ব্যাখ্যা করে।
এটি উপকারী যদি আপনি একটি মেথড লিখছেন যা একটি অ্যারে এক্সপেক্ট করে কিন্তু এটা অন্য যেকোনো জিনিস পেতে পারে এবং আপনার পুরো অ্যাপ্লিকেশন ক্র্যাশ করাতে পারে। আপনি এটি Array()-এ পাস করে নিশ্চিত করতে পারেন সেটি একটি অ্যারে যাতে সেটি ক্র্যাশ না করে।
এখন Integer()।
এটির কিছু স্পেশাল নিয়ম আছে:
- যদি অবজেক্টটি একটি স্ট্রিং হয় এবং স্ট্রিংয়ের কন্টেন্ট স্ট্রিক্টলি রুবিতে একটি বৈধ न्यুমেরিক রিপ্রেজেন্টেশনে কনফর্ম করে তবে এই মেথডটি একটি Integer রিটার্ন করবে। ইনভ্যালিড ফরম্যাট হলে
ArgumentErrorরেইজ করবে। - যদি অবজেক্টটি স্ট্রিং না হয় তবে এটি
to_intকল করার চেষ্টা করবে, তারপরto_i। - এটি
TypeErrorরেইজ করবে যদি অবজেক্টটি একটি কনভারশন মেথড ব্যবহার করে বৈধInteger-এ কনভার্ট করা না যায়।
উদাহরণ:
Integer(1) # 1 Integer("25") # 25 Integer("abc123") # ArgumentError (invalid value for Integer(): "abc123") Integer([]) # TypeError (can't convert Array into Integer)
এই Integer() মেথডটি উপকারী যদি আপনি ১০০% নিশ্চিত হতে চান আপনি একটি বৈধ Integer-এর সাথে কাজ করছেন।
এখন Hash[]।
আপনি একটি সম সংখ্যক এলিমেন্ট সম্বিষ্ট অ্যারে পাস করতে পারেন একটি নতুন হ্যাশ পেতে:
Hash[[["a", 1], ["b", 2], ["c", 3]]] # {"a"=>1, "b"=>2, "c"=>3}
উপকারী যদি আপনি দুটি অ্যারে-এর এলিমেন্ট মার্জ করে বা map এর মত মেথড ব্যবহার করে আপনার হ্যাশ বানান।
সারসংক্ষেপ
আপনি রুবিতে বিভিন্ন কনভারশন মেথড, কেন তারা একজিস্ট করে এবং কীভাবে ব্যবহার করবেন সেটি শিখেছেন!
আশা করি আপনি এটি হেল্পফুল পেয়েছেন 🙂
আপনি যদি এই আর্টিকেলটি পছন্দ করেন তবে আপনি আমার বইও ভালোবাসবেন, Ruby Deep Dive, চেক আউট করুন।