30

Ruby 1.8.7 では、ドキュメントARGFはクラスとモジュールの下にリストされておらずARGF、クラスでもモジュールでもありません。

ARGF.class # => Object

Ruby 1.9.3 では、ドキュメントARGFクラスとモジュールの下にありますが、次のように表示されます。

ARGF.class # => ARGF.class
ARGF.superclass # => NoMethodError: undefined method `superclass' for ARGF:ARGF.class
ARGF.class.superclass # => Object
  • ARGF実際のクラスは別のものなのに、Ruby 1.9 のドキュメントがクラスとして配置されるのはなぜですか? それとも同じものですか?
  • ARGF.classメタクラス、仮想クラス、シングルトン クラス、またはその他のクラスですか?
4

4 に答える 4

27

ARGFCで実装されており、奇妙なことができます。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 では問題ありません。ただし、混乱しないように、クラスをARGFClasslike NilClassTrueClass、に設定できると思います。FalseClass

変更履歴はわかりません。ARGFRuby コアの人々はドキュメントにアクセスしたかったと思いますが、これが最も簡単な方法でした。(RDoc はシングルトン オブジェクトのドキュメントを表示できません。)

于 2012-09-05T05:35:11.553 に答える
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
于 2012-09-05T05:10:53.607 に答える
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モジュールが混在しているため、すべてのeach / inject/map機能をサポートします。

編集:ドキュメントはARGFクラスとしてリストされています。ただし、実際には、奇妙な名前ARGF.classのクラスのシングルトンインスタンスを参照する定数です。

参考文献

于 2012-09-06T22:46:19.203 に答える
0

ARGFは配列クラスです。https://github.com/DouglasAllen/Ruby_core_ri_doc/tree/master/ARGFでいくつかの例を参照してください 。名前ではないかもしれませんが、コマンドライン引数を渡すことができることを除いて、他の配列と同じように使用することでわかります。何が起こるかを見るためだけに何か他のものを追加してみてください。

于 2012-09-09T03:53:36.780 に答える