रूबी "ऑब्जेक्ट संदर्भ द्वारा पास" का उपयोग करती है
(अजगर की शब्दावली का उपयोग करना।)
कहने के लिए रूबी "पास बाय वैल्यू" या "पास बाय रेफरेंस" वास्तव में सहायक होने के लिए वर्णनात्मक नहीं है। मुझे लगता है कि ज्यादातर लोग इन दिनों इसे जानते हैं, यह शब्दावली ("मूल्य" बनाम "संदर्भ") सी ++ से आता है।
C ++ में, "पास बाय वैल्यू" का अर्थ है कि फंक्शन को वेरिएबल की कॉपी मिलती है और कॉपी में कोई भी बदलाव मूल को नहीं बदलता है। यह वस्तुओं के लिए भी सच है। यदि आप किसी ऑब्जेक्ट चर को मान से पास करते हैं तो संपूर्ण ऑब्जेक्ट (उसके सभी सदस्यों सहित) की प्रतिलिपि हो जाती है और सदस्यों में कोई भी परिवर्तन उन सदस्यों को मूल ऑब्जेक्ट पर नहीं बदलता है। (यह अलग है अगर आप एक पॉइंटर को वैल्यू से पास करते हैं लेकिन रूबी के पास वैसे भी एएफएआईके नहीं है।)
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
C ++ में, "पास से संदर्भ" का अर्थ है कि फ़ंक्शन को मूल चर तक पहुंच मिलती है। यह एक नया शाब्दिक पूर्णांक निर्दिष्ट कर सकता है और मूल चर का मान तब भी होगा।
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
यदि तर्क कोई वस्तु नहीं है, तो रूबी मान से गुजरता है (C ++ अर्थ में)। लेकिन रूबी में सब कुछ एक वस्तु है, इसलिए रूबी में वास्तव में C ++ अर्थ में कोई पास नहीं है।
रूबी में, "ऑब्जेक्ट संदर्भ द्वारा पास" (पायथन की शब्दावली का उपयोग करने के लिए) का उपयोग किया जाता है:
- फ़ंक्शन के अंदर, ऑब्जेक्ट के किसी भी सदस्य के पास नए असाइन किए गए मान हो सकते हैं और ये परिवर्तन फ़ंक्शन के वापस आने के बाद बने रहेंगे। *
- फ़ंक्शन के अंदर, वैरिएबल को एक पूरी नई ऑब्जेक्ट असाइन करने से वैरिएबल पुरानी ऑब्जेक्ट को संदर्भित करना बंद कर देता है। लेकिन फ़ंक्शन के लौटने के बाद, मूल चर अभी भी पुरानी वस्तु का संदर्भ देगा।
इसलिए रूबी C ++ अर्थ में "पास बाय रेफरेंस" का उपयोग नहीं करता है। यदि ऐसा होता है, तो एक फ़ंक्शन के अंदर एक चर के लिए एक नई वस्तु को असाइन करने से पुराने ऑब्जेक्ट को फ़ंक्शन वापस आने के बाद भूल जाने का कारण होगा।
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
* यही कारण है कि, रूबी में, यदि आप किसी फ़ंक्शन के अंदर किसी ऑब्जेक्ट को संशोधित करना चाहते हैं, लेकिन फ़ंक्शन में वापस आने पर उन परिवर्तनों को भूल जाते हैं, तो आपको कॉपी में अपने अस्थायी परिवर्तन करने से पहले स्पष्ट रूप से ऑब्जेक्ट की एक प्रतिलिपि बनाना होगा।