在Ruby 1.8.7中,the documentation未在类和模块下列出ARGF
,ARGF
不是类或模块:
ARGF.class # => Object
在Ruby 1.9.3中,the documentation在类和模块下有ARGF
,但我看到了:
ARGF.class # => ARGF.class
ARGF.superclass # => NoMethodError: undefined method `superclass' for ARGF:ARGF.class
ARGF.class.superclass # => Object
ARGF
作为一个类,而实际的类是其他的?或者他们是一回事吗?ARGF.class
是元类,虚拟类,单例类还是别的什么?答案 0 :(得分:27)
ARGF
在C中实现,您可以在其中执行奇怪的操作。首先定义ARGF
类。它没有设置为Ruby中的任何常量,但其名称设置为“ARGF.class”。
然后将ARGF
常量设置为该类的实例。
rb_cARGF = rb_class_new(rb_cObject);
rb_set_class_path(rb_cARGF, rb_cObject, "ARGF.class");
/* ... */
argf = rb_class_new_instance(0, 0, rb_cARGF);
rb_define_global_const("ARGF", argf);
这是一个大致相同的Ruby代码。
argf_class = Class.new
def argf_class.name
"ARGF.class"
end
argf = argf_class.new
ARGF = argf
在Ruby中看起来不合理,但在C中它很好。虽然,我认为课程可以设置为ARGFClass
,例如NilClass
,TrueClass
,FalseClass
,这样就不会造成混淆。
我不知道变化的历史。我认为Ruby核心人员想要ARGF
进入文档,这是最简单的方法。 (RDoc无法显示单例对象的文档。)
答案 1 :(得分:7)
ARGF
不是类或模块似乎是正确的。
class ARGF
end
# => TypeError: ARGF is not a class
module ARGF
end
# => TypeError: ARGF is not a module
文档列出了类下的ARGF
,但除此之外,它并没有说它是一个类。也许,ARGF
并不打算将其作为一个类处理,并且文档列出的是错误的。这是文档的错误。
如果某个类的唯一实例(缺少文字),并且引用它的唯一方法是调用ARGF
,则看起来像ARGF.class
。
ARGF.class.class
# => Class
ARGF.class.ancestors
# => [ARGF.class, Enumerable, Object, Kernel, BasicObject]
类及其实例之间的通常关系适用于ARGF.class
和ARGF
。
ARGF.is_a?(ARGF.class)
# => true
ARGF.kind_of?(ARGF.class)
# => true
答案 2 :(得分:4)
如果我们捕获对象并使用纯Ruby来查看它们,我们可以看到一些东西:
1.9.3 (Object#main):0 > ARGFClass = ARGF.class
=> ARGF.class
1.9.3 (Object#main):0 > ARGFClass.name
=> "ARGF.class"
1.9.3 (Object#main):0 > ARGFClass.class
=> Class
1.9.3 (Object#main):0 > ARGFClass.superclass
=> Object
1.9.3 (Object#main):0 > ARGFClass.ancestors
=> [ARGF.class,
Enumerable,
Object,
JSON::Ext::Generator::GeneratorMethods::Object,
PP::ObjectMixin,
Kernel,
BasicObject]
由于某种原因,开发人员已经明确地将class.name值设置为返回ARGF.class
,这通常不常见,但在Ruby内部用于永远不能直接访问的常量。
我们可以使用ARGFClass实例化对象与任何其他类完全相同。这意味着它是一个真正的Ruby类:
1.9.3 (Object#main):0 > argfinstance = ARGFClass.new
=> ARGF
1.9.3 (Object#main):0 > argfinstance.inspect
=> "ARGF"
当你打电话给#new时,它不只是返回单身人士:
1.9.3 (Object#main):0 > argfinstance == ARGF
=> false
1.9.3 (Object#main):0 > argfinstance.object_id
=> 70346556507420
1.9.3 (Object#main):0 > ARGF.object_id
=> 70346552343460
Ruby开发人员故意将ARGF.class
命名为不能通过名称直接引用它,但它是一个真正的类,而ARGF
是一个真实的对象。
它有许多与IO对象相同的方法,实际上是在io.c
源文件中定义的。它还混合了Enumerable模块,因此它支持所有的每个/ inject / map功能。
编辑:文档将ARGF
列为一个类。但是,它实际上是一个常量引用奇怪命名的ARGF.class
类的单例实例。
答案 3 :(得分:0)
ARGF是一个Array类。 在https://github.com/DouglasAllen/Ruby_core_ri_doc/tree/master/ARGF看一些例子 也许不是名字,但你可以像任何数组一样使用它,除了你可以将命令行参数传递给它。尝试添加其他内容只是为了看看会发生什么。