রুবিকে দুর্দান্ত করে তোলে এমন একটি জিনিস হ'ল আমরা আমাদের প্রয়োজন অনুসারে প্রায় কোনও কিছু কাস্টমাইজ করতে পারি। এটি দরকারী এবং বিপজ্জনক উভয়ই। নিজেদের পায়ে গুলি করা সহজ, কিন্তু সাবধানে ব্যবহার করলে এর ফলে বেশ শক্তিশালী সমাধান হতে পারে।
রুবি ম্যাজিকে, আমরা মনে করি দরকারী এবং বিপজ্জনক একটি চমৎকার সমন্বয়। আসুন দেখি কিভাবে রুবি বস্তু তৈরি করে এবং শুরু করে এবং কিভাবে আমরা ডিফল্ট আচরণ পরিবর্তন করতে পারি।
ক্লাস থেকে নতুন অবজেক্ট তৈরি করার মূল বিষয়গুলি
শুরু করার জন্য, আসুন দেখি কিভাবে রুবিতে বস্তু তৈরি করা যায়। একটি নতুন অবজেক্ট তৈরি করতে (বা উদাহরণ ), আমরা new বলি ক্লাসে অন্যান্য ভাষার বিপরীতে, new এটি ভাষার নিজেই একটি মূলশব্দ নয়, কিন্তু একটি পদ্ধতি যা অন্য যেকোনটির মতোই বলা হয়৷
class Dog
end
object = Dog.new
নতুন তৈরি করা বস্তুকে কাস্টমাইজ করার জন্য, new-এ আর্গুমেন্ট পাস করা সম্ভব পদ্ধতি আর্গুমেন্ট হিসাবে যা পাশ করা হয়, ইনিশিয়ালাইজারের কাছে চলে যাবে।
class Dog
def initialize(name)
@name = name
end
end
object = Dog.new('Good boy') আবার, অন্যান্য ভাষার বিপরীতে, রুবিতে ইনিশিয়ালাইজারও কিছু বিশেষ সিনট্যাক্স বা কীওয়ার্ডের পরিবর্তে একটি পদ্ধতি।
এটি মাথায় রেখে, অন্য কোনও রুবি পদ্ধতির মতোই সেই পদ্ধতিগুলি নিয়ে জগাখিচুড়ি করা কি সম্ভব নয়? অবশ্যই এটা!
একটি বস্তুর আচরণ পরিবর্তন করা
ধরা যাক আমরা নিশ্চিত করতে চাই যে একটি নির্দিষ্ট শ্রেণীর সমস্ত অবজেক্ট সর্বদা লগ স্টেটমেন্ট প্রিন্ট করবে, এমনকি যদি মেথডটি সাবক্লাসে ওভাররাইড করা হয়। এটি করার একটি উপায় হল অবজেক্টের সিঙ্গেলটন ক্লাসে একটি মডিউল যোগ করা।
module Logging
def make_noise
puts "Started making noise"
super
puts "Finished making noise"
end
end
class Bird
def make_noise
puts "Chirp, chirp!"
end
end
object = Bird.new
object.singleton_class.include(Logging)
object.make_noise
# Started making noise
# Chirp, chirp!
# Finished making noise
এই উদাহরণে, একটি Bird বস্তুটি Bird.new ব্যবহার করে তৈরি করা হয়েছে , এবং Logging মডিউলটি তার সিঙ্গেলটন ক্লাস ব্যবহার করে ফলাফলের অবজেক্টে অন্তর্ভুক্ত করা হয়।
একটি সিঙ্গেলটন ক্লাস কি?
রুবি এমন পদ্ধতির অনুমতি দেয় যা একটি একক বস্তুর জন্য অনন্য। এটি সমর্থন করার জন্য, রুবি বস্তু এবং এর প্রকৃত শ্রেণীর মধ্যে একটি বেনামী শ্রেণী যোগ করে। যখন পদ্ধতিগুলি বলা হয়, সিঙ্গলটন ক্লাসে সংজ্ঞায়িতগুলি প্রকৃত ক্লাসের পদ্ধতিগুলির চেয়ে অগ্রাধিকার পায়। এই সিঙ্গেলটন ক্লাসগুলি প্রতিটি বস্তুর জন্য অনন্য, তাই তাদের সাথে পদ্ধতি যোগ করা প্রকৃত শ্রেণীর অন্য কোনো বস্তুকে প্রভাবিত করে না। প্রোগ্রামিং রুবি গাইডে ক্লাস এবং অবজেক্ট সম্পর্কে আরও জানুন।
যখনই এটি তৈরি করা হয় তখন প্রতিটি বস্তুর সিঙ্গলটন ক্লাস পরিবর্তন করা কিছুটা কষ্টকর। তাহলে চলুন Logging এর অন্তর্ভুক্তি সরানো যাক প্রতিটি তৈরি করা অবজেক্টের জন্য এটি যোগ করার জন্য ইনিশিয়ালাইজারের সাথে ক্লাস করুন।
module Logging
def make_noise
puts "Started making noise"
super
puts "Finished making noise"
end
end
class Bird
def initialize
singleton_class.include(Logging)
end
def make_noise
puts "Chirp, chirp!"
end
end
object = Bird.new
object.make_noise
# Started making noise
# Chirp, chirp!
# Finished making noise
যদিও এটি ভাল কাজ করে, যদি আমরা Bird এর একটি সাবক্লাস তৈরি করি , যেমন Duck , এর আরম্ভকারীকে super কল করতে হবে Logging ধরে রাখতে আচরণ যদিও কেউ যুক্তি দিতে পারে যে super কে সঠিকভাবে কল করা সর্বদা একটি ভাল ধারণা যখনই একটি পদ্ধতি ওভাররাইড করা হয়, আসুন এমন একটি উপায় খুঁজে বের করার চেষ্টা করি যার প্রয়োজন নেই এটা।
যদি আমরা super কল না করি সাবক্লাস থেকে, আমরা Logger এর অন্তর্ভুক্তি হারাই ক্লাস:
class Duck < Bird
def initialize(name)
@name = name
end
def make_noise
puts "#{@name}: Quack, quack!"
end
end
object = Duck.new('Felix')
object.make_noise
# Felix: Quack, quack!
পরিবর্তে, আসুন Bird.new ওভাররাইড করি . আগে উল্লেখ করা হয়েছে, new শুধুমাত্র ক্লাসে প্রয়োগ করা একটি পদ্ধতি। তাই আমরা এটিকে ওভাররাইড করতে পারি, সুপার কল করতে পারি এবং আমাদের প্রয়োজনে নতুন তৈরি করা বস্তুটিকে পরিবর্তন করতে পারি।
class Bird
def self.new(*arguments, &block)
instance = super
instance.singleton_class.include(Logging)
instance
end
end
object = Duck.new('Felix')
object.make_noise
# Started making noise
# Felix: Quack, quack!
# Finished making noise
কিন্তু, যখন আমরা make_noise কল করি তখন কি হয় ইনিশিয়েলাইজারে? দুর্ভাগ্যবশত, কারণ সিঙ্গেলটন ক্লাসে Logging অন্তর্ভুক্ত নেই মডিউল এখনও, আমরা পছন্দসই আউটপুট পাব না।
ভাগ্যক্রমে, একটি সমাধান আছে:ডিফল্ট .new তৈরি করা সম্ভব allocate কল করে স্ক্র্যাচ থেকে আচরণ .
class Bird
def self.new(*arguments, &block)
instance = allocate
instance.singleton_class.include(Logging)
instance.send(:initialize, *arguments, &block)
instance
end
end
কল করা হচ্ছে allocate ক্লাসের একটি নতুন, অপ্রবর্তিত বস্তু ফেরত দেয়। তাই পরে, আমরা অতিরিক্ত আচরণ অন্তর্ভুক্ত করতে পারি এবং শুধুমাত্র তারপর, initialize কল করুন যে বস্তুর উপর পদ্ধতি। (কারণ initialize ডিফল্টরূপে ব্যক্তিগত, আমাদের send ব্যবহার করতে হবে এর জন্য)।
Class#allocate সম্পর্কে সত্য
অন্যান্য পদ্ধতির মত, allocate ওভাররাইড করা সম্ভব নয় . রুবি allocate এর জন্য প্রেরন পদ্ধতির প্রচলিত পদ্ধতি ব্যবহার করে না অভ্যন্তরীণভাবে ফলস্বরূপ, শুধু allocate ওভাররাইড করা হচ্ছে এছাড়াও new ওভাররাইড না করে কাজ করে না যাইহোক, যদি আমরা কল করছি allocate সরাসরি, রুবি পুনরায় সংজ্ঞায়িত পদ্ধতি কল করবে। Class#new সম্পর্কে আরও জানুন এবং Class#allocate রুবির ডকুমেন্টেশনে।
কেন আমরা এটা করব?
অনেক কিছুর মতো, রুবি যেভাবে ক্লাস থেকে বস্তু তৈরি করে তা পরিবর্তন করা বিপজ্জনক হতে পারে এবং জিনিসগুলি অপ্রত্যাশিত উপায়ে ভেঙে যেতে পারে৷
তবুও, অবজেক্ট তৈরির পরিবর্তনের জন্য বৈধ ব্যবহারের ক্ষেত্রে রয়েছে। উদাহরণস্বরূপ, ActiveRecord allocate ব্যবহার করে একটি ভিন্ন init_from_db সহ অসংরক্ষিত বস্তু নির্মাণের বিপরীতে ডাটাবেস থেকে অবজেক্ট তৈরি করার সময় প্রারম্ভিক প্রক্রিয়া পরিবর্তন করার পদ্ধতি। এটি allocateও ব্যবহার করে becomes সহ বিভিন্ন একক-টেবিল উত্তরাধিকার প্রকারের মধ্যে রেকর্ড রূপান্তর করতে .
সবচেয়ে গুরুত্বপূর্ণ, অবজেক্ট তৈরির সাথে খেলার মাধ্যমে, আপনি রুবিতে এটি কীভাবে কাজ করে সে সম্পর্কে গভীর অন্তর্দৃষ্টি পান এবং বিভিন্ন সমাধানের জন্য আপনার মন খুলে দেন। আমরা আশা করি আপনি নিবন্ধটি উপভোগ করেছেন৷
অবজেক্ট তৈরি করার রুবির ডিফল্ট উপায় পরিবর্তন করে আপনি যে জিনিসগুলি বাস্তবায়ন করেছেন সে সম্পর্কে আমরা শুনতে চাই। অনুগ্রহ করে @AppSignal-এ আপনার চিন্তাভাবনা টুইট করতে দ্বিধা করবেন না৷
৷