ruby :如何避免对 类 名称进行硬编码?
ruby : how can I avoid hardcoding the classes names?
我正在学习 Ruby 以及 class 变量和实例变量之间的区别。
我正在编写一段代码,其中有(很多)classes 继承了其他 classes。
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
我有两个 class 变量:infos(进口商信息)和 schema(json 模式) .
我需要它们能够在实例之外获取它们(这就是为什么它们是 class 变量),并成为它们父值的扩展(这就是为什么我 deep_merge 他们)和
我的示例确实有效,但我想知道是否有一种方法可以不对 classes 名称 childImporter 和 parentImporter 进行硬编码,而是使用对父 class 的引用,例如具有
schema = PARENTCLASS.schema.deep_merge({
而不是
schema = parentImporter.schema.deep_merge({
或
super(params,THISCLASS.schema)
而不是
super(params,childImporter.schema).
有办法实现吗?
目前,如果我尝试
super(params,@@schema)
我明白了
NameError: uninitialized class variable @@schema in childImporter
谢谢
这可能会有所帮助 - 您可以像这样访问 class 和 superclass:
class Parent
end
class Child < Parent
def self.print_classes
p itself
p superclass
end
end
Child.print_classes
这将打印
Child
Parent
I wonder if there is a way not to hardcode the classes names childImporter and parentImporter and rather use a reference to the parent class, for example having
schema = PARENTCLASS.schema.deep_merge({
instead of
schema = parentImporter.schema.deep_merge({
您正在寻找的方法是 superclass
– 它 returns 接收者的 parent class。在 class 主体或 class 方法中,您可以在没有显式接收者的情况下调用它:
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"}
但还有更简单的方法。 类 inherit class 方法和 parent class 中的实例方法。在这两种变体中,您只需调用 super
即可调用 parent 的实现:
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"}
此外,您可能想要 memoize 值,这样它们就不会在每次调用方法时都 re-created:
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
是so-calledclass实例变量,即class[=范围内的实例变量67=](s)。它们的行为与偶然实例中的实例变量完全一样。特别是,ParentImporter
中的 @infos
与 ChildImporter
中的 @infos
之间没有任何联系。
or
super(params,THISCLASS.schema)
instead of
super(params,childImporter.schema).
要获得 object 的 class,您可以调用它的 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 变量。只需调用您的 class 方法即可。
我正在学习 Ruby 以及 class 变量和实例变量之间的区别。
我正在编写一段代码,其中有(很多)classes 继承了其他 classes。
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
我有两个 class 变量:infos(进口商信息)和 schema(json 模式) .
我需要它们能够在实例之外获取它们(这就是为什么它们是 class 变量),并成为它们父值的扩展(这就是为什么我 deep_merge 他们)和
我的示例确实有效,但我想知道是否有一种方法可以不对 classes 名称 childImporter 和 parentImporter 进行硬编码,而是使用对父 class 的引用,例如具有
schema = PARENTCLASS.schema.deep_merge({
而不是
schema = parentImporter.schema.deep_merge({
或
super(params,THISCLASS.schema)
而不是
super(params,childImporter.schema).
有办法实现吗?
目前,如果我尝试
super(params,@@schema)
我明白了
NameError: uninitialized class variable @@schema in childImporter
谢谢
这可能会有所帮助 - 您可以像这样访问 class 和 superclass:
class Parent
end
class Child < Parent
def self.print_classes
p itself
p superclass
end
end
Child.print_classes
这将打印
Child
Parent
I wonder if there is a way not to hardcode the classes names childImporter and parentImporter and rather use a reference to the parent class, for example having
schema = PARENTCLASS.schema.deep_merge({
instead of
schema = parentImporter.schema.deep_merge({
您正在寻找的方法是 superclass
– 它 returns 接收者的 parent class。在 class 主体或 class 方法中,您可以在没有显式接收者的情况下调用它:
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"}
但还有更简单的方法。 类 inherit class 方法和 parent class 中的实例方法。在这两种变体中,您只需调用 super
即可调用 parent 的实现:
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"}
此外,您可能想要 memoize 值,这样它们就不会在每次调用方法时都 re-created:
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
是so-calledclass实例变量,即class[=范围内的实例变量67=](s)。它们的行为与偶然实例中的实例变量完全一样。特别是,ParentImporter
中的 @infos
与 ChildImporter
中的 @infos
之间没有任何联系。
or
super(params,THISCLASS.schema)
instead of
super(params,childImporter.schema).
要获得 object 的 class,您可以调用它的 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 变量。只需调用您的 class 方法即可。