7
votes

Ruby Integer (), Array (), et al - Que sont-ils? D'où viennent-ils?

J'ai rencontré des conversions de la matrice de formulaire (valeur), la chaîne (valeur) et l'entier (valeur) à l'occasion. Il me semble que ce ne sont que du sucre syntaxique pour un appel à la valeur correspondante.Oa_a, la valeur.to_s ou la valeur.Tourent les méthodes.

Donc, je me demande: p>

  • Où / comment sont-ils définis? Je ne les trouve pas dans l'objet, le module, la classe, etc. li>
  • y a-t-il des scénarios courants pour lesquels il est préférable d'utiliser ces méthodes plutôt que la méthode correspondante / sous-jacente to_x? LI>
  • pourrait-il être utilisé dans la coercition de type générique? C'est-à-dire que puis-je faire quelque chose dans le sens de p>

    [Integer, String, Array].each {|klass| klass.do_generic_coercion(foo) }
    


2 commentaires

Je ne fais pas beaucoup de rubis, mais je soupçonne que c'est la syntaxe de casting.


Il n'y a pas de "casting" de rubis. En fait, tout idée de casting n'a de sens que dans une langue faiblement dactylographiée comme c, mais le rubis est fortement typé. Ce ne sont que des méthodes telles que toute autre méthode.


4 Réponses :


8
votes

bonne question! Voyons si nous pouvons le comprendre.

Ross-Harveys-MacBook-Pro:puppet_sd ross$ irb
irb(main):001:0> class X; X; end.new.to_a
(irb):1: warning: default `to_a' will be obsolete


4 commentaires

+1 Merci d'avoir montré comment vous l'avez trouvé. Cela sera très utile dans les projets futurs!


Votre réponse est proche, mais je trouve que cela est incorrect (.to_a n'est pas obsolète!) Et incomplet. Vérifiez ma réponse ci-dessous.


Ah, désolé, je ne me suis pas réalisé que vous parliez de l'objet par défaut # à_a, qui est à juste titre allé dans 1.9. Votre réponse est donc proche (R) et toujours incomplète ;-) Array (X) appellera TO_ARY si l'on est défini. Je pense que la notion de conversion implicite (to_ary) et de conversion explicite (TO_A) est à la fois subtile et importante.


WOW - Quelle réponse terriblement informative. Merci beaucoup! (Marc-André a également répondu à la troisième partie, c'est pourquoi j'ai "accepté" le sien; les deux ensemble font une lecture très intéressante et instructive.) Merci encore.



0
votes

Ils sont définis dans le module de noyau Ruby, comme:

 Array(1..5)   # => [1, 2, 3, 4, 5] 


0 commentaires

12
votes

C'est une question bonne et difficile. Réponse aux trois parties.

première partie

Pour trouver la définition, il est important de réaliser que le nom de la méthode est "Array", etc., qui Peut être assez contre-intuitif, car les méthodes sont généralement minuscules ... xxx

Cela vous indique que celles-ci sont définies dans le noyau et donc disponibles partout sans nécessiter de préfixe explicite.

deuxième partie

tableau () , string () , ... sont des méthodes de conversion. Appelant obj.to_a retournera un tableau, mais augmentera un nométhoderror si obj ne répond pas répond_to? : to_a . Donc, le cas typique lorsque vous préférez utiliser tableau () , string () , au lieu de to_a ou to_s Est-ce que vous n'êtes pas positif, un objet répond à une méthode de conversion donnée.

string (obj) retournera nil si obj pas < code> répondre_to? : to_s . String (Obj) vérifiera également que le résultat de TO_S est en réalité une chaîne; Cela devrait être, mais peut-être qu'un programmeur trop créatif a décidé de renvoyer quelque chose d'autre?

La plupart des autres méthodes de conversion agissent de la même manière, mais Array (OBJ) est différent. Il retournera [obj] si obj ne pas répond_to? : to_a . Il appellera effectivement to_ary (qui est l'opération de conversion implicite, tandis que to_a est explicite).

Il existe un autre moyen important de convertir des objets en 1.9 (et à venir 1.8.8): array.ecteur_convert (obj) . Ce retour nil si l'OBJ n'est pas répond_to? : to_ary . Il n'appellera pas le to_a . Bien qu'ils soient plus longs à taper, vous préférez les utiliser lors de l'écriture de code très général pouvant accepter différents types d'objets et que vous souhaitez éviter de convertir un hachage en une matrice par erreur, par exemple (puisque hachage a un to_a méthode mais pas to_ary ). Lorsque votre méthode nécessite un objet de type tableau et que vous êtes prêt à faire une conversion explicite, alors obj.to_a est bien. L'utilisation typique de (obj) serait dans une méthode qui accepte un seul obj pour agir ou une liste d'objets (bien que cela soit généralement écrit comme < Code> [* obj] ).

dernière partie

Espérons que les réponses aux deux premières parties vous donnent votre réponse finale. ..

Vous pouvez utiliser: xxx

ou xxx


1 commentaires

Merci d'avoir répondu. Entre la réponse de cette et DigitalRoss, j'ai appris ce dont j'avais besoin et bien plus encore.



0
votes

De ce que je comprends, la version simple est comme ceci:

  • objet.to_a essaie de convertir "objet" à un tableau à l'aide d'une fonction de membre de classe.
  • array (objet) essaie de créer un nouveau tableau à l'aide d'un "objet".

    Je peux ré-définir ce que .to_a signifie pour une classe donnée (ce n'est qu'un autre membre après tout). Le tableau (...) est défini dans le noyau afin qu'il se comporte de même pour n'importe quelle classe. J'utilise généralement des conversions de type du style tableau (...) lorsque je ne sais pas à l'avance sur quel type d'objet sera transmis. Il est préférable de manipuler des cas où un objet ne le fait pas Savoir se convertir en une matrice ou ne peut pas être converti en une matrice. Si l'objet à convertir est le résultat d'une expression longue ou complexe, à l'aide du style (...) est souvent plus clair. Je sauvegarde le formulaire .to_a pour les instances lorsque je connais la classe de l'objet et exactement à quoi s'attendre à partir de la sortie de .to_a (surtout des cas lorsque j'ai écrit ou modifié le .to_a fonction de membre moi-même).


0 commentaires