首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rational::兼容和复杂::兼容是怎么回事?

Rational::兼容和复杂::兼容是怎么回事?
EN

Stack Overflow用户
提问于 2016-02-20 20:52:44
回答 1查看 30关注 0票数 0

有人能解释一下这个学科中提到的(子)类的存在吗?

  • 缺少文件 http://ruby-doc.org/core/Rational/compatible.html http://ruby-doc.org/core/Complex/compatible.html
  • 标识符中断类/常量命名规则。它以小写开头,但应该以大写开头。
  • 以标准方式无法获得,尽管它们的存在已登记如下:

_

代码语言:javascript
复制
Rational::constants false
# [:compatible]

Rational::compatible
# NoMethodError: undefined method 'compatible' for Rational:Class

Rational::const_get 'compatible'
# NameError: wrong constant name compatible

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-21 00:19:03

我相信这个类的存在是为了向后兼容Ruby的旧版本。换句话说,它使Marshal.load能够在一个版本的Ruby中加载复杂和Rational对象,这些对象是在一个旧版本的Ruby中封送的。

您可以看到第二行(rational.c)中定义了Rational::兼容类的位置:

代码语言:javascript
复制
rb_define_private_method(rb_cRational, "marshal_dump", nurat_marshal_dump, 0);
compat = rb_define_class_under(rb_cRational, "compatible", rb_cObject);
rb_define_private_method(compat, "marshal_load", nurat_marshal_load, 1);
rb_marshal_define_compat(rb_cRational, compat, nurat_dumper, nurat_loader);

我的C语言很糟糕,但在我看来,这四行代码分别做了以下工作:

  1. Rational#marshal_dump私有方法定义为指向C函数nurat_marshal_load的指针。
  2. 定义compatible类下的Rational类(rb_cRational)。我认为第三个论点,rb_cObject是超类。
  3. Rational#marshal_load定义为C函数nurat_marshal_dump
  4. 这是一个有趣的问题:它使用四个参数调用rb_marshal_define_compat:Rational类(rb_cRational);Rational::兼容类(compat);以及nurat_dumpernurat_loader

第1 629项开始,在同一个文件中,您可以看到定义nurat_dumpernurat_loader (以及nurat_marshal_dumpnurat_marshal_load)的位置。使用git blame的魔力,我们可以确切地看到何时定义了nurat_dumpernurat_loader:2012年7月25日,在Subversion提交#36538中。以下是提交消息:

Compos.c,理性主义.c:兼容的编组装载机

  • complex.crational.c:兼容的编组加载器,兼容1.8。红宝石-核心:45775

现在我们有进展了!Bug #6625是这样的一个:

复杂理性的断裂元帅相容 1.8或更早版本的复杂和Rational不能由主干加载。

它接着描述了一个测试用例,并包括在上面提交中看到的修补程序。

那么,也许你在想,rb_marshal_define_compat是什么呢?你可以看到它,marshal.c。就像我说的,我的C语言很糟糕,但我认为它所做的是把它的论点--newclass(即Rational)、oldclass (Rational::兼容)、dumperloader-into a 结构 --并插入到compat_allocator_tbl中。稍后,当您尝试Marshal.dumpMarshal.load对象时,它将查看该表中是否存在兼容性类,并在必要时使用它的"dumper“或”加载程序“。

至于为什么Rational::兼容性不是用大写字母命名的,也不能通过普通方式访问的,我只能猜测这是通过设计实现的,因此只能通过Ruby在内部进行访问。

但是,您可以使用ObjectSpace获得对类的引用,尽管您不能使用它做很多事情:

代码语言:javascript
复制
compatible = ObjectSpace.each_object(Class).find do |o|
  o.name == "Rational::compatible"
end

p compatible
# => Rational::compatible

p compatible.instance_methods(false)
# => []

p compatible.private_instance_methods(false)
# => [:marshal_load]
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35528864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档