Ниль имеет отличный ответ для этого, я просто хочу что-то добавить к нему.
счетные Собаки :)
Вам нужна переменная класса, чтобы сделать это ..
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, который не содержит переменных экземпляра. Это ничем не отличается от ссылки на новый экземпляр «Собака».
Аналогично, вы можете сказать 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]
Это не имеет значения, если вы передаете такую ссылку на вызов метода или к другому классу или просто оценить его сам по себе - Руби знает, что это ссылка на объект, и выглядит внутри объекта, и это цепочка наследования на как разрешать вещи.
Разрешающих Названия методов
Это было только частичная правда :) При интерпретации x.legs
, Ruby проверяет, есть ли метод в классе-цепочке наследования объекта, который реагирует на это имя «ногу» , Это не волшебный доступ к переменной экземпляра с тем же именем!
Мы можем определить метод «ноги», выполнив «attr_reader: legs» или «attr_accessor: 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
нет никакой переменной экземпляра экземпляра магии, которую автоматически получает доступ. Они всегда доступны с помощью метода, который позже можно переопределить.
Надеюсь, это имеет смысл для вас
А, хорошо, спасибо вам большое. Поэтому в моем примере, когда создается экземпляр собаки, он получает свои значения при инициализации и всех своих методах. Однако методы не оцениваются до тех пор, пока приложение/программа не попросит его с чем-то вроде @ dog.popularity ... это значение, которое метод популярности возвращает, затем связанный с этим экземпляром собаки? например, если я снова его вызову, он снова обработает метод/связанные методы или он просто узнает значение с того момента, когда он был ранее вызван? – BC00
Он обрабатывается каждый раз, он не помнит. Кстати, вы обычно не хотите или не нуждаетесь в «attr_accessor: foo» и «def foo» - только один или другой. Если все, что вы хотите, это чтение и запись переменных экземпляра, то attr_accessor прост. Что-то более сложное, вы хотите определить метод. –
Огромная благодарность, это приносит много вещей для меня – BC00