我正在学习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进行硬编码,而是使用对父类的引用,例如具有
schema = PARENTCLASS.schema.deep_merge({
代替
schema = parentImporter .schema.deep_merge({
或
super(params,THISCLASS.schema)
代替
super(params, childImporter .schema)。
有没有办法做到这一点?
当前,如果我尝试
super(params,@@ schema)
我明白了
NameError:childImporter中未初始化的类变量@@ schema
谢谢
答案 0 :(得分:4)
我想知道是否有一种方法不对类名称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"}
但是有一种更简单的方法。类inherit既是类方法又是其父类的实例方法。在这两种变体中,您都可以简单地调用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"}
此外,您可能想memoize的值,这样就不会在每次调用方法时都重新创建它们:
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
是所谓的类实例变量,即类对象范围内的实例变量。它们的行为与临时实例中的实例变量完全相同。特别是,@infos
中的ParentImporter
与ChildImporter
中的super(params,THISCLASS.schema)
之间没有联系。
或
super(params,childImporter.schema).
代替
importer = ChildImporter.new importer.class #=> ChildImporter importer.class.infos #=> {:name=>"Child Importer", :type=>"Importer"}
要获取对象的类,可以调用其class
方法:
def initialize(params = {})
super(params, self.class.schema)
end
在实例方法中也是如此:
class
请注意,class.schema
方法必须始终由显式接收者调用。省略接收器并仅写@@
会导致错误。
底部注释:我根本不会使用$.when(
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"),
$.getScript("https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.js"),
$.getScript("1.js"),
$.getScript("2.js"),
$.getScript("3.js"),
$.Deferred(function(deferred) {
$(deferred.resolve);
})
).done(function() {
$('input[name=\'time\']').daterangepicker();
});
类变量。只需调用您的类方法即可。
答案 1 :(得分:0)
这可能会有所帮助-您可以像这样访问类和超类:
class Parent
end
class Child < Parent
def self.print_classes
p itself
p superclass
end
end
Child.print_classes
这将打印
孩子
父母