28 votes

Qu'est-ce que ARGF.class dans Ruby 1.9?

Je suis nouveau sur Ruby 1.9 et je suis assez dérouté par certains de ces newish des classes et des modules.

Une liste de Ruby 1.8.7 des classes et des modules est ici. Tous ces éléments sont parfaitement raisonnable. Je peux étudier dans la cisr 1.8.7, par exemple:

>> Data.class
=> Class
>> Kernel.class
=> Module
>> NameError.class
=> Class

Ils sont de toutes les classes et de modules.

Ensuite, nous allons à la documentation de Ruby 1.9.3 classes et de modules, trouvé ici. Maintenant, nous voyons quelques nouvelles entrées, dont l'une est ARGF. Vraiment?!

En Ruby 1.8.7, ARGF n'est pas une classe ou d'un module:

>> ARGF.class
=> Object

Mais en Ruby 1.9.3, je vois ceci:

>> ARGF.class
=> ARGF.class
>> ARGF.superclass
NoMethodError: undefined method `superclass' for ARGF:ARGF.class
        from (irb):3
        from /usr/local/bin/irb:12:in `<main>'
>> ARGF.class.superclass
=> Object

Donc, ce que cela me dit que

  • La documentation dit que ARGF est une classe, mais il n'est pas vraiment une classe.
  • La classe de l' ARGF objet est - ARGF.class ou en quelque sorte la classe de cet objet est une classe qui se trouve être une propriété de l'objet (?!)

Qu'est-ce que l'explication ici? Est-il une métaclasse ici? Une classe virtuelle? Classe Singleton? Quelque chose d'autre? Pourquoi la documentation de maintenant, placez ARGF comme une classe lorsque la classe est quelque chose d'autre? Ou est-ce la même chose? Qu'est-ce exactement a été modifié à la 1.9? Je soupçonne que la nouvelle façon est censé pour faire plus de sens, mais jusqu'à présent, pour moi, cette situation est très loin de mon "moindre surprise".

26voto

Semyon Perepelitsa Points 7592

ARGF est implémenté en C et vous pouvez faire des choses bizarres dans ce. L' ARGF classe est définie en premier. Elle n'est pas définie pour toute constante en Ruby, mais son nom est "ARGF.class". Ensuite, ARGF constante est définie à une instance de cette classe.

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

Voici un code Ruby qui est en train de faire à peu près la même chose.

argf_class = Class.new
def argf_class.name
  "ARGF.class"
end
argf = argf_class.new
ARGF = argf

Il ne semble pas raisonnable en Ruby, mais en C, il est très bien. Bien, je pense que la classe peut être réglé en ARGFClass comme NilClass, TrueClass, FalseClass, de sorte qu'il n'est pas source de confusion.

Je ne connais pas l'histoire de la changer. Je pense que Ruby gens voulaient obtenir de l' ARGF dans les docs et ce était la façon la plus simple. (RDoc ne peut pas montrer de la documentation pour les objets singleton.)

7voto

sawa Points 62592

Il semble correct qu' ARGF n'est pas une classe ou d'un module.

class ARGF
end
# => TypeError: ARGF is not a class

module ARGF
end
# => TypeError: ARGF is not a module

La documentation des listes d' ARGF dans la classe, mais autre que cela, il ne dit pas qu'il est une classe. Sans doute, il n'était pas prévu que ARGF traitées en tant que classe, et il est faux de la documentation doivent être répertoriées en tant que telles. C'est la documentation de bug.

Il ressemble ARGF si la seule instance d'une certaine classe, à qui il manque un littéral, et la seule façon de se référer à elle est d'appeler ARGF.class.

ARGF.class.class
# => Class

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

Les relations habituelles entre la classe et son instance tient pour ARGF.class et ARGF.

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

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

4voto

Si l'on capture les objets et de les regarder en utilisant simplement une pure Ruby, nous pouvons voir que peu de choses:

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]

Pour une raison quelconque, les développeurs ont explicitement l'ensemble de la classe.nom de la valeur à renvoyer ARGF.class, ce qui est généralement rare, mais est utilisé en interne dans Ruby pour les constantes qui ne doit jamais être directement accessible.

Nous pouvons instancier des objets avec la ARGFClass exactement le même que toute autre classe. Cela signifie que c'est une vraie classe Ruby:

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

Ce n'est pas simplement retourner le singleton lorsque vous appelez #new soit:

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

Les développeurs Ruby ont intentionnellement nommé l' ARGF.class d'une façon telle qu'il ne peut pas être référencé directement par son nom, mais c'est une vraie classe et ARGF est un objet réel.

Il a beaucoup des mêmes méthodes que d'un IO objet, et, en fait, est définie dans l' io.c le fichier source. Il a également la Énumérable module mixte en tant qu'il prend en charge tous les chaque/compression/carte de la fonctionnalité.

edit: La documentation des listes d' ARGF en tant que classe. Cependant, sa en fait une constante de la référence d'une instance du singleton de l'étrangement nommé ARGF.class classe.

Références

0voto

Douglas G. Allen Points 359

ARGF est une classe Array. voir quelques exemples sur https://github.com/DouglasAllen/Ruby_core_ri_doc/tree/master/ARGF Peut-être pas par nom mais vous pourrez le dire en l'utilisant comme n'importe quel tableau sauf que vous pouvez y passer des arguments de ligne de commande. Essayez d'ajouter quelque chose d'autre juste pour voir ce qui se passe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X