例項變數

例項變數具有物件範圍,它們可以在物件中的任何位置宣告,但是在類級別宣告的例項變數只能在類物件中可見。當使用 @ 作為字首時,變數將被視為例項變數。例項變數用於設定和獲取物件屬性,如果未定義則返回 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 來例項化聲音:

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

這可用於建立類級變數,這些變數不會被子類覆蓋,因為類也是 Ruby 中的物件。

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"