রুবি ম্যাজিকের একটি নতুন পর্বে স্বাগতম! এই মাসের সংস্করণটি মেটাক্লাস সম্পর্কে, একটি বিষয় যা দুই ডেভেলপারের (হাই মাউড!) মধ্যে আলোচনার মাধ্যমে ছড়িয়ে পড়েছে।
মেটাক্লাসগুলি পরীক্ষা করার মাধ্যমে, আমরা রুবিতে ক্লাস এবং ইনস্ট্যান্স পদ্ধতিগুলি কীভাবে কাজ করে তা শিখব। পথ ধরে, একটি সুস্পষ্ট "সংজ্ঞায়িত" পাস করে এবং class << self
ব্যবহার করে একটি পদ্ধতি সংজ্ঞায়িত করার মধ্যে পার্থক্য আবিষ্কার করুন অথবা instance_eval
. চলুন!
ক্লাস ইনস্ট্যান্স এবং ইনস্ট্যান্স পদ্ধতি
রুবিতে কেন মেটাক্লাস ব্যবহার করা হয় তা বোঝার জন্য, আমরা ইনস্ট্যান্স- এবং ক্লাস পদ্ধতির মধ্যে পার্থক্যগুলি পরীক্ষা করে শুরু করব।
রুবিতে, একটি শ্রেণী একটি অবজেক্ট যা অন্য অবজেক্ট তৈরি করার জন্য একটি ব্লুপ্রিন্ট সংজ্ঞায়িত করে। ক্লাসগুলি সেই ক্লাসের যেকোন উদাহরণে কোন পদ্ধতিগুলি উপলব্ধ তা নির্ধারণ করে৷
৷একটি ক্লাসের ভিতরে একটি পদ্ধতি সংজ্ঞায়িত করা একটি ইনস্ট্যান্স পদ্ধতি তৈরি করে সেই ক্লাসে। সেই ক্লাসের যেকোন ভবিষ্যত দৃষ্টান্তে সেই পদ্ধতিটি উপলব্ধ থাকবে।
class User
def initialize(name)
@name = name
end
def name
@name
end
end
user = User.new('Thijs')
user.name # => "Thijs"
এই উদাহরণে, আমরা User
নামে একটি ক্লাস তৈরি করি , একটি উদাহরণ পদ্ধতি সহ #name
নামে যে ব্যবহারকারীর নাম ফেরত দেয়। ক্লাস ব্যবহার করে, আমরা তারপর একটি ক্লাস ইনস্ট্যান্স তৈরি করি এবং এটিকে user
নামে একটি ভেরিয়েবলে সংরক্ষণ করুন . যেহেতু user
User
এর একটি উদাহরণ ক্লাস, এটির #name
আছে পদ্ধতি উপলব্ধ।
একটি শ্রেণী তার পদ্ধতি টেবিলে তার উদাহরণ পদ্ধতি সংরক্ষণ করে . ক্লাসের যেকোন ইন্সট্যান্স তার ক্লাসের মেথড টেবিলকে বোঝায় যাতে তার ইনস্ট্যান্স মেথড অ্যাক্সেস করা যায়।
ক্লাস অবজেক্ট
একটি শ্রেণী পদ্ধতি একটি পদ্ধতি যা প্রথমে একটি উদাহরণ তৈরি না করে সরাসরি ক্লাসে কল করা যেতে পারে। self.
এর সাথে নামের উপসর্গ দিয়ে একটি ক্লাস পদ্ধতি তৈরি করা হয় এটি সংজ্ঞায়িত করার সময়।
একটি শ্রেণী নিজেই একটি বস্তু। একটি ধ্রুবক ক্লাস অবজেক্টকে বোঝায়, তাই এটিতে সংজ্ঞায়িত ক্লাস পদ্ধতিগুলি অ্যাপ্লিকেশনের যে কোনও জায়গা থেকে কল করা যেতে পারে।
class User
# ...
def self.all
[new("Thijs"), new("Robert"), new("Tom")]
end
end
User.all # => [#<User:0x00007fb01701efb8 @name="Thijs">, #<User:0x00007fb01701ef68 @name="Robert">, #<User:0x00007fb01701ef18 @name="Tom">]
একটি self.
দিয়ে সংজ্ঞায়িত পদ্ধতি -প্রিফিক্স ক্লাসের পদ্ধতি টেবিলে যোগ করা হয় না। তারা পরিবর্তে ক্লাসের মেটাক্লাসে যোগ করা হয়েছে।
মেটাক্লাসেস
একটি ক্লাস বাদে, রুবির প্রতিটি বস্তুর একটি লুকানো মেটাক্লাস রয়েছে। মেটাক্লাসগুলি সিঙ্গলটন, যার অর্থ তারা একটি একক বস্তুর অন্তর্গত। আপনি যদি একটি ক্লাসের একাধিক দৃষ্টান্ত তৈরি করেন, তবে তারা একই ক্লাস ভাগ করবে, তবে তাদের সকলের আলাদা মেটাক্লাস থাকবে।
thijs, robert, tom = User.all
thijs.class # => User
robert.class # => User
tom.class # => User
thijs.singleton_class # => #<Class:#<User:0x00007fb71a9a2cb0>>
robert.singleton_class # => #<Class:#<User:0x00007fb71a9a2c60>>
tom.singleton_class # => #<Class:#<User:0x00007fb71a9a2c10>>
এই উদাহরণে, আমরা দেখতে পাই যে যদিও প্রতিটি বস্তুর User
ক্লাস আছে , তাদের সিঙ্গলটন ক্লাসের আলাদা অবজেক্ট আইডি আছে, মানে তারা আলাদা অবজেক্ট।
একটি মেটাক্লাস অ্যাক্সেস করে, রুবি বিদ্যমান বস্তুতে সরাসরি পদ্ধতি যোগ করার অনুমতি দেয়। এটি করা বস্তুর ক্লাসে একটি নতুন পদ্ধতি যোগ করবে না।
robert = User.new("Robert")
def robert.last_name
"Beekman"
end
robert.last_name # => "Beekman"
User.new("Tom").last_name # => NoMethodError (undefined method `last_name' for #<User:0x00007fe1cb116408>)
এই উদাহরণে, আমরা একটি #last_name
যোগ করি robert
-এ সংরক্ষিত ব্যবহারকারীর কাছে পরিবর্তনশীল যদিও robert
user
এর একটি উদাহরণ , user
-এর যেকোন সদ্য নির্মিত দৃষ্টান্ত #last_name
-এ অ্যাক্সেস থাকবে না পদ্ধতি, যেহেতু এটি শুধুমাত্র robert
-এ বিদ্যমান এর মেটাক্লাস।
self.
কি ?
একটি পদ্ধতি সংজ্ঞায়িত করার সময় এবং একটি রিসিভার পাস করার সময়, নতুন পদ্ধতিটি ক্লাসের মেথড টেবিলে যোগ করার পরিবর্তে রিসিভারের মেটাক্লাসে যোগ করা হয়।
tom = User.new("Tom")
def tom.last_name
"de Bruijn"
end
উপরের উদাহরণে, আমরা #last_name
যোগ করেছি সরাসরি tom
-এ বস্তু, tom
পাস করে পদ্ধতি সংজ্ঞায়িত করার সময় রিসিভার হিসাবে।
এটি ক্লাস পদ্ধতির জন্যও কাজ করে।
class User
# ...
def self.all
[new("Thijs"), new("Robert"), new("Tom")]
end
end
এখানে, আমরা স্পষ্টভাবে self.
পাস করি .all
তৈরি করার সময় রিসিভার হিসাবে পদ্ধতি একটি শ্রেণীর সংজ্ঞায়, self.
ক্লাস বোঝায় (user
এই ক্ষেত্রে), তাই .all
পদ্ধতিটি user
-এ যোগ করা হয় এর মেটাক্লাস।
কারণ user
একটি ধ্রুবকের মধ্যে সংরক্ষিত একটি বস্তু, আমরা একই বস্তু-এবং একই মেটাক্লাস-কে অ্যাক্সেস করব-যখনই আমরা এটি উল্লেখ করি।
মেটাক্লাস খোলা হচ্ছে
আমরা শিখেছি যে ক্লাস পদ্ধতিগুলি ক্লাস অবজেক্টের মেটাক্লাসের পদ্ধতি। এটি জেনে, আমরা ক্লাস পদ্ধতি তৈরি করার আরও কিছু কৌশল দেখব যা আপনি আগে দেখেছেন৷
class << self
যদিও এটি কিছুটা শৈলীর বাইরে চলে গেছে, কিছু লাইব্রেরি class << self
ব্যবহার করে ক্লাস পদ্ধতি সংজ্ঞায়িত করতে। এই সিনট্যাক্স কৌশলটি বর্তমান ক্লাসের মেটাক্লাস খুলে দেয় এবং সরাসরি এটির সাথে ইন্টারঅ্যাক্ট করে।
class User
class << self
self # => #<Class:User>
def all
[new("Thijs"), new("Robert"), new("Tom")]
end
end
end
User.all # => [#<User:0x00007fb01701efb8 @name="Thijs">, #<User:0x00007fb01701ef68 @name="Robert">, #<User:0x00007fb01701ef18 @name="Tom">]
এই উদাহরণটি User.all
নামে একটি ক্লাস পদ্ধতি তৈরি করে user
এ একটি পদ্ধতি যোগ করে এর মেটাক্লাস। আমরা পূর্বে দেখেছি পদ্ধতিটির জন্য স্পষ্টভাবে একটি রিসিভার পাস করার পরিবর্তে, আমরা self.
সেট করি user
এর কাছে User
এর পরিবর্তে এর মেটাক্লাস নিজেই।
আমরা আগে শিখেছি, একটি স্পষ্ট রিসিভার ছাড়া যেকোন পদ্ধতির সংজ্ঞা বর্তমান ক্লাসের একটি উদাহরণ পদ্ধতি হিসাবে যোগ করা হয়। ব্লকের ভিতরে, বর্তমান ক্লাস হল User
এর মেটাক্লাস (#<Class:User>
)।
instance_eval
আরেকটি বিকল্প হল instance_eval
ব্যবহার করে , যা একটি প্রধান পার্থক্যের সাথে একই জিনিস করে। যদিও ক্লাসের মেটাক্লাস ব্লকে সংজ্ঞায়িত পদ্ধতিগুলি গ্রহণ করে, self.
প্রধান শ্রেণীর একটি রেফারেন্স থেকে যায়।
class User
instance_eval do
self # => User
def all
[new("Thijs"), new("Robert"), new("Tom")]
end
end
end
User.all # => [#<User:0x00007fb01701efb8 @name="Thijs">, #<User:0x00007fb01701ef68 @name="Robert">, #<User:0x00007fb01701ef18 @name="Tom">]
এই উদাহরণে, আমরা User
-এ একটি উদাহরণ পদ্ধতি সংজ্ঞায়িত করি এর মেটাক্লাস ঠিক আগের মতই, কিন্তু self.
এখনও user
নির্দেশ করে . যদিও এটি সাধারণত একই বস্তুর দিকে নির্দেশ করে, "ডিফল্ট সংজ্ঞা" এবং self.
বিভিন্ন বস্তুর দিকে নির্দেশ করতে পারে।
আমরা যা শিখেছি
আমরা শিখেছি যে ক্লাসগুলিই একমাত্র অবজেক্ট যার পদ্ধতি থাকতে পারে এবং সেই উদাহরণ পদ্ধতিগুলি আসলে একটি বস্তুর মেটাক্লাসের পদ্ধতি। আমরা জানি যে class << self
সহজভাবে self.
অদলবদল করে আপনাকে মেটাক্লাসে পদ্ধতিগুলি সংজ্ঞায়িত করার অনুমতি দেওয়ার জন্য, এবং আমরা জানি যে instance_eval
বেশিরভাগই একই জিনিস করে (কিন্তু self.
স্পর্শ না করে )।
যদিও আপনি স্পষ্টভাবে মেটাক্লাসের সাথে কাজ করবেন না, রুবি তাদের হুডের নিচে ব্যাপকভাবে ব্যবহার করে। আপনি যখন একটি পদ্ধতি সংজ্ঞায়িত করেন তখন কী ঘটবে তা জানা আপনাকে বুঝতে সাহায্য করতে পারে যে কেন রুবি এটির মতো আচরণ করে (এবং কেন আপনাকে self.
এর সাথে ক্লাস পদ্ধতির উপসর্গ দিতে হবে। )।
পড়ার জন্য ধন্যবাদ. আপনি যা পড়েছেন তা পছন্দ করলে, আমরা মাসে একবার একটি নতুন নিবন্ধ প্রকাশ করলে একটি ই-মেইল পেতে আপনি রুবি ম্যাজিকের সদস্যতা নিতে চাইতে পারেন।