实例变量

实例变量具有对象范围,它们可以在对象中的任何位置声明,但是在类级别声明的实例变量只能在类对象中可见。当使用 @ 作为前缀时,变量将被视为实例变量。实例变量用于设置和获取对象属性,如果未定义则返回 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"