这主要是一个“学术”课程,但实际情况如下:
根据此Ruby本征类图(略作编辑):
file = new File(imagePath);
FileUploadService service =
getRetrofit().create(FileUploadService.class);
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(
MediaType.parse(getContentResolver().getType(imageUri)),
file
);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("file", file.getName(), requestFile);
Call<ResponseBody> call = service.upload(body);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.v("Upload", "success");
String resource = BASE_URL + "images/" + file.getName();
sendMessage(resource, recieverBareid);
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.v("Upload", "failed");
}
});
是BasicObject.singleton_class.singleton_class.superclass
。
但是,在Ruby解释器(Ruby v2.5.1)上运行它,结果发现Class
是BasicObject.singleton_class.singleton_class.superclass
而不是#<Class:Class>
。因此,该图是在说谎还是我缺少什么?
该图来自我在Freenode的Ruby IRC聊天的一个用户。但是,它已被许多其他用户多次引用,并被视为Ruby对象模型圣经。
答案 0 :(得分:2)
Ruby解释器的行为非常合理,因为:
Child
类扩展Parent
时,Ruby对其进行设置,以便单例类#<Class:Child>
也扩展了#<Class:Parent>
;和BasicObject.singleton_class
是Class
的子类,因此BasicObject.singleton_class.singleton_class
将是#<Class:Class>
的子类验证相等性:
BasicObject.singleton_class.singleton_class.superclass.equal?(Class.singleton_class)
#=> true
这引出了下一个问题–为什么#<Class:BaseObject>
首先扩展Class
?按照上述规则,由于BaseObject
没有超类-即BaseObject.superclass
是nil
-逻辑上应该是其单例类也不具有超类。
答案是,#<Class:BaseObject>
扩展Class
可以确保单例类在继承层次结构中的一致性。以这个Ruby对象为例:
obj = "a string"
这是一个公认的概念,不是将obj
仅仅作为String
的实例,而是可以将其视为其自己的singleton类的(唯一)实例, String
的子类。那就是:
obj.class.equal?(obj.singleton_class.superclass)
#=> true
同样合理的是,对类实例也应同样适用。但这并不矛盾,因为它与上述规则冲突,其中Child
类的单例类的超类是其Parent
类的单例类。
class Foo; end
Foo.class
#=> Class
Foo.singleton_class.superclass
#=> #<Class:Object> <-- not equal to Class!
# because:
Foo.superclass
#=> Object
但是可以通过将Class
放在单例类继承层次结构的顶部来解决此矛盾:
Foo.singleton_class.superclass
#=> #<Class:Object>
Foo.singleton_class.superclass.superclass
#=> #<Class:BasicObject>
Foo.singleton_class.superclass.superclass.superclass
#=> Class
这样,即使Foo.singleton_class.superclass
不等于Foo.class
,通过沿继承链走,它最终也确实到达了那里。