如何在 Ruby 中最好地抽象 class 变量
How to best abstract class variables in Ruby
我有一个class比如
# this has been simplified for the example
class MyClass
@@private_attributes = []
def self.private_attributes(*args)
@@private_attributes = args
end
def private_attributes
@private_attributes ||= @@private_attributes
end
end
效果很好。我将此 @@private_attributes
设置为 class 级别,然后以多种方式在实例级别使用。
我想在其他地方抽象这个逻辑来简化我的 class,类似的东西
class MyClass
include PrivateAttributes
end
当我创建模块 PrivateAttributes
时,无论我如何塑造它,@@private_attributes
在 MyClass
级别都无法理解。
我尝试了很多东西,但这是最新的代码尝试
module PrivateAttributes
include ProcessAttributes
def self.included(base)
base.extend(ClassMethods)
base.include(InstanceMethods)
end
module ClassMethods
@@private_attributes = []
def private_attributes(*args)
@@private_attributes = args
end
end
module InstanceMethods
def private_attributes
@private_attributes ||= process_attributes_from(@@private_attributes)
end
def private_attributes?
instance_options[:scope] == :private
end
end
end
它因这个错误而崩溃
NameError:
uninitialized class variable @@private_attributes in PrivateAttributes::InstanceMethods
Did you mean? private_constant
简而言之,@@private_attributes
并没有在整个代码中传递,而是停留在模块级别。
从我原来的 class 中抽象出这个逻辑的最佳方式是什么?
工作解决方案
一个简单的解决方法是在 class 级别上使用 mattr_accessor
或任何类似的东西来传达我们的数据。在这种情况下,我更愿意写下我自己的方法:
module PrivateAttributes
include ProcessAttributes
def self.included(base)
base.extend(ClassMethods)
base.include(InstanceMethods)
end
module ClassMethods
@@private_attributes_memory = []
def private_attributes(*args)
@@private_attributes_memory = args
end
def private_attributes_memory
@@private_attributes_memory
end
end
module InstanceMethods
def private_attributes
@private_attributes ||= process_attributes_from private_attributes_memory
end
# you can add diverse methods here
# which will be used in MyClass once included
private
def private_attributes_memory
self.class.private_attributes_memory
end
end
end
我有一个class比如
# this has been simplified for the example
class MyClass
@@private_attributes = []
def self.private_attributes(*args)
@@private_attributes = args
end
def private_attributes
@private_attributes ||= @@private_attributes
end
end
效果很好。我将此 @@private_attributes
设置为 class 级别,然后以多种方式在实例级别使用。
我想在其他地方抽象这个逻辑来简化我的 class,类似的东西
class MyClass
include PrivateAttributes
end
当我创建模块 PrivateAttributes
时,无论我如何塑造它,@@private_attributes
在 MyClass
级别都无法理解。
我尝试了很多东西,但这是最新的代码尝试
module PrivateAttributes
include ProcessAttributes
def self.included(base)
base.extend(ClassMethods)
base.include(InstanceMethods)
end
module ClassMethods
@@private_attributes = []
def private_attributes(*args)
@@private_attributes = args
end
end
module InstanceMethods
def private_attributes
@private_attributes ||= process_attributes_from(@@private_attributes)
end
def private_attributes?
instance_options[:scope] == :private
end
end
end
它因这个错误而崩溃
NameError:
uninitialized class variable @@private_attributes in PrivateAttributes::InstanceMethods
Did you mean? private_constant
简而言之,@@private_attributes
并没有在整个代码中传递,而是停留在模块级别。
从我原来的 class 中抽象出这个逻辑的最佳方式是什么?
工作解决方案
一个简单的解决方法是在 class 级别上使用 mattr_accessor
或任何类似的东西来传达我们的数据。在这种情况下,我更愿意写下我自己的方法:
module PrivateAttributes
include ProcessAttributes
def self.included(base)
base.extend(ClassMethods)
base.include(InstanceMethods)
end
module ClassMethods
@@private_attributes_memory = []
def private_attributes(*args)
@@private_attributes_memory = args
end
def private_attributes_memory
@@private_attributes_memory
end
end
module InstanceMethods
def private_attributes
@private_attributes ||= process_attributes_from private_attributes_memory
end
# you can add diverse methods here
# which will be used in MyClass once included
private
def private_attributes_memory
self.class.private_attributes_memory
end
end
end