2009-12-30 7 views
0

J'utilise Ruby 1.8.6 pour le code suivant:Ruby Array # n'utilise pas l'implémentation surchargée?

# Create an array and override the #to_s on that object 
thing = [1,2,3] 
def thing.to_s 
    'one' 
end 

print "Using print: " 
print thing 

puts 
puts "Using puts: " 
puts thing 

Sortie:

Using print: one 
Using puts: 
1 
2 
3 

Alors chose est un Tableau et je l'ai chose substituée #to_s. impression semble utiliser ma mise en œuvre dépassée tandis que met ne fonctionne pas. Pourquoi?

J'ai suivi le code source de Kernel # puts et Kernel # print (qui sont des implémentations C) et je vois qu'il s'agit d'implémentations très différentes. Je veux savoir quelle pourrait être la décision de conception (le cas échéant) derrière cela?

D'ailleurs, si je crée chose comme une instance d'une autre classe que j'ai écrit (ou une table de hachage/cordes/autres classes que j'ai essayé), à la fois l'impression et met utiliser la mise en œuvre surchargée de to_s.

Répondre

2

de la langue de programmation Ruby:
alt text http://ecx.images-amazon.com/images/I/41n-JSlBHkL._SL75_.jpg

flux de sortie sont réinscriptible, comme les chaînes et les tableaux sont, et vous pouvez les écrire des valeurs avec l'opérateur <<. puts est l'une des méthodes de sortie les plus courantes. Il convertit chacun de ses arguments en une chaîne et écrit chacun d'eux dans le flux. Si la chaîne ne se termine pas par un caractère de nouvelle ligne, elle en ajoute une. Si l'un des arguments de puts est un tableau, le tableau est développé de manière récursive et chaque élément est imprimé sur sa propre ligne comme s'il était passé directement en argument à puts. La méthode print convertit ses arguments en chaînes et les affiche dans le flux. Si le séparateur de zone global $ a été modifié par rapport à sa valeur par défaut nil, cette valeur est transmise entre chacun des arguments à print. Si le séparateur d'enregistrement de sortie $/ a été modifié par rapport à sa valeur par défaut nil, cette valeur est sortie après l'impression de tous les arguments.

Quant aux décisions de conception, que je ne sais pas.

+2

Dans le cas où quelqu'un l'aurait manqué dans l'explication plutôt verbeuse: 'puts' des tableaux de cas spéciaux de sorte que si vous en passez un comme argument, puts fait' arg.each {| i | met i} '. – Chuck

+0

Oui, cela explique cela. Cependant, avec le POLS de Ruby (principe des moindres surprises) à l'esprit, je m'attendais à ce que puts utilise la méthode #to_s que j'ai écrite. Peut-être, il y a un cas pour la méthode puts d'avoir un autre cas particulier. Si l'objet a un usage défini to_s qui autrement passerait par la routine. En même temps je peux voir que les puts ne sont probablement pas trop utilisés dans le code de production (vous feriez mieux d'utiliser les enregistreurs à moins que vous ne vouliez écrire dans des fichiers) donc cette implémentation est correcte. – arnab

+0

@JRL Les images que vous avez mises sont manquantes. – ismail

3

Oh boy ... Cela a déjà fait l'objet d'un nombre incalculable de discussions interminables sur la liste de diffusion ruby-talk, la liste de diffusion ruby-core et une quantité de blogs.

L'essentiel est que puts cas spéciaux Array s. Pourquoi est-il des cas particuliers, ces cas particuliers pourquoi il ne ceux (par opposition à, disons, tous Enumerable s), pourquoi il cas particuliers ceux (et non, disons, print), personne ne sait vraiment. C'est comme ça.

BTW, puisque vous avez mentionné les POLS: la communauté Ruby a toujours fait très clair que les POLS ne s'applique à Matz. Donc, Ruby est sur le point de ne pas surprendre matz.Si vous ou moi ou quelqu'un d'autre est surpris, cela ne compte pas.

+1

Vous ne pouvez pas ne pas surprendre tout le monde! –