ruby - रुबी इंस्टेंस चर कब सेट हो जाते हैं?




syntax instance-variables (4)

"रूबी प्रोग्रामिंग भाषा" पुस्तक में एक स्पष्ट विवरण है, इसे पढ़ें बहुत उपयोगी होगा। मैं इसे यहां पेस्ट करता हूं (अध्याय 7.1.16 से):

एक क्लास परिभाषा के अंदर उपयोग किया जाने वाला एक इंस्टेंस वैरिएबल लेकिन इंस्टेंस विधि परिभाषा के बाहर एक क्लास इंस्टेंस वैरिएबल है

class Point
    # Initialize our class instance variables in the class definition itself
    @n = 0              # How many points have been created
    @totalX = 0         # The sum of all X coordinates
    @totalY = 0         # The sum of all Y coordinates

    def initialize(x,y) # Initialize method 
      @x,@y = x, y      # Sets initial values for instance variables
    end

    def self.new(x,y)   # Class method to create new Point objects
      # Use the class instance variables in this class method to collect data
      @n += 1           # Keep track of how many Points have been created
      @totalX += x      # Add these coordinates to the totals
      @totalY += y

      super             # Invoke the real definition of new to create a Point
                    # More about super later in the chapter
    end

    # A class method to report the data we collected
    def self.report
        # Here we use the class instance variables in a class method
        puts "Number of points created: #@n"
        puts "Average X coordinate: #{@totalX.to_f/@n}"
        puts "Average Y coordinate: #{@totalY.to_f/@n}"
    end
end

......

चूंकि क्लास इंस्टेंस वेरिएबल्स क्लास ऑब्जेक्ट्स के इंस्टेंस वेरिएबल्स हैं, इसलिए हम उनके लिए एक्सेसर विधियां बनाने के लिए attr, attr_reader, और attr_accessor का उपयोग कर सकते हैं।

class << self
  attr_accessor :n, :totalX, :totalY
end

इन एक्सेसर्स को परिभाषित करने के साथ, हम अपने कच्चे डेटा को Point.n, Point.totalX, और Point.totalY के रूप में देख सकते हैं।

class Hello
@hello = "hello"
    def display
        puts @hello
    end
end

h = Hello.new
h.display

मैंने उपरोक्त वर्ग बनाया है। यह कुछ भी प्रिंट नहीं करता है। मैंने सोचा कि आवृत्ति चर @hello कक्षा घोषणा के दौरान सेट किया गया था। लेकिन जब मैं डिस्प्ले विधि को कॉल करता हूं तो आउटपुट 'शून्य' होता है। ऐसा करने का सही तरीका क्या है?


आपके कोड में पहले @hello को क्लास इंस्टेंस वैरिएबल कहा जाता है।

यह क्लास ऑब्जेक्ट का एक इंस्टेंस वैरिएबल है जो निरंतर Hello पॉइंट्स को इंगित करता है। (और जो क्लास Class का एक उदाहरण है।)

तकनीकी रूप से, जब आप class दायरे में होते हैं, तो आपका self आपके वर्तमान वर्ग की वस्तु पर सेट होता है, और @variables आपके वर्तमान self से संबंधित होते हैं। लड़का मैं इन चीजों को समझाने में चूसता हूं।

प्रोग्रामैटिक प्रोग्रामर से $ 5-प्रत्येक स्क्रीनकास्ट के इस संग्रह को देखकर आप यह सब और अधिक स्पष्ट कर सकते हैं।

(या आप यहां स्पष्टीकरण मांग सकते हैं और मैं अपडेट करने का प्रयास करूंगा।)


मैं क्लास वेरिएबल्स को देखने की भी सिफारिश करता हूं जो "@@" के साथ प्रीफ़िक्स्ड हैं - यहां कुछ नमूना कोड है जो आपको दिखाता है कि कक्षा और इंस्टेंस वर्र्स कैसे भिन्न हैं:

class Vars
  @@classvar="foo"
  def test
    @instancevar="bar"
  end
  def Vars.show
    puts "classvar: #{@@classvar}"
    puts "instancevar: #{@instancevar}"
  end
  def instance_show
    puts "classvar: #{@@classvar}"
    puts "instancevar: #{@instancevar}"

  end
end

# only shows classvar since we don't have an instance created
Vars::show
# create a class instance
vars = Vars.new
# instancevar still doesn't show b/c it hasn't been initialized
vars.instance_show
# initialize instancevar
vars.test
# now instancevar shows up as we expect
vars.instance_show

मैं भूल गया था कि रुबी में एक "क्लास इंस्टेंस वेरिएबल" अवधारणा थी। किसी भी मामले में, ओपी की समस्या परेशान लग रही थी, और वास्तव में किसी भी उत्तर में संबोधित नहीं किया गया था, कोच के जवाब में संकेत के अलावा: यह दायरे की समस्या है। (संपादन पर जोड़ा गया: असल में, श्रीस का जवाब अंत में इस बिंदु को संबोधित करता है , लेकिन मैं इस जवाब को वैसे भी खड़ा करूंगा, क्योंकि मुझे लगता है कि उदाहरण कोड समस्या को समझने के लिए उपयोगी हो सकता है।)

रूबी क्लास में, @ शुरू होने वाला एक वैरिएबल नाम दो चरों में से एक को संदर्भित कर सकता है: या तो एक आवृत्ति परिवर्तनीय या क्लास इंस्टेंस वैरिएबल में , उस वर्ग के आधार पर जहां इसे संदर्भित किया गया है। यह एक काफी सूक्ष्म गोचा है।

एक उदाहरण बिंदु को स्पष्ट करेगा। यहां थोड़ी रूबी टेस्ट क्लास है (सभी कोड आईआरबी में परीक्षण किए गए हैं):

class T

  @@class_variable = "BBQ"
  @class_instance_variable_1 = "WTF"
  @class_instance_variable_2 = "LOL"

  def self.class_method
    puts "@@class_variable           == #{@@class_variable           || 'nil'}"
    puts "@class_instance_variable_1 == #{@class_instance_variable_1 || 'nil'}"
    puts "@class_instance_variable_2 == #{@class_instance_variable_2 || 'nil'}"
    puts "@instance_variable         == #{@instance_variable         || 'nil'}"
  end

  def initialize
    @instance_variable = "omg"
    # The following line does not assign a value to the class instance variable,
    # but actually declares an instance variable withthe same name!
    @class_instance_variable_1 = "wtf"
    puts "@@class_variable           == #{@@class_variable           || 'nil'}"
    # The following two lines do not refer to the class instance variables,
    # but to the instance variables with the same names.
    puts "@class_instance_variable_1 == #{@class_instance_variable_1 || 'nil'}"
    puts "@class_instance_variable_2 == #{@class_instance_variable_2 || 'nil'}"
    puts "@instance_variable         == #{@instance_variable         || 'nil'}"
  end

  def instance_method
    puts "@@class_variable           == #{@@class_variable           || 'nil'}"
    # The following two lines do not refer to the class instance variables,
    # but to the instance variables with the same names.
    puts "@class_instance_variable_1 == #{@class_instance_variable_1 || 'nil'}"
    puts "@class_instance_variable_2 == #{@class_instance_variable_2 || 'nil'}"
    puts "@instance_variable         == #{@instance_variable         || 'nil'}"
  end

end

मैंने वैरिएबल को नाम दिया जो मैंने सोचा था कि वे थे, हालांकि यह हमेशा मामला नहीं बनता है:

irb> T.class_method
@@class_variable           == BBQ
@class_instance_variable_1 == WTF    # the value of the class instance variable
@class_instance_variable_2 == LOL    # the value of the class instance variable
@instance_variable         == nil    # does not exist in the class scope
=> nil

irb> t = T.new
@@class_variable           == BBQ
@class_instance_variable_1 == wtf    # the value of the instance variable
@class_instance_variable_2 == nil    # the value of the instance variable
@instance_variable         == omg
=> #<T:0x000000015059f0 @instance_variable="omg", @class_instance_variable_1="wtf">

irb> t.instance_method
@@class_variable           == BBQ
@class_instance_variable_1 == wtf    # the value of the instance variable
@class_instance_variable_2 == nil    # the value of the instance variable
@instance_variable         == omg
=> nil

irb> T.class_method
@@class_variable           == BBQ
@class_instance_variable_1 == WTF    # the value of the class instance variable
@class_instance_variable_2 == LOL    # the value of the class instance variable
@instance_variable         == nil    # does not exist in the class scope
=> nil

@@class_variable और @instance_variable हमेशा व्यवहार करते हैं जैसा कि आप उम्मीद करेंगे: पूर्व को वर्ग स्तर पर परिभाषित किया गया है, और चाहे किसी क्लास विधि में या किसी उदाहरण विधि में संदर्भित किया गया हो, तो इसे शीर्ष पर असाइन किया गया मान रखता है। उत्तरार्द्ध केवल कक्षा T किसी ऑब्जेक्ट में एक मान प्राप्त करता है, इसलिए कक्षा विधि में, यह एक अज्ञात चर को संदर्भित करता है जिसका मूल्य nil

क्लास विधि कल्पनात्मक रूप से class_method ने @@class_variable के मूल्यों को और आउटपुट के रूप में दो @class_instance_variable s को @class_instance_variable किया है, जैसा कि कक्षा के शीर्ष पर प्रारंभ किया गया है। हालांकि, उदाहरण विधियों में initialize और instance_method , उसी नाम के विभिन्न चरों का उपयोग किया जाता है, यानी, आवृत्ति चर, वर्ग आवृत्ति चर नहीं

आप देख सकते हैं कि initialize विधि में असाइनमेंट क्लास इंस्टेंस वैरिएबल @class_instance_variable_1 को प्रभावित नहीं करता है, क्योंकि @class_instance_variable_1 का बाद का कॉल इसके पुराने मान, "WTF" आउटपुट करता है। इसके बजाए, initialize विधि को एक नया इंस्टेंस वैरिएबल घोषित किया गया, जिसे एक नाम भी दिया गया है (misleadingly) @class_instance_variable_1 । इसे सौंपा गया मान, "wtf" , initialize तरीकों और initialize द्वारा आउटपुट है।

उदाहरण कोड में परिवर्तनीय @class_instance_variable_2 मूल समस्या में वेरिएबल @hello बराबर है: इसे घोषित किया गया है और क्लास इंस्टेंस वैरिएबल के रूप में प्रारंभ किया गया है, लेकिन जब एक इंस्टेंस विधि उस नाम के चर को संदर्भित करती है, तो यह वास्तव में एक आवृत्ति चर को देखती है वही नाम - जिसे कभी घोषित नहीं किया गया था, इसलिए इसका मूल्य शून्य है।





instance-variables