尼尔对此有一个很好的答案,我只是想添加一些东西。
数狗:)
你需要一个类变量来做到这一点..
class Dog
@@count = 0 # this is a class variable; all objects created by this class share it
def initialize
@@count += 1 # when we create a new Dog, we increment the count
end
def total
@@count
end
end
还有另一种方法可以使用“类对象的实例变量”来做到这一点,但这是一个有点高级的话题。
访问实例变量
在 Ruby 中,变量实际上只是对对象/实例的引用。
> x = 1
=> 1
> x.class
=> Fixnum
> 1.instance_variables
=> []
x 是对对象 '1' 的引用,它是类 Fixnum 的一个实例。'1' 对象是 Fixnum 的一个实例,它不包含任何实例变量。它与对新“Dog”实例的引用没有任何不同。
类似地,您可以说x = Dog.new
,那么 x 是对 Dog 类实例的引用。
class Dog
attr_accessor :legs # this defines the 'legs' and 'legs=' methods!
end
x = Dog.new
x.instance_variables
=> [] # if you would assign legs=4 during "initialize", then it would show up here
x.legs = 4 # this is really a method call(!) to the 'legs' method
x.instance_variables # get created when they are first assigned a value
=> [:legs]
将这样的引用传递给方法调用,或传递给另一个类,或者只是自己评估它都没有关系 - Ruby 知道它是一个对象引用,并查看对象内部以及它的继承链如何解决问题。
解析方法名称
这只是部分事实:) 解释时x.legs
,Ruby 检查对象的类继承链中是否有一个方法,该方法响应该名称“腿”。它不会神奇地访问具有相同名称的实例变量!
我们可以通过执行“attr_reader :legs”或“attr_accessor :legs”来定义方法“legs”,或者自己定义方法。
class Dog
def legs
4 # most dogs have 4 legs, we don't need a variable for that
end
end
x.legs # this is a method call! it is not directly accessing a :legs instance variable!
=> 4
x.instance_variables
=> [] # there is no instance variable with name ":legs"
如果我们尝试将它实现为方法和实例变量,就会发生这种情况::)
class Dog
attr_accessor :legs # this creates "def legs" and "def legs=" methods behind the scenes
def legs # here we explicitly override the "def legs" method from the line above.
4
end
end
x = Dog.new
x.legs # that's the method call we implemented explicitly
=> 4
x.legs = 3 # we can still assign something to the instance_variable via legs=
=> 3
x.legs # the last definition of a method overrides previous definitions
# e.g. it overrides the automatically generated "legs" method
=> 4
attr_accessor :legs
只是执行此操作的简写符号:
class Dog
def legs
@legs
end
def legs=(value)
@legs = value
end
end
没有神奇的方法可以自动访问实例变量。它们总是通过一种方法访问,以后可以覆盖该方法。
我希望这对你有意义