টাইপ কোэрশন (Type coercion) হল একটি অবজেক্টের টাইপ কে অন্য একটি টাইপে পরিবর্তন করা, এর ভ্যালুসহ। উদাহরণস্বরূপ, একটি Integer কে String-এ পরিবর্তন করা #to_s দিয়ে বা একটি Float কে Integer-এ #to_i দিয়ে। কম পরিচিত #to_str এবং #to_int মেথডস কিছু অবজেক্ট ইমপ্লিমেন্ট করে যা প্রথম দৃষ্টিতে একই কাজ করে মনে হয়, কিন্তু কিছু পার্থক্য আছে।
AppSignal Academy-এর এই সংস্করণে, আমরা রুবিতে এক্সপ্লিসিট কাস্টিং (explicit casting) এবং ইমপ্লিসিট কোэрশন (implicit coercion) টাইপের ওপর গভীরে যাব, সংক্ষেপে টাইপকাস্টিং (typecasting) এক্টরস (actors) ছুঁইয়ে। আমরা দুটি মেথডের পার্থক্য কভার করব এবং কীভাবে সেগুলো ব্যবহার করা হয় সেটি আলোচনা করব।
প্রথমে দেখি কীভাবে আমরা সাধারণত রুবিতে ভ্যালুগুলো ভিন্ন টাইপে কোয়ার্স (coerce) করি এক্সপ্লিসিট কাস্টিং হেল্পারস (explicit casting helpers) দিয়ে।
এক্সপ্লিসিট কাস্টিং হেল্পারস (Explicit Casting Helpers)
সबচেয়ে সাধারণ কাস্টিং হেল্পারস হল #to_s, #to_i, #to_a এবং #to_h। এগুলো এক্সপ্লিসিট কাস্টিং মেথডস। এগুলো আমাদের সহজে একটি ভ্যালু এক টাইপ থেকে অন্য টাইপে ট্রান্সফর্ম করতে সাহায্য করে।
এক্সপ্লিসিট হেল্পারস একটি স্পষ্ট প্রতিশ্রুতি (promise) দেয়। যখনই #to_s একটি অবজেক্টের ওপর কল করা হয়, এটি সবসময় একটি স্ট্রিং ফেরত দেবে, এমনকি যদি অবজেক্টটি খুব ভালো স্ট্রিং-এ কনভার্ট না হয়। এটি মাইকেল কিটন (Michael Keaton) কে ব্যাটম্যান (Batman) হিসেবে কাস্ট করার মত। আপনি একটি ব্যাটম্যান পাবেন, এমনকি যদি একটি কমেডি এক্টর (comedy actor) ভুমিকার জন্য বিশেষভাবে উপযুক্ত নাও হন।
রুবি প্রায় সকল বেসিক অবজেক্টে রুবি স্ট্যান্ডার্ড লাইব্রেরিতে এই হেল্পার মেথডস অফার করে।
এই মেথডগুলো, বিশেষ করে #to_s, রুবির অধিকাংশ বেসিক টাইপসে ইমপ্লিমেন্টেড থাকে। যত vrijeme কাস্টING প্রায়শই একটি ভ্যালু ফেরত দেয়, ফলাফল সেটি নাও হতে পারে যা আপনি আশা করেন।
#to_s, #to_i, #to_a এবং #to_h হেল্পারস কল করা যেকোনো ভ্যালুকে সিলেক্টেড টাইপে ফোর্স (force) করে। সেগুলো টাইপের একটি রিপ্রেজেন্টেশন ফেরত দেয় যেটি কোয়ার্স (coerced) হয়েছে, ভ্যালুর সাথে কী হয়েছে সেটি নির্বিশেষে।
ইমপ্লিসিট কোэрশন মেথডস (Implicit Coercion Methods)
যে টাইপে আমরা কাস্ট করছি সেটির মত আচরণ না করা ভ্যালুগুলোর ওপর টাইপ কাস্টিং মেথডস কল করা এরর বা ডেটা লস করতে পারে। রুবি ইমপ্লিসিট কোэрশন মেথডসও অফার করে যেগুলো শুধু তখন ভ্যালু ফেরত দেয় যখন অবজেক্টগুলো সেই টাইপের মত আচরণ করে। এইভাবে আমরা নিশ্চিত হতে পারি যে ভ্যালুটি সেই টাইপের মত আচরণ করে যা আমরা চাই। এই ইমপ্লিসিট কোэрশন মেথডস হল #to_str, #to_int, #to_ary এবং #to_hash।
ইমপ্লিসিট কোэрশন লিওনার্দো নিময় (Leonard Nimoy) কে স্পক (Spock) ছাড়া যেকোনো রলে কাস্ট করার মত। সেটি কাজ করবে যদি ক্যারেক্টারটি স্পকের cukup কাছাকাছি হয়, কিন্তু ফেইল করবে যদি না হয়। #to_str হেল্পার চেষ্টা করে স্ট্রিং-এ কনভার্ট করার, কিন্তু NoMethodError রেইজ করবে যদি অবজেক্টটি মেথডটি ইমপ্লিমেন্ট না করে এবং ইমপ্লিসিটলি কোয়ার্স করা যায় না।
আমরা দেখতে পাচ্ছি রুবি এখন কিছুটা বেশি স্ট্রিক্ট (strict) যে সেটি কী করবে এবং কী করবে না রিকোয়েস্টেড টাইপসে কোয়ার্স করার জন্য। যদি কোয়ার্সন (coercion) সম্ভব না হয়, #to_* মেথডটি অবজেক্টে ইমপ্লিমেন্টেড থাকে না এবং সেটি কল করলে NoMethodError রেইজ করে।
যখন আমরা ইমপ্লিসিট কোэрশনস ব্যবহার করি, যেমন #to_str, আমরা ফাংশনকে একটি স্ট্রিং অবজেক্ট ফেরত দিতে বলি, শুধু তখন যখন অরিজিনাল টাইপও একটি স্ট্রিংর মত আচরণ করে। এই কারণেই, #to_str রুবি স্ট্যান্ডার্ড লাইব্রেরিতে শুধু String-এ ইমপ্লিমেন্টেড থাকে।
রুবি কীভাবে ইমপ্লিসিট কোэрশন ব্যবহার করে (How Ruby Uses Implicit Coercion)
এক্সপ্লিসিট কোэрশনের চেয়ে আরও প্রিসাইজ (precise) হোনার পাশাপাশি, ইমপ্লিসিট কোэрশন আর কী জন্য উপযোগী? আশ্চর্য, রুবি নিজে ইমপ্লিসিট কোэрশনগুলো 상당ভাগ সিনেরিওতে ব্যবহার করে। উদাহরণস্বরূপ, অবজেক্টগুলো + দিয়ে কম্বাইন (combine) করার সময়।
এখানে, আমরা দেখি রুবি একটি TypeError রেইজ করে যেহেতু সেটি Name টাইপ থেকে String-এ একটি ইমপ্লিসিট কনভারশন করতে পারছে না।
আমরা যদি ক্লাসে #to_str ইমপ্লিমেন্ট করি, রুবি জানবে কীভাবে Name টাইপ কোয়ার্স করতে হয়।
একই বিষয় Array এবং #to_ary-র জন্য কাজ করে।
তবে #to_ary আরও সিনেরিওতে ব্যবহার হয়। আমরা এটি ব্যবহার করতে পারি একটি অ্যারে ডিস্ট্রাকচার (destructure) করতে আলাদা ভেরিয়েবলসে।
এটি ব্লক প্যারামিটারের কনভারশনও করে।
আরও সিনেরিও আছে যেখানে ইমপ্লিসিট কোэрশন মেথডস ব্যবহার হয়, যেমন ** সহ #to_hash। এটি ভ্যালুকে #to_hash দিয়ে হ্যাশে কোয়ার্স করে parse_options মেথডে পাস করার আগে।
টাইপ এনফোর্স করা (Enforcing Types)
রুবি আরও রেজিলিয়েন্ট (resilient) কোэрশন মেথডসও অফার করে যখন টাইপ অজানা (unknown type) এবং আমরা নিশ্চিত করতে চাই আমরা সঠিক টাইপ পাচ্ছি। প্রতিটি বেসিক টাইপের জন্য একটি আছে (String(...), Integer(...), Float(...), Array(...), Hash(...), ইত্যাদি)।
String(...) মেথড প্রথম #to_str কল করার চেষ্টা করে ভ্যালুতে, এবং যখন সেটি ফেইল করে, এর #to_s মেথড কল করে। সব অবজেক্ট #to_str মেথড ডিফাইন করে না, তাই উভয় ইমপ্লিসিট কোэрশন (#to_str) এবং এক্সপ্লিসিট (#to_s) কাস্টিং মেথডস দিয়ে চেক করা স্ট্রিং কনভারশন কাজ করার চান্স বাড়ায় এবং আপনি যে ভ্যালু চান সেটি পান। প্রথমে ইমপ্লিসিট কোэрশন কল করে আমরা বেশি সম্ভাবনা থাকে একটি রেজাল্ট পাওয়ার যেটির একই ভ্যালু আছে কিন্তু কোয়ার্সড টাইপের, এবং না কিছু যেন "#<Object:0x00007f8e6d053a90>"।
আপনার শুধু ইমপ্লিসিট কাস্টিং মেথডস ইমপ্লিমেন্ট করা উচিত সেই অবজেক্টসের জন্য যেগুলো কোয়ার্সড টাইপের মত আচরণ করে, যেমন আপনার নিজস্ব String ক্লাসের জন্য #to_str।
প্রথমে ইমপ্লিসিট কোэрশন চেষ্টা করার পাশাপাশি, String(...) হেল্পার রিটার্নড টাইপও চেক করে। #to_str শুধু একটি মেথড যা যেকোনো টাইপের ভ্যালু ফেরত দিতে পারে, এমনকি নন-স্ট্রিংস (non-Strings)। আমরা যে টাইপ চাই সেটি পাওয়া নিশ্চিত করতে String(...) TypeError রেইজ করে যদি টাইপগুলো মেলে না।
এখানে, আমরা দেখতে পাচ্ছি রুবি #to_str-র ফলাফল ইগনোর (ignore) করে কারণ এটা nil ফেরত দিয়েছিল, যা String-টাইপের নয়। বদলে, এটি #to_s রেজাল্টে ফলব্যাক (fall back) করে।
যদি #to_sও nil ফেরত দেয় এবং তাদেশ জন্য সঠিক টাইপ নয়, String(...) একটি TypeError রেইজ করবে।
যদিও সেগুলো টাইপ কোэрশন এনফোর্স করতে আরও নির্ভরযোগ্য (reliable), দ্রষ্টব্য যে কাস্টিং হেল্পার মেথডস (String(...), Integer(...), ইত্যাদি) সাধারণত কিছুটা স্লোয়ার (slower) কারণ সেগুলো দেয়া ভ্যালুতে আরও চেক্স পرفর্ম (perform) করতে হয়।
উপসংহার (In Conclusion)
যখন আপনি নিশ্চিত করতে চান আপনি একটি অবজেক্টের জন্য সঠিক টাইপের ডেটা ডিল করছেন, টাইপ কোэрশন একটি উপযোগী প্রসেস। এই পোস্টে, আমরা আমাদের এক্সপ্লিসিট কাস্টিং হেল্পারস মনে করি #to_s, #to_i, #to_a এবং #to_h। আমরা أولئك ইন্সট্যান্সগুলোও দেখেছি যখন ইমপ্লিসিট হেল্পারস যেমন #to_str, #to_int, #to_ary এবং #to_hash উপযোগী এবং কীভাবে রুবি নিজে সেগুলো ব্যবহার করে।
আমরা আশা করি আপনি এই টাইপ কোэрশন ওভারভিউ উপযোগী পেয়েছেন এবং আপনি এক্টর টাইপকাস্টিং অ্যানালজি (actor typecasting analogy) কেমন পেয়েছেন। সবসময়ের মত, আপনি যদি কোনো টপিক কভার করাতে চান জানাতে দিন। আপনার কোনো প্রশ্ন বা মন্তব্য থাকলে, আমাদের @AppSignal-এ লাইন ড্রপ করতে সংকোচ করবেন না।