What is ARGF.class in Ruby 1.9? What is ARGF.class in Ruby 1.9? ruby ruby

What is ARGF.class in Ruby 1.9?


ARGF is implemented in C and you can do weird things in it. The ARGF class is defined there first. It is not set to any constant in Ruby, but its name is set to "ARGF.class".Then ARGF constant is set to an instance of that class.

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);

Here is a Ruby code that is doing roughly the same thing.

argf_class = Class.newdef argf_class.name  "ARGF.class"endargf = argf_class.newARGF = argf

It does not look reasonable in Ruby, but in C it is fine. Although, I think the class could be set to ARGFClass like NilClass, TrueClass, FalseClass, so that it is not confusing.

I don't know the history of the change. I think Ruby core folks wanted to get ARGF into the docs and this was the simplest way. (RDoc can't show documentation for singleton objects.)


It seems correct that ARGF is not a class or a module.

class ARGFend# => TypeError: ARGF is not a classmodule ARGFend# => TypeError: ARGF is not a module

The documentation lists ARGF under class, but other than that, it does not say it is a class. Probably, it was not intended that ARGF handled as a class, and it is wrong of the documentation to have listed as such. It is the documentation's bug.

It looks like ARGF if the only instance of a certain class, which lacks a literal, and the only way to refer to it is to call ARGF.class.

ARGF.class.class# => ClassARGF.class.ancestors# => [ARGF.class, Enumerable, Object, Kernel, BasicObject]

The usual relation between class and its instance holds for ARGF.class and ARGF.

ARGF.is_a?(ARGF.class)# => trueARGF.kind_of?(ARGF.class)# => true


If we capture the objects and look at them using just pure Ruby we can see a few things:

1.9.3 (Object#main):0 > ARGFClass = ARGF.class                                                                                                                                      => ARGF.class1.9.3 (Object#main):0 > ARGFClass.name                                                                                                                                              => "ARGF.class"1.9.3 (Object#main):0 > ARGFClass.class                                                                                                                                             => Class1.9.3 (Object#main):0 > ARGFClass.superclass                                                                                                                                        => Object1.9.3 (Object#main):0 > ARGFClass.ancestors                                                                                                                                         => [ARGF.class,    Enumerable,    Object,    JSON::Ext::Generator::GeneratorMethods::Object,    PP::ObjectMixin,    Kernel,    BasicObject]

For some reason, the developers have explicitly set the class.name value to return ARGF.class, which is generally uncommon but is used internally in Ruby for constants that should never be accessed directly.

We can instantiate objects with the ARGFClass exactly the same as any other class. That means it is a real Ruby class:

1.9.3 (Object#main):0 > argfinstance = ARGFClass.new                                                                                                                                => ARGF1.9.3 (Object#main):0 > argfinstance.inspect                                                                                                                                        => "ARGF"

It's not just returning the singleton when you call #new either:

1.9.3 (Object#main):0 > argfinstance == ARGF                                                                                                                                        => false1.9.3 (Object#main):0 > argfinstance.object_id                                                                                                                                      => 703465565074201.9.3 (Object#main):0 > ARGF.object_id                                                                                                                                              => 70346552343460

The Ruby developers have intentionally named the ARGF.class in such a way that it can't be referenced directly by name, but it is a real class and ARGF is a real object.

It has a lot of the same methods as an IO object, and in fact is defined in the io.c source file. It also has the Enumerable module mixed in so it supports all the each/inject/map functionality.

edit: The documentation lists ARGF as a class. However, its actually a constant referencing a singleton instance of the oddly named ARGF.class class.

References