আপনি একটি পদ্ধতি কল যখন কি ঘটবে বলে মনে করেন? একই নামের অন্য একটি পদ্ধতি থাকলে রুবি কীভাবে সিদ্ধান্ত নেয় কোন পদ্ধতিতে কল করবে? আপনি কি কখনও ভেবে দেখেছেন যে পদ্ধতিটি কোথায় রাখা হয়েছে বা উৎস থেকে এসেছে?
রুবি একটি সংজ্ঞায়িত "পথ" বা "প্যাটার্ন" ব্যবহার করে কল করার সঠিক পদ্ধতি এবং "কোন পদ্ধতির ত্রুটি নেই" ফেরত দেওয়ার সঠিক সময় নির্ধারণ করতে, এবং আমরা এটিকে "পথ" বলতে পারি রুবি মেথড লুকআপ পাথ> .এই টিউটোরিয়ালে, আমরা রুবির মেথড লুকআপে ডুব দেব। শেষে, আপনি কোন পদ্ধতির কথা বলছেন তা নির্ধারণ করতে রুবি কীভাবে একটি বস্তুর অনুক্রমের মধ্য দিয়ে যায় সে সম্পর্কে আপনার ভাল ধারণা থাকবে।
আমরা যা শিখব তা সম্পূর্ণরূপে উপলব্ধি করার জন্য, আপনাকে রুবি সম্পর্কে একটি প্রাথমিক ধারণা থাকতে হবে। যদিও আমরা মডিউল এবং ক্লাসের মতো জিনিসগুলি উল্লেখ করব, এটি তারা যা করে তার গভীরে ডুব দেবে না। আমরা শুধুমাত্র এই টিউটোরিয়ালের লক্ষ্যে পৌঁছানোর জন্য প্রয়োজনীয় গভীরতাকে কভার করব:রুবি কীভাবে একটি বস্তুতে আপনি যে বার্তা (পদ্ধতি) দিচ্ছেন তা নির্ধারণ করে।
ওভারভিউ
যখন আপনি কোনো পদ্ধতিকে কল করেন, যেমন first_person.valid? , রুবিকে কিছু জিনিস নির্ধারণ করতে হবে:
- পদ্ধতিটি কোথায়
.valid?সংজ্ঞায়িত করা হয়েছে। - এমন একাধিক জায়গা আছে যেখানে
.valid?পদ্ধতি সংজ্ঞায়িত করা হয়? যদি তাই হয়, তাহলে এই প্রসঙ্গে ব্যবহার করার জন্য কোনটি সঠিক।
রুবি যে প্রক্রিয়াটি (বা পথ) অনুসরণ করে সেটিকে আমরা মথড লুকআপ বলি। . রুবিকে খুঁজে বের করতে হবে কোথায় পদ্ধতিটি তৈরি করা হয়েছে যাতে এটি কল করতে পারে। এটি সঠিক পদ্ধতিতে কল করেছে তা নিশ্চিত করতে এটিকে নিম্নলিখিত স্থানে অনুসন্ধান করতে হবে:
- সিঙ্গেলটন পদ্ধতি:রুবি একটি বস্তুর নিজস্ব পদ্ধতি সংজ্ঞায়িত করার একটি উপায় প্রদান করে; এই পদ্ধতিগুলি শুধুমাত্র সেই বস্তুর জন্য উপলব্ধ এবং অবজেক্টের একটি উদাহরণ দ্বারা অ্যাক্সেস করা যায় না৷ ৷
- মিক্সড-ইন মডিউলে পদ্ধতি:
prependব্যবহার করে মডিউলগুলিকে একটি ক্লাসে মিশ্রিত করা যেতে পারে ,include, অথবাextend. যখন এটি ঘটে, ক্লাসের মডিউলগুলিতে সংজ্ঞায়িত পদ্ধতিগুলিতে অ্যাক্সেস থাকে এবং রুবি যে পদ্ধতিটিকে কল করা হয়েছে তা অনুসন্ধান করতে মডিউলগুলিতে যায়। এটি জানাও গুরুত্বপূর্ণ যে অন্যান্য মডিউলগুলিকে প্রাথমিক মডিউলগুলিতে মিশ্রিত করা যেতে পারে, এবং অনুসন্ধানও এগুলির মধ্যে অগ্রসর হয়৷ - উদাহরণ পদ্ধতি:এগুলি ক্লাসে সংজ্ঞায়িত পদ্ধতি এবং সেই ক্লাসের উদাহরণ দ্বারা অ্যাক্সেসযোগ্য৷
- অভিভাবক শ্রেণীর পদ্ধতি বা মডিউল:যদি ক্লাসটি অন্য শ্রেণীর সন্তান হয়, রুবি পিতামাতার ক্লাসে অনুসন্ধান করে। অনুসন্ধানটি অভিভাবক শ্রেণীর সিঙ্গেলটন পদ্ধতি, মিশ্র মডিউল এবং এর অভিভাবক শ্রেণিতে যায়৷
- অবজেক্ট, কার্নেল, এবং বেসিকঅবজেক্ট:এই হল শেষ স্থান যেখানে রুবি অনুসন্ধান করে। এর কারণ রুবির প্রতিটি বস্তুর পূর্বপুরুষের অংশ হিসেবে এগুলি রয়েছে৷
ক্লাস এবং মডিউল
পদ্ধতি প্রায়ই বস্তুর উপর বলা হয়. এই অবজেক্টগুলি নির্দিষ্ট ক্লাস দ্বারা তৈরি করা হয়, যা রুবির অন্তর্নির্মিত ক্লাস বা বিকাশকারী দ্বারা তৈরি করা ক্লাস হতে পারে৷
class Human
attr_reader :name
def initialize(name)
@name = name
end
def hello
put "Hello! #{name}"
end
end
আমরা তখন hello কল করতে পারি পদ্ধতি যা আমরা উপরে Human এর উদাহরণে তৈরি করেছি ক্লাস; উদাহরণস্বরূপ,
john = Human.new("John")
john.hello # Output -> Hello John
hello পদ্ধতি একটি উদাহরণ পদ্ধতি; এই কারণেই আমরা এটিকে Human এর দৃষ্টান্তে কল করতে পারি ক্লাস এমন কিছু ক্ষেত্রে হতে পারে যেখানে আমরা চাই না যে পদ্ধতিটি দৃষ্টান্তে কল করা হোক। এই ক্ষেত্রে, আমরা ক্লাসেই পদ্ধতিটিকে কল করতে চাই। এটি অর্জন করতে, আমাদের একটি ক্লাস পদ্ধতি তৈরি করতে হবে। উপরের ক্লাসের জন্য একটি ক্লাস পদ্ধতি সংজ্ঞায়িত করা এইরকম দেখাবে:
def self.me
puts "I am a class method"
end
তারপর আমরা Human.me করে এটিকে কল করতে পারি . আমাদের অ্যাপ্লিকেশনের জটিলতা বাড়ার সাথে সাথে (ভাবুন আমরা এখানে একটি নতুন স্টার্ট-আপ তৈরি করছি), এমন একটি সময় আসতে পারে যখন আমাদের দুই বা তার বেশি ক্লাসের একাধিক পদ্ধতি রয়েছে যা একই কাজ করে। যদি এটি ঘটে থাকে, এর অর্থ হল আমাদের জিনিসগুলিকে শুকনো রাখতে হবে এবং নিশ্চিত করতে হবে যে আমরা নিজেদের পুনরাবৃত্তি না করি। এই শ্রেণীতে আমরা কীভাবে কার্যকারিতা শেয়ার করি তা এই সমস্যাটি জড়িত৷
আপনি যদি আগে মডিউল ব্যবহার না করে থাকেন, তাহলে আপনি এই "ভাগ করা" পদ্ধতির জন্য কঠোরভাবে একটি নতুন ক্লাস তৈরি করতে প্রলুব্ধ হতে পারেন। যাইহোক, এটি করার ফলে নেতিবাচক পরিণতি হতে পারে, বিশেষ করে যখন আপনাকে একাধিক উত্তরাধিকার ব্যবহার করতে হবে, এমন কিছু যা রুবি সমর্থন করে না। মডিউলগুলি এই কেস পরিচালনার সর্বোত্তম উপায়। মডিউলগুলি ক্লাসের অনুরূপ, তবে তাদের কয়েকটি পার্থক্য রয়েছে। প্রথমত, এখানে একটি মডিউল দেখতে কেমন তার একটি উদাহরণ:
module Movement
def walk
puts "I can walk!"
end
end
- সংজ্ঞা শুরু হয়
moduleদিয়েclassএর পরিবর্তে কীওয়ার্ড . - মডিউলগুলিতে উদাহরণ থাকতে পারে না, তাই আপনি
Movement.newব্যবহার করতে পারবেন না .
পদ্ধতি
পদ্ধতিগুলিকে একটি নির্দিষ্ট বস্তু দ্বারা সঞ্চালিত ক্রিয়া হিসাবে দেখা যেতে পারে। আমার যদি [2, 3, 4] এর মত একটি অ্যারে থাকে numberList নামক একটি ভেরিয়েবলে বরাদ্দ করা হয়েছে , .push পদ্ধতি হল একটি ক্রিয়া যা অ্যারে দ্বারা পুট করা যেতে পারে এটি অ্যারের মধ্যে প্রাপ্ত মান। এই কোড স্নিপেট একটি উদাহরণ:
john.walk
এটি আপনার কাছে সাধারণ কিছু বলতে পারে, "আমি বস্তুর পদ্ধতিতে কল করছি", যেখানে john একটি বস্তুর উল্লেখ করে যা Human এর একটি উদাহরণ , এবং walk পদ্ধতি। যাইহোক, এটি সম্পূর্ণ সত্য নয় কারণ অনুমানকৃত পদ্ধতিটি বস্তুর ক্লাস, সুপারক্লাস বা মিক্সড-ইন থেকে আসে মডিউল।
এটি যোগ করা গুরুত্বপূর্ণ যে একটি বস্তুর উপর একটি পদ্ধতি সংজ্ঞায়িত করা সম্ভব, এমনকি একটি বস্তু যেমন john , কারণ রুবিতে সবকিছুই একটি অবজেক্ট, এমনকি একটি ক্লাস অবজেক্ট তৈরিতে ব্যবহৃত হয়।
def john.drip
puts "My drip is eternal"
end
drip পদ্ধতিটি শুধুমাত্র john-কে বরাদ্দ করা বস্তু দ্বারা অ্যাক্সেসযোগ্য হতে পারে . drip এটি একটি সিঙ্গলটন পদ্ধতি যা john এর কাছে উপলব্ধ হবে বস্তু এটা জানা গুরুত্বপূর্ণ যে সিঙ্গলটন পদ্ধতি এবং ক্লাস পদ্ধতির মধ্যে কোন পার্থক্য নেই, আপনি এই স্ট্যাক ওভারফ্লো উত্তর থেকে দেখতে পারেন। আপনি উপরের উদাহরণের মতো একটি বস্তুর উপর সংজ্ঞায়িত একটি পদ্ধতি উল্লেখ না করা পর্যন্ত, এটি বলা ভুল হবে যে পদ্ধতিটি একটি নির্দিষ্ট বস্তুর অন্তর্গত। আমাদের উদাহরণে, walk পদ্ধতিটি Movement এর অন্তর্গত মডিউল, যখন hello পদ্ধতিটি Human এর অন্তর্গত ক্লাস এই বোঝার সাথে, এটিকে আরও এক ধাপ এগিয়ে নেওয়া সহজ হবে, যা হল যে কোনও বস্তুর উপর যে সঠিক পদ্ধতিটি কল করা হচ্ছে তা নির্ধারণ করতে, রুবিকে অবজেক্টের ক্লাস বা সুপার ক্লাস বা মডিউলগুলি পরীক্ষা করতে হবে যা মিশ্রিত হয়েছে। বস্তুর অনুক্রমের মধ্যে।
মিক্সিং মডিউল
রুবি শুধুমাত্র একক উত্তরাধিকার সমর্থন করে; একটি শ্রেণী শুধুমাত্র একটি শ্রেণী থেকে উত্তরাধিকারী হতে পারে। এটি শিশু শ্রেণীর পক্ষে অন্য শ্রেণীর আচরণ (পদ্ধতি) উত্তরাধিকার সূত্রে পাওয়া সম্ভব করে তোলে। যখন আপনার এমন আচরণ থাকে যা বিভিন্ন শ্রেণিতে ভাগ করা দরকার তখন কী ঘটে? উদাহরণস্বরূপ, walk করতে Human উদাহরণের জন্য পদ্ধতি উপলব্ধ ক্লাস, আমরা মিশ্রিত করতে পারি Movement Human মডিউল ক্লাস সুতরাং, Human এর একটি পুনর্লিখন include ব্যবহার করে ক্লাস এই মত দেখাবে:
require "movement" # Assuming we have the module in a file called movement.rb
class Human
include Movement
attr_reader :name
def initialize(name)
@name = name
end
def hello
put "Hello! #{name}"
end
end
এখন, আমরা walk কল করতে পারি উদাহরণে পদ্ধতি:
john = Human.new("John")
john.walk
অন্তর্ভুক্ত করুন
আপনি যখন অন্তর্ভুক্ত করুন ব্যবহার করেন কীওয়ার্ড, যেমন আমরা উপরে করেছি, অন্তর্ভুক্ত মডিউল(গুলি) এর পদ্ধতিগুলি উদাহরণ পদ্ধতি(গুলি) হিসাবে ক্লাসে যুক্ত হয়। এর কারণ হল অন্তর্ভুক্ত মডিউল পূর্বপুরুষদের মধ্যে যোগ করা হয়েছে Human ক্লাস, যেমন Movement মডিউলটিকে Human-এর অভিভাবক হিসাবে দেখা যেতে পারে ক্লাস আমরা উপরে দেখানো উদাহরণে আপনি দেখতে পাচ্ছেন, আমরা walk বলেছি Human এর উদাহরণে পদ্ধতি ক্লাস।
প্রসারিত করুন
অন্তর্ভুক্ত ছাড়াও , রুবি আমাদের এক্সটেন্ড প্রদান করে কীওয়ার্ড এটি ক্লাস পদ্ধতি(গুলি) হিসাবে ক্লাসের জন্য উপলব্ধ মডিউল(গুলি) এর পদ্ধতি(গুলি) তৈরি করে, যা সিঙ্গলটন পদ্ধতি হিসাবেও পরিচিত, যেমনটি আমরা আগে শিখেছি। সুতরাং, যদি আমাদের Feeding নামে একটি মডিউল থাকে যেটা মনে হচ্ছে
module Feeding
def food
"I make my food :)"
end
end
তারপরে আমরা এই আচরণটি আমাদের Human-এ শেয়ার করতে পারি এটির প্রয়োজন এবং extend Feeding যোগ করে ক্লাস করুন . যাইহোক, এটি ব্যবহার করতে, পরিবর্তে food কল করুন ক্লাসের উদাহরণে মেথড, আমরা এটাকে ক্লাসেই কল করব, যেভাবে আমরা ক্লাস মেথড বলি।
Human.food
প্রিপেন্ড
এটি অন্তর্ভুক্ত এর মত কিন্তু কিছু পার্থক্যের সাথে, যেমন এই পোস্টে বলা হয়েছে;
এটি আসলে অন্তর্ভুক্ত করার মত কাজ করে, ব্যতীত যে মডিউলটি ক্লাস এবং এর সুপারক্লাসের মধ্যে চেইনে ঢোকানোর পরিবর্তে, এটি চেইনের নীচে, এমনকি ক্লাসের আগেও এটি সন্নিবেশ করাবে।
এর মানে হল যে ক্লাস ইনস্ট্যান্সে একটি পদ্ধতি কল করার সময়, রুবি ক্লাসে দেখার আগে মডিউল পদ্ধতিগুলি খতিয়ে দেখবে৷
যদি আমাদের একটি মডিউল থাকে যা একটি hello সংজ্ঞায়িত করে পদ্ধতি যা আমরা তারপর Human-এ মিশ্রিত করি prepend ব্যবহার করে ক্লাস , রুবি আমাদের ক্লাসে যে পদ্ধতিটি আছে তার পরিবর্তে আমাদের মডিউলে যে পদ্ধতিটি আছে তাকে কল করবে৷
রুবির prepend কীভাবে তা সঠিকভাবে বোঝার জন্য কাজ করে, আমি এই নিবন্ধটি একবার দেখার পরামর্শ দিই৷
পদ্ধতি লুকআপ পাথ
একটি মেথড কল করার চেষ্টা করার সময় রুবি ইন্টারপ্রেটার প্রথম যে জায়গাটি দেখে তা হল সিঙ্গেলটন পদ্ধতি। আমি এই রিপ্লটি তৈরি করেছি, যা আপনি সম্ভাব্য ফলাফল দেখতে খেলতে পারেন।
ধরুন আমাদের কাছে একগুচ্ছ মডিউল এবং ক্লাস আছে যা দেখতে নিচের মত:
module One
def another
puts "From one module"
end
end
module Two
def another
puts "From two module"
end
end
module Three
def another
puts "From three module"
end
end
class Creature
def another
puts "From creature class"
end
end
আসুন এগুলিকে Human-এ মিশ্রিত করতে এগিয়ে যাই ক্লাস।
class Human < Creature
prepend Three
extend Two
include One
def another
puts "Instance method"
end
def self.another
puts "From Human class singleton"
end
end
মডিউলগুলি মিশ্রিত করা ছাড়াও, আমাদের একটি উদাহরণ এবং ক্লাস পদ্ধতি রয়েছে। আপনি দেখতে পারেন যে Human ক্লাস হল Creature এর একটি সাবক্লাস ক্লাস।
প্রথম লুকআপ - সিঙ্গেলটন পদ্ধতি
যখন আমরা Human.another চালাই , যা মুদ্রিত হয় তা হল From Human class singleton থেকে , যা আমাদের ক্লাস পদ্ধতিতে আছে। যদি আমরা ক্লাস পদ্ধতিটি মন্তব্য করি এবং এটি আবার চালাই, তাহলে এটি From two module প্রিন্ট করবে কনসোলে এটি আসে সেই মডিউল থেকে যা আমরা extend ব্যবহার করে মিশ্রিত করেছি . এটি দেখায় যে সিঙ্গেলটন পদ্ধতির মধ্যে লুকআপ শুরু হয়। যদি আমরা অপসারণ (বা মন্তব্য আউট) extend Two এবং আবার কমান্ড চালান, এটি একটি পদ্ধতি অনুপস্থিত ত্রুটি নিক্ষেপ করবে . আমরা এই ত্রুটিটি পেয়েছি কারণ রুবি another খুঁজে পায়নি সিঙ্গলটন পদ্ধতির মধ্যে পদ্ধতি।
আমরা এগিয়ে যাব এবং একটি উদাহরণ তৈরি করে ক্লাস ইনস্ট্যান্স ব্যবহার করব:
n = Human.new
আমরা উদাহরণের জন্য একটি সিঙ্গলটন পদ্ধতিও তৈরি করব:
def n.another
puts "From n object"
end
এখন, যখন আমরা n.another চালাই , যে সংস্করণটিকে বলা হয় সেটি হল n-এ সংজ্ঞায়িত সিঙ্গেলটন পদ্ধতি বস্তু যে কারণে রুবি extend ব্যবহার করে মডিউলটিকে মিশ্রিত বলে মনে করবে না এই ক্ষেত্রে কারণ আমরা ক্লাসের উদাহরণে পদ্ধতিটিকে কল করছি। এটা জানা গুরুত্বপূর্ণ যে extend ব্যবহারে মিশ্রিত মডিউল যুক্ত পদ্ধতিগুলির তুলনায় সিঙ্গলটন পদ্ধতিগুলির একটি উচ্চতর প্রাসঙ্গিকতা রয়েছে .
সেকেন্ড লুক-আপ - preprend ব্যবহার করে মিশ্রিত মডিউল
যদি আমরা n এ সিঙ্গেলটন পদ্ধতি সম্পর্কে মন্তব্য করি অবজেক্ট এবং কমান্ড চালান, পদ্ধতির যে সংস্করণটি বলা হয় সেটি হল মডিউলটি যা আমরা prepend ব্যবহার করে মিশ্রিত করেছি। . এর কারণ হল prepend ব্যবহার ক্লাসের আগে মডিউল সন্নিবেশ করান।
তৃতীয় লুকআপ - ক্লাস
যদি আমরা মডিউল Three মন্তব্য করি , another এর সংস্করণ যে পদ্ধতিটিকে কল করা হয় সেটি হল ক্লাসে সংজ্ঞায়িত ইনস্ট্যান্স পদ্ধতি।
চতুর্থ লুকআপ - include ব্যবহার করে মিশ্রিত মডিউল
রুবি পদ্ধতির জন্য পরবর্তী যে স্থানটি অনুসন্ধান করে তা হল মডিউলগুলিতে যা include ব্যবহার করে মিশ্রিত হয়েছে . সুতরাং, যখন আমরা উদাহরণ পদ্ধতিতে মন্তব্য করি, তখন আমরা যে সংস্করণটি পাই তা হল মডিউল One-এ .
পঞ্চম লুকআপ - অভিভাবক শ্রেণী
যদি ক্লাসের একটি অভিভাবক ক্লাস থাকে, রুবি ক্লাসে অনুসন্ধান করে। অনুসন্ধানটি অভিভাবক শ্রেণিতে মিশ্রিত মডিউলগুলিতে যাওয়া অন্তর্ভুক্ত করে; যদি আমরা Creature-এ মিশ্রিত একটি মডিউলে পদ্ধতি সংজ্ঞায়িত করতাম ক্লাস, পদ্ধতি কল করা হবে।
পদ্ধতি অনুসন্ধানের সমাপ্তি
আমরা জানতে পারি কোন পদ্ধতির অনুসন্ধান কোথায় শেষ হয় তার পূর্বপুরুষদের যাচাই করে:কলিং .ancestors ক্লাসে Human এর জন্য এটি করা হচ্ছে ক্লাস [Three, Human, One, Creature, Object, Kernel, BasicObject] ফেরত দেবে . একটি পদ্ধতির অনুসন্ধান BasicObject এ শেষ হয় ক্লাস, যা রুবির রুট ক্লাস। প্রতিটি বস্তু যা কিছু শ্রেণীর একটি উদাহরণ BasicObject থেকে উদ্ভূত ক্লাস।
পদ্ধতি অনুসন্ধানটি বিকাশকারী-সংজ্ঞায়িত পিতামাতার শ্রেণী অতিক্রম করার পরে, এটি নিম্নলিখিতটিতে পৌঁছে যায়:
-
Objectক্লাস -
Kernelমডিউল -
BasicObjectক্লাস
method_missing পদ্ধতি
আপনি যদি কিছুদিন ধরে রুবি ব্যবহার করে থাকেন, তাহলে সম্ভবত আপনি NoMethodError দেখেছেন , যা ঘটে যখন আপনি একটি বস্তুর উপর একটি অজানা পদ্ধতির চেষ্টা করেন। রুবি বস্তুর পূর্বপুরুষের মধ্য দিয়ে যাওয়ার পরে এবং বলা পদ্ধতিটি খুঁজে না পাওয়ার পরে এটি ঘটে। আপনি যে ত্রুটি বার্তাটি পেয়েছেন তা method_missing দ্বারা পরিচালিত হয়৷ পদ্ধতি, BasicObject-এ সংজ্ঞায়িত ক্লাস আপনি যে অবজেক্টে মেথড কল করছেন সেটির মেথড ওভাররাইড করা সম্ভব, যা আপনি এটি চেক করে জানতে পারবেন।
উপসংহার
এখন আপনি জানেন যে রুবি একটি অবজেক্টের উপর বলা পদ্ধতিটি বের করতে যে পথটি নেয়। এই বোঝার সাথে, আপনি একটি বস্তুর উপর একটি অজানা পদ্ধতি কল করার ফলে উদ্ভূত ত্রুটিগুলি সহজেই ঠিক করতে সক্ষম হবেন৷