如何避免类和全局变量(How to avoid class and global variables)

Rubocop向“红宝石风格指南”证实了这一点 。 它不鼓励使用除实例变量之外的任何东西。 我发现不使用至少类变量会让人感到困惑。 样式指南中的这个片段对全局变量的使用不以为然,而是推荐模块实例变量

# bad $foo_bar = 1 # good module Foo class << self attr_accessor :bar end end Foo.bar = 1

谨慎使用全局变量是有意义的,但既不使用全局变量也不使用类变量会让我大吃一惊。

模块实例变量类实例变量中 ,哪种内存使用效率更高?

例如:

选项A(类实例变量):

# things that exist only with life module Life # an instance of life with unique actions/attributes class Person attr_accessor :memories def initialize @memories = [] end def memorize(something) @memories << something end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

选项B(模块实例变量):

# things that exist only with life module Life # something all living things possess module Memory class << self attr_accessor :memories end end # an instance of life with unique actions/attributes class Person include Memory def initialize Memory.memories = [] end def memorize(something) Memory.memories << something end def memories Memory.memories end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

Rubocop confirms to The Ruby Style Guide. It discourages use of anything besides instance variables. I find it confusing to not use at the least class variables. This snippet from the Style Guide frowns on usage of global variables and instead recommends module instance variables:

# bad $foo_bar = 1 # good module Foo class << self attr_accessor :bar end end Foo.bar = 1

It makes sense to be wary of using global variables, but using neither global nor class variables blows my mind.

Among module instance variables and class instance variables, which is more efficient usage of memory?

For example:

Option A (Class Instance Variable):

# things that exist only with life module Life # an instance of life with unique actions/attributes class Person attr_accessor :memories def initialize @memories = [] end def memorize(something) @memories << something end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

Option B (Module Instance Variable):

# things that exist only with life module Life # something all living things possess module Memory class << self attr_accessor :memories end end # an instance of life with unique actions/attributes class Person include Memory def initialize Memory.memories = [] end def memorize(something) Memory.memories << something end def memories Memory.memories end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

最满意答案

你误解了术语“类实例变量”。 它表示“ Class对象上的实例变量”,而不是“某个类的实例上的实例变量”。

class Person attr_accessor :memories # instance variable, not shared class << self attr_accessor :memories # class instance variable, shared between # all instances of this class end end

显然,有时你需要使用类实例变量。 避免使用类变量( @@memories ),因为它们在层次结构中的所有类(类及其子代)之间共享,这可能导致令人惊讶的行为。

You misunderstand the term "class instance variable". It means "instance variable on a Class object", not "instance variable on an instance of some class".

class Person attr_accessor :memories # instance variable, not shared class << self attr_accessor :memories # class instance variable, shared between # all instances of this class end end

Obviously, sometimes you do need to use class instance variables. Refrain from using class variables (@@memories) as they are shared between all classes in the hierarchy (the class and its children), which may lead to surprising behaviour.

如何避免类和全局变量(How to avoid class and global variables)

Rubocop向“红宝石风格指南”证实了这一点 。 它不鼓励使用除实例变量之外的任何东西。 我发现不使用至少类变量会让人感到困惑。 样式指南中的这个片段对全局变量的使用不以为然,而是推荐模块实例变量

# bad $foo_bar = 1 # good module Foo class << self attr_accessor :bar end end Foo.bar = 1

谨慎使用全局变量是有意义的,但既不使用全局变量也不使用类变量会让我大吃一惊。

模块实例变量类实例变量中 ,哪种内存使用效率更高?

例如:

选项A(类实例变量):

# things that exist only with life module Life # an instance of life with unique actions/attributes class Person attr_accessor :memories def initialize @memories = [] end def memorize(something) @memories << something end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

选项B(模块实例变量):

# things that exist only with life module Life # something all living things possess module Memory class << self attr_accessor :memories end end # an instance of life with unique actions/attributes class Person include Memory def initialize Memory.memories = [] end def memorize(something) Memory.memories << something end def memories Memory.memories end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

Rubocop confirms to The Ruby Style Guide. It discourages use of anything besides instance variables. I find it confusing to not use at the least class variables. This snippet from the Style Guide frowns on usage of global variables and instead recommends module instance variables:

# bad $foo_bar = 1 # good module Foo class << self attr_accessor :bar end end Foo.bar = 1

It makes sense to be wary of using global variables, but using neither global nor class variables blows my mind.

Among module instance variables and class instance variables, which is more efficient usage of memory?

For example:

Option A (Class Instance Variable):

# things that exist only with life module Life # an instance of life with unique actions/attributes class Person attr_accessor :memories def initialize @memories = [] end def memorize(something) @memories << something end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

Option B (Module Instance Variable):

# things that exist only with life module Life # something all living things possess module Memory class << self attr_accessor :memories end end # an instance of life with unique actions/attributes class Person include Memory def initialize Memory.memories = [] end def memorize(something) Memory.memories << something end def memories Memory.memories end end end bob = Life::Person.new bob.memorize 'birthday' bob.memorize 'wedding' bob.memorize 'anniversary' bob.memories # => ["birthday", "wedding", "anniversary"]

最满意答案

你误解了术语“类实例变量”。 它表示“ Class对象上的实例变量”,而不是“某个类的实例上的实例变量”。

class Person attr_accessor :memories # instance variable, not shared class << self attr_accessor :memories # class instance variable, shared between # all instances of this class end end

显然,有时你需要使用类实例变量。 避免使用类变量( @@memories ),因为它们在层次结构中的所有类(类及其子代)之间共享,这可能导致令人惊讶的行为。

You misunderstand the term "class instance variable". It means "instance variable on a Class object", not "instance variable on an instance of some class".

class Person attr_accessor :memories # instance variable, not shared class << self attr_accessor :memories # class instance variable, shared between # all instances of this class end end

Obviously, sometimes you do need to use class instance variables. Refrain from using class variables (@@memories) as they are shared between all classes in the hierarchy (the class and its children), which may lead to surprising behaviour.