Ruby Language
चर स्कोप और दृश्यता
खोज…
वाक्य - विन्यास
- $ global_variable
- @@ class_variable
- @उदाहरण चर
- local_variable
टिप्पणियों
वर्ग चर वर्ग पदानुक्रम में साझा किए जाते हैं। इससे आश्चर्यजनक व्यवहार हो सकता है।
class A
@@variable = :x
def self.variable
@@variable
end
end
class B < A
@@variable = :y
end
A.variable # :y
कक्षाएं ऑब्जेक्ट हैं, इसलिए उदाहरण चर का उपयोग राज्य प्रदान करने के लिए किया जा सकता है जो प्रत्येक वर्ग के लिए विशिष्ट है।
class A
@variable = :x
def self.variable
@variable
end
end
class B < A
@variable = :y
end
A.variable # :x
स्थानीय चर
स्थानीय चर (अन्य चर वर्गों के विपरीत) में कोई उपसर्ग नहीं होता है
local_variable = "local"
p local_variable
# => local
इसका दायरा इस बात पर निर्भर है कि इसे कहां घोषित किया गया है, इसे "घोषणा कंटेनरों" के दायरे से बाहर नहीं किया जा सकता है। उदाहरण के लिए, यदि किसी विधि में स्थानीय चर घोषित किया जाता है, तो इसका उपयोग केवल उस विधि के अंदर किया जा सकता है।
def some_method
method_scope_var = "hi there"
p method_scope_var
end
some_method
# hi there
# => hi there
method_scope_var
# NameError: undefined local variable or method `method_scope_var'
बेशक, स्थानीय चर तरीकों तक सीमित नहीं हैं, अंगूठे के एक नियम के रूप में, आप कह सकते हैं कि, जैसे ही आप एक do ... end
अंदर एक चर घोषित do ... end
ब्लॉक या घुंघराले ब्रेसिज़ में लिपटे {}
यह स्थानीय और scoped होगा जिस ब्लॉक में यह घोषित किया गया है।
2.times do |n|
local_var = n + 1
p local_var
end
# 1
# 2
# => 2
local_var
# NameError: undefined local variable or method `local_var'
हालाँकि, if
या case
ब्लॉक में स्थानीय चर का उपयोग मूल-दायरे में किया जा सकता है:
if true
usable = "yay"
end
p usable
# yay
# => "yay"
जबकि स्थानीय चरों को घोषणा के अपने ब्लॉक के बाहर उपयोग नहीं किया जा सकता है, इसे नीचे ब्लॉकों में पारित किया जाएगा:
my_variable = "foo"
my_variable.split("").each_with_index do |char, i|
puts "The character in string '#{my_variable}' at index #{i} is #{char}"
end
# The character in string 'foo' at index 0 is f
# The character in string 'foo' at index 1 is o
# The character in string 'foo' at index 2 is o
# => ["f", "o", "o"]
लेकिन विधि / वर्ग / मॉड्यूल परिभाषाओं के लिए नहीं
my_variable = "foo"
def some_method
puts "you can't use the local variable in here, see? #{my_variable}"
end
some_method
# NameError: undefined local variable or method `my_variable'
ब्लॉक तर्क के लिए उपयोग किए जाने वाले चर (बेशक) ब्लॉक के लिए स्थानीय हैं, लेकिन पहले से परिभाषित चर को ओवरशेड करेंगे, उन्हें अधिलेखित किए बिना।
overshadowed = "sunlight"
["darkness"].each do |overshadowed|
p overshadowed
end
# darkness
# => ["darkness"]
p overshadowed
# "sunlight"
# => "sunlight"
वर्ग चर
कक्षा चर में एक वर्ग व्यापक गुंजाइश होती है, उन्हें कक्षा में कहीं भी घोषित किया जा सकता है। @@
साथ उपसर्ग करने पर एक चर को एक वर्ग चर माना जाएगा
class Dinosaur
@@classification = "Like a Reptile, but like a bird"
def self.classification
@@classification
end
def classification
@@classification
end
end
dino = Dinosaur.new
dino.classification
# => "Like a Reptile, but like a bird"
Dinosaur.classification
# => "Like a Reptile, but like a bird"
वर्ग चर संबंधित कक्षाओं के बीच साझा किए जाते हैं और इन्हें बाल वर्ग से अधिलेखित किया जा सकता है
class TRex < Dinosaur
@@classification = "Big teeth bird!"
end
TRex.classification
# => "Big teeth bird!"
Dinosaur.classification
# => "Big teeth bird!"
यह व्यवहार ज्यादातर समय अवांछित होता है और वर्ग-स्तरीय उदाहरण चर का उपयोग करके इसे दरकिनार किया जा सकता है।
एक मॉड्यूल के अंदर परिभाषित वर्ग चर वर्ग वर्ग चर सहित उनके अधिलेखित नहीं होंगे:
module SomethingStrange
@@classification = "Something Strange"
end
class DuckDinosaur < Dinosaur
include SomethingStrange
end
DuckDinosaur.class_variables
# => [:@@classification]
SomethingStrange.class_variables
# => [:@@classification]
DuckDinosaur.classification
# => "Big teeth bird!"
सार्वत्रिक चर
वैश्विक चर का वैश्विक दायरा होता है और इसलिए, इसका उपयोग हर जगह किया जा सकता है। उनका दायरा इस बात पर निर्भर नहीं है कि वे कहां परिभाषित हैं। एक वैरिएबल को वैश्विक माना जाएगा, जब $
चिन्ह के साथ उपसर्ग किया जाएगा।
$i_am_global = "omg"
class Dinosaur
def instance_method
p "global vars can be used everywhere. See? #{$i_am_global}, #{$another_global_var}"
end
def self.class_method
$another_global_var = "srsly?"
p "global vars can be used everywhere. See? #{$i_am_global}"
end
end
Dinosaur.class_method
# "global vars can be used everywhere. See? omg"
# => "global vars can be used everywhere. See? omg"
dinosaur = Dinosaur.new
dinosaur.instance_method
# "global vars can be used everywhere. See? omg, srsly?"
# => "global vars can be used everywhere. See? omg, srsly?"
चूंकि एक वैश्विक चर को हर जगह परिभाषित किया जा सकता है और हर जगह दिखाई देगा, एक "अपरिभाषित" वैश्विक चर को कॉल करने से त्रुटि पैदा होने के बजाय शून्य वापस आ जाएगी।
p $undefined_var
# nil
# => nil
यद्यपि वैश्विक चर इसके उपयोग को आसान बनाते हैं लेकिन स्थिरांक के पक्ष में इसका उपयोग दृढ़ता से हतोत्साहित किया जाता है।
आवृत्ति के चर
इंस्टेंस वेरिएबल्स में ऑब्जेक्ट वाइड स्कोप होता है, उन्हें ऑब्जेक्ट में कहीं भी घोषित किया जा सकता है, हालांकि क्लास लेवल पर घोषित किया गया इंस्टेंस वैरिएबल केवल क्लास ऑब्जेक्ट में दिखाई देगा। एक चर को एक उदाहरण चर माना जाएगा जब @
साथ उपसर्ग किया जाता है। इंस्टेंस वेरिएबल्स का उपयोग ऑब्जेक्ट्स की विशेषताओं को सेट करने और प्राप्त करने के लिए किया जाता है और परिभाषित नहीं होने पर शून्य वापस आ जाएगा।
class Dinosaur
@base_sound = "rawrr"
def initialize(sound = nil)
@sound = sound || self.class.base_sound
end
def speak
@sound
end
def try_to_speak
@base_sound
end
def count_and_store_sound_length
@sound.chars.each_with_index do |char, i|
@sound_length = i + 1
p "#{char}: #{sound_length}"
end
end
def sound_length
@sound_length
end
def self.base_sound
@base_sound
end
end
dino_1 = Dinosaur.new
dino_2 = Dinosaur.new "grrr"
Dinosaur.base_sound
# => "rawrr"
dino_2.speak
# => "grrr"
वर्ग स्तर पर घोषित उदाहरण चर वस्तु स्तर पर पहुँचा नहीं जा सकता है:
dino_1.try_to_speak
# => nil
हालाँकि, हमने ध्वनि को @base_sound
करने के लिए उदाहरण चर @base_sound
का उपयोग किया जब कोई ध्वनि नई विधि से पारित नहीं हुई:
dino_1.speak
# => "rawwr"
ऑब्जेक्ट में कहीं भी इंस्टेंस चर घोषित किए जा सकते हैं:
dino_1.count_and_store_sound_length
# "r: 1"
# "a: 2"
# "w: 3"
# "r: 4"
# "r: 5"
# => ["r", "a", "w", "r", "r"]
dino_1.sound_length
# => 5
एक ही वर्ग के उदाहरणों के बीच इंस्टेंस चर साझा नहीं किए जाते हैं
dino_2.sound_length
# => nil
इसका उपयोग कक्षा स्तर के चर बनाने के लिए किया जा सकता है, जो कि बाल-वर्ग द्वारा अधिलेखित नहीं किया जाएगा, क्योंकि कक्षाएं रूबी में भी ऑब्जेक्ट हैं।
class DuckDuckDinosaur < Dinosaur
@base_sound = "quack quack"
end
duck_dino = DuckDuckDinosaur.new
duck_dino.speak
# => "quack quack"
DuckDuckDinosaur.base_sound
# => "quack quack"
Dinosaur.base_sound
# => "rawrr"