{"id":2663,"date":"2014-05-15T15:11:48","date_gmt":"2014-05-15T13:11:48","guid":{"rendered":"https:\/\/sgaul.de\/?p=2663"},"modified":"2014-05-16T12:32:08","modified_gmt":"2014-05-16T10:32:08","slug":"klassen-und-klassenhierarchievariablen-in-ruby","status":"publish","type":"post","link":"https:\/\/sgaul.de\/2014\/05\/15\/klassen-und-klassenhierarchievariablen-in-ruby\/","title":{"rendered":"Klassen- und Klassenhierarchievariablen in Ruby"},"content":{"rendered":"

Sucht man nach einem Klassenvariablenkonzept f\u00fcr Ruby trifft man \u00fcber kurz oder lang auf das @@-Konzept. Wer sich darauf einl\u00e4sst kann schnell Probleme bekommen. Der Grund ist relativ einfach: @@-Variablen sind keine Klassenvariablen<\/em>.<\/p>\n

Einfache \u201eKlassenvariablen\u201c<\/h2>\n
class Cat\r\n  \r\n  @@size = :small\r\n  \r\n  def self.size\r\n    @@size\r\n  end\r\n\r\n  def self.size= new_size\r\n    @@size = new_size\r\n  end\r\n\r\n  def size\r\n    @@size\r\n  end\r\n\r\nend<\/pre>\n

<\/p>\n

expect(Cat.size).to be :small\r\nexpect(Cat.new.size).to be :small\r\nCat.size = :medium\r\nexpect(Cat.size).to be :medium\r\nexpect(Cat.new.size).to be :medium\r\n<\/pre>\n

Vererbung<\/h2>\n
class HouseCat < Cat\r\nend\r\n\r\nclass Lion < Cat\r\nend<\/pre>\n
expect(Lion.size).to be :small\r\nLion.size = :big\r\nexpect(Lion.size).to be :big\r\nexpect(HouseCat.size).to be :big<\/pre>\n

Hauskatze und L\u00f6we teilen die selbe Variable, was zu erwarten war. L\u00e4sst sich das trennen?<\/p>\n

@@-Variablen sind keine Klassenvariablen<\/h2>\n
class HouseCat < Cat\r\nend\r\n\r\nclass Lion < Cat\r\n  @@size = :big\r\nend<\/pre>\n
expect(Lion.size).to be :big\r\nexpect(HouseCat.size).to be :big # !!!<\/pre>\n

Nein. Die gesetzte Variable gilt f\u00fcr die gesamte Klassenhierarchie aufw\u00e4rts<\/em>.<\/p>\n

Superklassen haben \u00fcbrigens keinen Zugriff:<\/p>\n

class Cat\r\n  \r\n  def self.size\r\n    @@size\r\n  end\r\n\r\nend\r\n\r\nclass Lion < Cat\r\n  @@size = :big\r\nend<\/pre>\n
expect{ Lion.size }.to raise_error NameError<\/pre>\n

Richtige Klassenvariablen<\/h2>\n

Da in Ruby auch Klassen Objekte sind, sind Instanzvariablen dieser Objekte auch Klassenvariablen. Bemerkenswert ist hier die strenge Sichtbarkeitsbeschr\u00e4nkung: Selbst wenn @small<\/code> und self.size<\/code> in der selben Klassen definiert werden, kann self.size<\/code> nach der Vererbung in die HouseCat<\/code> nicht l\u00e4nger mit @small<\/code> auf die Klassenvariable von Cat<\/code> zurgreifen.<\/p>\n

class Cat\r\n  \r\n  @size = :small\r\n  \r\n  def self.size\r\n    @size\r\n  end\r\n\r\nend\r\n\r\nclass HouseCat < Cat\r\nend\r\n\r\nclass Lion < Cat\r\n  @size = :big\r\nend<\/pre>\n
expect(Lion.size).to be :big\r\nexpect(Cat.size).to be :small\r\nexpect(HouseCat.size).to be_nil\r\n<\/pre>\n

Aber hier k\u00f6nnen ja wieder Klassenhierarchievariablen helfen.<\/p>\n","protected":false},"excerpt":{"rendered":"

Sucht man nach einem Klassenvariablenkonzept f\u00fcr Ruby trifft man \u00fcber kurz oder lang auf das @@-Konzept. Wer sich darauf einl\u00e4sst kann schnell Probleme bekommen. Der Grund ist relativ einfach: @@-Variablen sind keine Klassenvariablen. Einfache \u201eKlassenvariablen\u201c class Cat @@size = :small def self.size @@size end def self.size= new_size @@size = new_size end def size @@size end… Klassen- und Klassenhierarchievariablen in Ruby<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[91],"tags":[481,527,552],"_links":{"self":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/2663"}],"collection":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/comments?post=2663"}],"version-history":[{"count":8,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/2663\/revisions"}],"predecessor-version":[{"id":2682,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/2663\/revisions\/2682"}],"wp:attachment":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/media?parent=2663"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/categories?post=2663"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/tags?post=2663"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}