You can create instance variables of a class and define their accessors as singleton methods of that class. But class variables like @@var behave strangely, especially when inherited. Are there any use cases of it?

有帮助吗?

解决方案

I interpret what you mean by strange as the fact that class variables are not different among each class but are shared among the inheritance hierarchy of classes.

As you mention and is also pointed out in Jörg W Mittag's answer to this question, it you wanted a variable to be consistent withing a class but differ outside of the class, then you can use a class instance variable on that class. That means, class variables should behave differently from that if it has any reason to exist. And class variables are indeed shared among classes within the inheritance hierarchy.

class A
  @@foo = 3
end
class B < A
  puts @@foo
end
# => 3

Probably, it may be useful when you want to share something that are common to classes in the hierarchy. For example, suppose you have some feature in a class that would be used in the classes that inherit this class. Suppose that that feature is dependent on a parameter, and you want that parameter change to be consistent among the classes that inherit that feature. Then, class variable will be useful.

For example, suppose you have this method:

class Array
  def join_with_delimiter
    join(@@delimiter)
  end
end
class A < Array; end

By setting @@delimiter once, you can expect consistent behavior across Array and A.

class Array; @@delimiter = "*" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"
A.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"

class A; @@delimiter = "#" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a#b#c"
A.new([:a, :b, :c]).join_with_delimiter # => "a#b#c"

If you do that with a class instance variable, you would not get consistent behavior:

class Array
  def self.delimiter; @delimiter end
  def join_with_delimiter
    join(self.class.delimiter)
  end
end
class A < Array; end

class Array; @delimiter = "*" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"
A.new([:a, :b, :c]).join_with_delimiter # => "abc"

class A; @delimiter = "#" end
Array.new([:a, :b, :c]).join_with_delimiter # => "a*b*c"
A.new([:a, :b, :c]).join_with_delimiter # => "a#b#c"

其他提示

Class variables are used for passing values to different methods inside a class.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top