Что такое переменные экземпляра и класса в контексте метода класса в Ruby? - PullRequest
5 голосов
/ 08 апреля 2010

Если у меня есть следующий фрагмент кода Ruby:

class Blah
  def self.bleh
    @blih = "Hello"
    @@bloh = "World"
  end
end

Что такое @blih и @@ bloh? @blih - это переменная экземпляра в классе Blah, а @@ bloh - это переменная класса в классе Blah, верно? Означает ли это, что @@ bloh - это переменная в классе Бла, Class?

Ответы [ 4 ]

4 голосов
/ 08 апреля 2010

Люди, кажется, игнорируют, что метод является методом класса.

@ blih будет переменной экземпляра экземпляра класса Class для константы Bleh. Следовательно:

irb(main):001:0> class Bleh
irb(main):002:1>   def self.bleh
irb(main):003:2>     @blih = "Hello"
irb(main):004:2>     @@blah = "World"
irb(main):005:2>   end
irb(main):006:1> end
=> nil
irb(main):007:0> Bleh.instance_variables
=> []
irb(main):008:0> Bleh.bleh
=> "World"
irb(main):009:0> Bleh.instance_variables
=> ["@blih"]
irb(main):010:0> Bleh.instance_variable_get :@blih
=> "Hello"

@@ blah будет доступно как переменная класса Bleh:

irb(main):017:0> Bleh.class_variables
=> ["@@blah"]
irb(main):018:0> Bleh.send :class_variable_get, :@@blah
=> "World"
4 голосов
/ 08 апреля 2010

У этого безумия есть метод ...

class Example
  @foo # class instance variable
  @@bar # class variable

  def fun1
    @baz # instance variable
  end
end

Переменные экземпляра

Переменные экземпляра (@foo и @baz в примере) всегда начинаются с @и они всегда принадлежат независимо от того, какой объект self ссылается на : либо объект класса, либо объект Class, представляющий класс.Ссылка на переменную экземпляра в определении класса или методе класса полностью отличается от ссылки на переменную экземпляра в методе экземпляра.

Наследование Поскольку переменные экземпляра не определены классом, они не связаны с механизмом наследования - они просто создаются, когда им присваивается значение.Переменные экземпляра класса, являющиеся просто переменными экземпляра объекта Class, представляющего класс, таким образом, не наследуются.

Переменные класса

Переменные класса видны и совместно используются методами класса и методами экземпляра класса, а также самим определением класса.Переменные класса могут использоваться в методах экземпляра, методах класса и в самом определении класса вне любого метода. Переменные класса всегда оцениваются со ссылкой на объект класса, созданный с помощью оператора определения класса .

Переменная экземпляра класса против переменной экземпляра

Недостаток переменных экземпляра классачто они не могут быть использованы в методах экземпляра как переменные класса.Другим недостатком является возможность перепутать их с обычными переменными экземпляра.Преимущество переменных экземпляра класса над переменными класса связано с запутанным поведением переменных класса при создании подкласса существующего класса: если класс использует переменные класса, то любой подкласс может изменить поведение класса и всех его потомков, изменив значениепеременной общего класса.Это сильный аргумент в пользу использования переменных экземпляра класса вместо переменных класса.

Многое из этого - из превосходного "языка программирования Ruby" альтернативный текст http://ecx.images -amazon.com / images / I / 517LDwIEYwL._SL75_.jpg

1 голос
/ 08 апреля 2010

Переменная с префиксом двух в знаках является переменной класса, доступной как в экземпляре, так и в методах класса этого класса.

Пример:

class CountEm
  @@children = 0

  def initialize
    @@children += 1
    @myNumber = @@children
  end

  def whoAmI
    "I'm child number #@myNumber (out of #@@children)"
  end

  def CountEm.totalChildren
    @@children
  end
end

c1 = CountEm.new
c2 = CountEm.new
c3 = CountEm.new
c1.whoAmI              # -> "I'm child number 1 (out of 3)"
c3.whoAmI              # -> "I'm child number 3 (out of 3)"
CountEm.totalChildren  # -> 3

Пример взят из ссылки текст

0 голосов
/ 08 апреля 2010

[отредактировано для ясности]

В вашем примере параметр @blih не будет виден вне области действия вашего метода класса, потому что внутри метода класса нет экземпляра, который бы связывал с ним переменную экземпляра.

Говоря о терминологии, я бы сказал, что "@@ bloh - это переменная класса в классе Blah", но не "переменная в классе Blah".Класс «Класс» остается нетронутым.

...