Ruby 获取对模块中定义的类变量的访问权限
因此,虽然我完全反对以这种方式扩展现有类,但有时(黑客攻击Ruby 获取对模块中定义的类变量的访问权限,ruby,oop,rspec,Ruby,Oop,Rspec,因此,虽然我完全反对以这种方式扩展现有类,但有时(黑客攻击rspec)有必要执行以下操作: module MyModule module ClassMethods def define_something(name) @@names ||= [] @@names << name end end def self.included(base) base.extend ClassMethods end def all_n
rspec
)有必要执行以下操作:
module MyModule
module ClassMethods
def define_something(name)
@@names ||= []
@@names << name
end
end
def self.included(base)
base.extend ClassMethods
end
def all_names
@@names
end
end
class Example
include MyModule
define_something "one"
define_something "two"
end
Example.new.all_names
我理解这一点,因为在编写MyModule::ClassMethods
时,我们正在处理实例而不是类(而不是self.
),所以我尝试:
module MyModule
module ClassMethods
def define_something(name)
@names ||= []
@names << name
end
end
def self.included(base)
base.extend ClassMethods
end
def all_names
@@names
end
end
class Example
include MyModule
define_something "one"
define_something "two"
end
Example.new.all_names
模块MyModule
模块类方法
定义某物(名称)
@姓名| |=[]
@名称从设计角度来看,通常最好避免使用实例变量引用跨越类/实例行。这通常更清楚:
module MyModule
module ClassMethods
def define_something(name)
self.defined_somethings << name
end
def defined_somethings
@_my_module_names ||= []
end
end
def self.included(base)
base.extend ClassMethods
end
def all_names
self.class.defined_somethings
end
end
class Example
include MyModule
define_something "one"
define_something "two"
end
Example.new.all_names.inspect
#=> ["one","two"]
模块MyModule
模块类方法
定义某物(名称)
自我定义的东西[“一”、“二”]
在这里,我注意创建了一个具有详细名称的类级实例变量。调用它@name
可能会使它与包含此模块的类定义的变量发生冲突。请记住,在设计mixin代码时,您是一位客人,需要格外礼貌
类类型实例变量,如@@name
,有时很麻烦,因为它们最终可能跨越继承链,具体取决于它们的使用方式。定义方法意味着您可以在链中的任何点重写它,这是共享变量不可能做到的
换句话说,将实例的类视为一个单独的对象,并进行明确、定义良好的方法调用以保持这种分离。从设计角度来看,通常最好避免使用实例变量引用跨越类/实例行。这通常更清楚:
module MyModule
module ClassMethods
def define_something(name)
self.defined_somethings << name
end
def defined_somethings
@_my_module_names ||= []
end
end
def self.included(base)
base.extend ClassMethods
end
def all_names
self.class.defined_somethings
end
end
class Example
include MyModule
define_something "one"
define_something "two"
end
Example.new.all_names.inspect
#=> ["one","two"]
模块MyModule
模块类方法
定义某物(名称)
自我定义的东西[“一”、“二”]
在这里,我注意创建了一个具有详细名称的类级实例变量。调用它@name
可能会使它与包含此模块的类定义的变量发生冲突。请记住,在设计mixin代码时,您是一位客人,需要格外礼貌
类类型实例变量,如@@name
,有时很麻烦,因为它们最终可能跨越继承链,具体取决于它们的使用方式。定义方法意味着您可以在链中的任何点重写它,这是共享变量不可能做到的
换句话说,将实例的类视为一个单独的对象,并进行明确的、定义良好的方法调用以保持这种分离
module MyModule
module ClassMethods
def define_something(name)
@names ||= []
@names << name
end
end
def self.included(base)
base.extend ClassMethods
end
def all_names
self.class.instance_variable_get(:@names)
end
end
class Example
include MyModule
define_something "one"
define_something "two"
end
Example.new.all_names
模块MyModule
模块类方法
定义某物(名称)
@姓名| |=[]
@名称尝试以下方法
module MyModule
module ClassMethods
def define_something(name)
@names ||= []
@names << name
end
end
def self.included(base)
base.extend ClassMethods
end
def all_names
self.class.instance_variable_get(:@names)
end
end
class Example
include MyModule
define_something "one"
define_something "two"
end
Example.new.all_names
模块MyModule
模块类方法
定义某物(名称)
@姓名| |=[]
@名称@
和@
完全不同。无论您是在类上下文还是实例上下文中,都不能使用@
访问@
变量,反之亦然。@
和@
是完全不同的。无论是在类上下文还是实例上下文中,都不能使用@
访问@
变量,反之亦然。