রুবি "অবজেক্ট রেফারেন্স দ্বারা পাস" ব্যবহার করে
(পাইথনের পরিভাষা ব্যবহার করে))
রুবি "মান দ্বারা পাস" বা "রেফারেন্স দ্বারা পাস" ব্যবহার করে বলে সাহায্যকারী হওয়ার পক্ষে এটি যথেষ্ট বর্ণনামূলক নয়। আমি মনে করি যেহেতু বেশিরভাগ লোকেরা এটি জানেন, সেই পরিভাষা ("মান" বনাম "রেফারেন্স") সি ++ থেকে এসেছে।
সি ++ এ, "মান দ্বারা পাস" এর অর্থ ফাংশনটি ভেরিয়েবলের একটি অনুলিপি পায় এবং অনুলিপিতে যে কোনও পরিবর্তন আসল পরিবর্তন করে না। বস্তুর ক্ষেত্রেও এটি সত্য। যদি আপনি কোনও মান ভেরিয়েবলকে মান দ্বারা পাস করেন তবে পুরো বস্তুটি (এর সমস্ত সদস্য সহ) অনুলিপি পেতে থাকে এবং সদস্যদের যে কোনও পরিবর্তন আসল বস্তুতে সেই সদস্যগুলিকে পরিবর্তন করে না। (যদি আপনি মান অনুসারে কোনও পয়েন্টার পাস করেন তবে এটি আলাদা তবে রুবির কোনও পয়েন্টার নেই, এএফএআইকি।)
class A {
public:
int x;
};
void inc(A arg) {
arg.x++;
printf("in inc: %d\n", arg.x); // => 6
}
void inc(A* arg) {
arg->x++;
printf("in inc: %d\n", arg->x); // => 1
}
int main() {
A a;
a.x = 5;
inc(a);
printf("in main: %d\n", a.x); // => 5
A* b = new A;
b->x = 0;
inc(b);
printf("in main: %d\n", b->x); // => 1
return 0;
}
আউটপুট:
in inc: 6
in main: 5
in inc: 1
in main: 1
সি ++ এ, "রেফারেন্স দ্বারা পাস" এর অর্থ ফাংশনটি আসল ভেরিয়েবলের অ্যাক্সেস পায়। এটি সম্পূর্ণ নতুন আক্ষরিক পূর্ণসংখ্যাকে বরাদ্দ করতে পারে এবং আসল ভেরিয়েবলেরও তখন এর মানটি থাকে।
void replace(A &arg) {
A newA;
newA.x = 10;
arg = newA;
printf("in replace: %d\n", arg.x);
}
int main() {
A a;
a.x = 5;
replace(a);
printf("in main: %d\n", a.x);
return 0;
}
আউটপুট:
in replace: 10
in main: 10
যুক্তি যদি কোনও বস্তু না হয় তবে রুবি মান দ্বারা পাস (সি ++ অর্থে) ব্যবহার করে। তবে রুবিতে সবকিছুই একটি অবজেক্ট, সুতরাং রুবিতে সি ++ অর্থে সত্যিকার অর্থে কোনও পাস নেই।
রুবিতে, "অবজেক্ট রেফারেন্স দিয়ে পাস করুন" (পাইথনের পরিভাষা ব্যবহার করতে) ব্যবহৃত হয়:
- ফাংশনের অভ্যন্তরে, অবজেক্টের যে কোনও সদস্যের কাছে নতুন মান নির্ধারিত থাকতে পারে এবং ফাংশনটি ফিরে আসার পরে এই পরিবর্তনগুলি বহাল থাকবে *
- ফাংশনের অভ্যন্তরে, ভেরিয়েবলকে সম্পূর্ণ নতুন অবজেক্ট বরাদ্দকরণের ফলে ভেরিয়েবল পুরানো অবজেক্টটি উল্লেখ করা বন্ধ করে দেয়। তবে ফাংশনটি ফিরে আসার পরে, মূল পরিবর্তনশীলটি এখনও পুরানো অবজেক্টটি উল্লেখ করবে reference
সুতরাং রুবি সি ++ অর্থে "পাস বাই রেফারেন্স" ব্যবহার করেন না। যদি এটি হয়ে থাকে তবে কোনও ফাংশনের অভ্যন্তরে কোনও ভেরিয়েবলে একটি নতুন অবজেক্ট বরাদ্দকরণের ফলে ফাংশনটি ফিরে আসার পরে পুরানো অবজেক্টটি ভুলে যেতে পারে।
class A
attr_accessor :x
end
def inc(arg)
arg.x += 1
puts arg.x
end
def replace(arg)
arg = A.new
arg.x = 3
puts arg.x
end
a = A.new
a.x = 1
puts a.x # 1
inc a # 2
puts a.x # 2
replace a # 3
puts a.x # 2
puts ''
def inc_var(arg)
arg += 1
puts arg
end
b = 1 # Even integers are objects in Ruby
puts b # 1
inc_var b # 2
puts b # 1
আউটপুট:
1
2
2
3
2
1
2
1
* এই কারণেই, রুবিতে, আপনি যদি কোনও ফাংশনের অভ্যন্তরে কোনও অবজেক্ট পরিবর্তন করতে চান তবে ফাংশনটি ফিরে আসার পরে সেই পরিবর্তনগুলি ভুলে যেতে পারেন, তবে অনুলিপিটি অনুলিপি করে নিজের অস্থায়ী পরিবর্তন করার আগে আপনাকে অবশ্যই স্পষ্টভাবে অবজেক্টের একটি অনুলিপি তৈরি করতে হবে।