我正在学习Ruby以及类变量和实例变量之间的区别。
我正在处理一段代码,其中我有(很多(继承其他类的类。
class childImporter < parentImporter
def self.infos
parentImporter.infos.merge({
:name=> 'My Importer',
})
end
def self.schema
schema = parentImporter.schema.deep_merge({
'selectors' => {
'track' => {
'artist'=> {'path'=>{'default'=>'//creator'}},
'title'=> {'path'=>{'default'=>['//name'}},
}
}
})
@@schema = schema
end
def initialize(params = {})
super(params,childImporter.schema)
end
end
我有两个类变量:信息(导入器信息(和架构(json 模式(。
我需要它们能够将它们置于实例之外(这就是为什么它们是类变量(,并成为其父值的扩展(这就是我deep_merge它们的原因(,并且
我的例子实际上有效,但我想知道是否有办法不对类名称 childImporter 和 parentImporter 进行硬编码,而是使用对父类的引用,例如
架构 = PARENTCLASS.schema.deep_merge({
而不是
schema =parentImporter.schema.deep_merge({
或
super(params,thisclass.schema(
而不是
super(params,childImporter.schema(.
有没有办法做到这一点?
目前,如果我尝试
超级(参数,@@schema(
我得到
名称错误:子导入程序中未初始化的类变量@@schema
谢谢
我想知道是否有办法不对类名称 childImporter 和 parentImporter 进行硬编码,而是使用对父类的引用,例如
schema = PARENTCLASS.schema.deep_merge({
而不是
schema = parentImporter.schema.deep_merge({
您要查找的方法superclass
– 它返回接收方的父类。在类主体或类方法中,可以在没有显式接收器的情况下调用它:
class ParentImporter
def self.infos
{ name: 'Parent Importer', type: 'Importer' }
end
end
class ChildImporter < ParentImporter
def self.infos
superclass.infos.merge(name: 'Child Importer')
end
end
ParentImporter.infos #=> {:name=>"Parent Importer", :type=>"Importer"}
ChildImporter.infos #=> {:name=>"Child Importer", :type=>"Importer"}
但还有一种更简单的方法。类从其父类继承类方法和实例方法。在这两种变体中,您都可以简单地调用super
来调用父级的实现:
class ChildImporter < ParentImporter
def self.infos
super.merge(name: 'Child Importer')
end
end
ParentImporter.infos #=> {:name=>"Parent Importer", :type=>"Importer"}
ChildImporter.infos #=> {:name=>"Child Importer", :type=>"Importer"}
此外,您可能希望记住这些值,以便每次调用方法时都不会重新创建它们:
class ParentImporter
def self.infos
@infos ||= { name: 'Parent Importer', type: 'Importer' }
end
end
class ChildImporter < ParentImporter
def self.infos
@infos ||= super.merge(name: 'Child Importer')
end
end
这些@infos
是所谓的类实例变量,即类对象范围内的实例变量。它们的行为与临时实例中的实例变量完全相同。特别是,ParentImporter
中的@infos
与ChildImporter
中的之间没有联系。
或
super(params,THISCLASS.schema)
而不是
super(params,childImporter.schema).
要获取对象的类,可以调用其class
方法:
importer = ChildImporter.new
importer.class #=> ChildImporter
importer.class.infos #=> {:name=>"Child Importer", :type=>"Importer"}
这在实例方法中同样有效:
def initialize(params = {})
super(params, self.class.schema)
end
请注意,必须始终使用显式接收器调用class
方法。省略接收器并仅写入class.schema
会导致错误。
底部说明:我根本不会使用类变量@@
。只需调用您的类方法。
这可能会有所帮助 - 您可以像这样访问类和超类:
class Parent
end
class Child < Parent
def self.print_classes
p itself
p superclass
end
end
Child.print_classes
这将打印
孩子
父母