如何避免 class 和全局变量
How to avoid class and global variables
Rubocop confirms to The Ruby Style Guide。它不鼓励使用实例变量以外的任何东西。我发现至少不使用 class 变量会让人感到困惑。样式指南中的这段代码对全局变量的使用表示不满,而是推荐 模块实例变量 :
# bad
$foo_bar = 1
# good
module Foo
class << self
attr_accessor :bar
end
end
Foo.bar = 1
谨慎使用全局变量是有道理的,但既不使用全局变量也不使用 class 变量让我大吃一惊。
模块实例变量和class实例变量,哪个内存使用效率更高?
例如:
选项 A(Class 实例变量):
# 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"]
您误解了术语 "class instance variable"。意思是"instance variable on a Class
object",不是"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
显然,有时您确实需要使用 class 实例变量。避免使用 class 变量 (@@memories
),因为它们在层次结构中的所有 classes(class 及其子级)之间共享,这可能会导致令人惊讶的行为。
Rubocop confirms to The Ruby Style Guide。它不鼓励使用实例变量以外的任何东西。我发现至少不使用 class 变量会让人感到困惑。样式指南中的这段代码对全局变量的使用表示不满,而是推荐 模块实例变量 :
# bad
$foo_bar = 1
# good
module Foo
class << self
attr_accessor :bar
end
end
Foo.bar = 1
谨慎使用全局变量是有道理的,但既不使用全局变量也不使用 class 变量让我大吃一惊。
模块实例变量和class实例变量,哪个内存使用效率更高?
例如:
选项 A(Class 实例变量):
# 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"]
您误解了术语 "class instance variable"。意思是"instance variable on a Class
object",不是"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
显然,有时您确实需要使用 class 实例变量。避免使用 class 变量 (@@memories
),因为它们在层次结构中的所有 classes(class 及其子级)之间共享,这可能会导致令人惊讶的行为。