Ruby : 如何避免对类名进行硬编码?



我正在学习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中的@infosChildImporter中的之间没有联系。


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

这将打印

孩子

父母

相关内容

  • 没有找到相关文章

最新更新