Ruby: The Bad Parts [fermé]


20

J'ai récemment lu le livre de Crockford "Javascript: The Good Parts" et l'un des principes sous-jacents était que les langages de programmation peuvent avoir de mauvais ensembles de fonctionnalités que les programmeurs devraient éviter.

Je suis un Rubyist et bien que j'aime la langue, il est toujours utile d'avoir du recul. Alors, quelle est selon vous la pire caractéristique (par exemple les méthodes, les classes, les pratiques) de Ruby? Mon intention ici n'est pas de commencer une discussion sur les mérites de la langue elle-même ou sa vitesse et ainsi de suite. Je préfère plutôt une discussion sur les fonctionnalités que vous considérez dangereuses / gênantes / douloureuses à utiliser, en fonction des expériences passées.


1
Je n'ai jamais été fan de devoir utiliser le mot "end", et puis le mélange de cela avec "{" et "}" devient encore plus ennuyeux. Cela me fait apprécier la syntaxe de style Python ou directement les {&}. Bien que l'on puisse discuter d'avant en arrière sur cela, et finalement cela a beaucoup à voir avec les préférences personnelles. J'ai entendu quelqu'un dire que Ruby prend les parties les plus laides de Python et Perl et les assemble. J'apprécie cependant apprendre Ruby.

En fait, j'aime bien cette question et j'attends avec impatience des réponses, mais j'ai néanmoins voté pour la fermer. Je ne pense pas que ce soit un bon choix pour Stack Overflow (car il est potentiellement trop subjectif / argumentatif, ouvert, etc.).
stakx

Je pense qu'il vaut la peine d'en discuter car cela pourrait mettre en lumière des pratiques dangereuses à éviter. Je vois votre point cependant et ai édité la question pour être plus étroite.

9
Je ne vois pas en quoi cette question est suffisamment distincte, par exemple Quelles sont les choses que vous aimeriez améliorer dans le langage Ruby? , Quels sont les Ruby Gotchas dont un débutant devrait être averti? , Quels sont les problèmes réels avec Ruby? ou toute autre question de gazillion sur les points douloureux de Ruby. De plus, même si cette question évolue pour se différencier des autres, elle appartiendrait à Programmers.SE , pas à StackOverflow.
Jörg W Mittag

2
Je dois faire vérifier mes yeux - je pensais que le titre de cette question était "Ruby: The Brad Pitts".
oosterwal

Réponses:


8

Vous devriez regarder Python vs Ruby: A Battle to The Death de Gary Bernhardt. Il fait la citation:

Ce que je trouve moche dans Ruby, c'est ce qui rend possible un logiciel Ruby incroyable comme RSpec, et que Python n'aurait jamais pu (compte tenu de l'implémentation actuelle).

Bien qu'il parle beaucoup de Python en particulier, il touche à beaucoup de choses qui sont juste étranges dans Ruby. L'un des grands sujets primordiaux est le patching de singe .

Les objets Ruby (contrairement aux objets de certains autres langages orientés objet) peuvent être modifiés individuellement. Vous pouvez toujours ajouter des méthodes par objet. Dans Ruby, le comportement ou les capacités d'un objet peuvent différer de ceux fournis par sa classe.

Bien que cela offre beaucoup de flexibilité et alimente certains des joyaux les plus populaires et compliqués de Ruby, cela peut vous mordre dans le cul si vous essayez de déboguer un problème sans vous rendre compte qu'une bibliothèque quelque part a modifié une méthode principale.


Javascript vous permet également de traiter les objets de cette façon.
0112

8

Certaines personnes ne pensent au rubis qu'en termes de rubis sur rails et c'est un peu ennuyeux parce que la langue se débrouille assez bien.


7

Je pense que la pire caractéristique est celle open classesqui vous permet de changer globalement le comportement de toutes les instances actuelles et futures de la classe modifiée.

La partie problématique de cette fonctionnalité est que ces changements (globaux) se produisent pendant l'exécution lorsque l'interpréteur Ruby rencontre la définition, ce qui peut être longtemps après que vous ayez déjà instancié quelques objets qui changent maintenant tout à coup leur comportement.

Dans une grande base de code, cela peut entraîner des bogues très, très difficiles à trouver - d'autant plus que cela est aggravé par l'histoire de débogage faible de Ruby (par exemple par rapport au CLR ou à la JVM) et l'utilisation d'autres fonctionnalités (par exemple eval) dans ce contexte peut rendre il est assez difficile de trouver l'emplacement où ce changement global s'est produit. c'est-à-dire si vous avez déjà atteint le point où vous soupçonnez que la «bonne» classe cause le problème! D'après mon expérience, vous commencez généralement par une chasse aux oies sauvages, car les problèmes commencent à faire surface sur un objet en utilisant le vrai coupable.

Donc, la meilleure chose serait de cesser d'utiliser des classes ouvertes ( #extendet de mettre les changements dans un Moduleest à mon humble avis beaucoup plus sûr, plus facile à comprendre et à tester) ou si cela ne peut être évité pour:

  • étendre uniquement les classes avec un nouveau comportement (c'est-à-dire ne pas remplacer le comportement existant)
  • avoir une place définie dans l'arborescence du code source, où toutes les extensions utilisant des classes ouvertes doivent être placées
  • ne pas utiliser #evalet amis pour créer des classes ouvertes
  • mettre toutes les utilisations des classes ouvertes sur un grand tableau visible, où tous les développeurs peuvent les voir - et préciser que toutes les modifications apportées sont des `` décisions architecturales '' affectant l'ensemble de la base de code (ce qu'elles font) et non le lieu de hacks rapides utiles pour votre tâche actuelle

5

La plus grande raison pour laquelle je n'utilise pas de rubis: c'est plus lent que la mélasse en janvier au pôle Nord pendant une période glaciaire. L'analyse comparative des langages est une science inexacte, mais Ruby apparaît considérablement plus lent que même JavaScript et Python.


c'était aussi mon expérience.
Chuck Stephanski

2
quelle application avez-vous développée pour laquelle le rubis était trop lent? Je veux dire, je vous crois quand vous dites que c'est lent, mais comment cela vous a-t-il empêché d'atteindre votre objectif?
David

1
Je pense que Ruby est génial lorsque vous voulez faire quelque chose comme un prototype et que vous voulez que cela se fasse rapidement, quelque chose qui n'est pas énorme et ne fera pas de calculs massifs. Si vous vous attendez à mâcher beaucoup de cycles CPU en permanence, tout bon programmeur sait utiliser quelque chose comme C ou C ++.
Jeff Welling

1
@David: J'envisagerais d'utiliser Ruby pour un code de traitement de séquence d'ADN simple, mais je ne le fais pas parce que Python remplit un créneau similaire, a des fonctionnalités similaires et est beaucoup plus rapide. Si je veux aller à un niveau inférieur, D est encore plus rapide et toujours pratique.
dsimcha

1
@Jeff: D'accord, mais C et C ++ sont pénibles à écrire. Le but des langages de haut niveau comme Ruby est d'éviter autant que possible de gérer cette douleur. Plus ils sont lents, moins ils atteignent bien cet objectif. Ruby est lent même pour un langage dynamique de haut niveau. Cela et NumPy / SciPy sont la raison pour laquelle j'utilise Python à la place lorsque j'ai besoin d'un langage dynamique de haut niveau.
dsimcha

4

Si cela peut être étendu à Ruby on Rails, alors:

  1. Le fait que la logique de la base de données donne à chaque table une auto_incrementclé primaire, y compris les tables qui n'en ont pas besoin et ne devraient pas en avoir.

  2. Le fait que les clés composées ne sont pas du tout prises en charge.

Pour Ruby, mon reproche serait le même que pour toute langue qui troque la sécurité contre l'expressivité; il est facile de faire beaucoup avec juste un peu de code, mais il est tout aussi facile de faire un énorme gâchis avec n'importe quelle quantité de code.


Veuillez consulter mes modifications car j'ai réduit la portée de la question. Je vais commencer un autre parallèle pour Rails si cette question avec modifications est approuvée.

1
Désolé, mais vous vous trompez, toutes les tables d'une application Rails ne doivent pas nécessairement avoir un auto_incrementidentifiant, notamment les tables de jointure pour les relations has_and_belongs_to_many sont suggérées de ne PAS explicitement avoir de colonne id.
Brett Bender

@Brett - Ces ajouts sont-ils relativement nouveaux? Quand je jouais avec lui au début de 2008, il n'avait définitivement pas ces fonctionnalités. Dans tous les cas, c'est super qu'ils soient disponibles maintenant.

1
@aroth: Je ne suis pas sûr que tout le monde considérerait "relativement nouveau" comme signifiant "au cours des trois dernières années" :-)

Il y a une alternative à ActiveRecord de Rails appelée DataMapper , qui n'est pas aussi opiniâtre qu'ActiveRecord.
Endy Tjahjono

3

Ruby embrasse la métaprogrammation (réflexion, introspection), la programmation multi-paradigmes et le dynamisme à un niveau inhabituel. Il est facile de se tirer une balle dans le pied avec puissance et flexibilité.

Gênant? Ruby a la capacité d'être extrêmement lisible ou insondable. J'ai vu du code qui semble appartenir à un script Bash.

Mauvaises pratiques? Certains rubis valorisent l'intelligence à la sagesse. Ils écrivent et partagent des astuces qui montrent leur intelligence, mais cela crée un code illisible et fragile.

En passant: Javascript a été un désastre de par sa conception, et le livre "The Good Parts" essaie d'extraire sa beauté cachée. Perl, un langage qui a popularisé "Il y a plus d'une façon de le faire" (c'est-à-dire la flexibilité), a un livre similaire dans "Perl, Best Practices". L'histoire de Perl est celle de l'expérimentation et de l'expérience durement gagnée, "Best Practices" représente son savoir. Perl 6 sera, je pense qu'il est juste de dire, un redémarrage du langage basé sur cette connaissance et plus encore. Ruby peut souffrir de problèmes similaires.

@James et boucles for ... Quand vous faites une boucle for en rubis, il appelle alors ".each". Par conséquent, "for" est du sucre syntaxique pour les personnes plus à l'aise avec les boucles de style C. Mais en tant que Rubyist, vous allez toujours utiliser des itérateurs comme .map, .inject, .each_with_object. Vous n'aurez jamais à écrire une boucle for avec quelque chose comme "i = 0; i> 6; i ++" en rubis, et donc vous finissez par abandonner l'habitude. @andrew ... rubis éloquent n'approuve pas les boucles.


-1

Cela concerne plus les programmeurs que le langage, mais pourquoi les programmeurs Ruby détestent-ils autant les boucles?

Je me rends compte que Ruby a:

someCollection.each do |item|
   ...
end

mais je n'ai jamais vu cela utilisé dans des situations où une boucle for ne ferait pas exactement la même chose.

J'ai demandé plusieurs fois et je n'ai jamais obtenu une bonne réponse à celle-ci.

Si c'est juste une question de style, je suis heureux d'accepter cela, mais j'ai vu des programmeurs Ruby vraiment travailler à ce sujet et je suis vraiment curieux.


1
Une fois que j'ai même obtenu la réponse "C'est moins d'appuyer sur les touches", ce qui est clairement faux ... :-)
James

2
Deux théories: 1) Utiliser des forboucles est quelque chose que les n00bs font. Les gens qui programment C en Ruby. 2) Les blocs sont beaucoup utilisés dans Ruby, donc utiliser quelque chose qui ne ressemble pas à un bloc n'est qu'un effort mental supplémentaire.
Andrew Grimm

3
Alors que je viens de commencer à apprendre Ruby, les blocs sont quelque chose que j'aime vraiment et qui me manque lorsque j'essaie d'utiliser Python. Une boucle for ferait-elle la même chose? Bien sûr, pour moi, ce genre de style correspond plus à mes préférences qu'une boucle for.
Jetti

2
@andrew Pour être honnête, votre 1ère réponse est exactement le genre de détritus que j'ai récupéré quand je l'ai déjà demandé. Aucune vraie raison, avec une insulte subtile sur le dessus. @Wayne, @Jetti et @andrews 2e réponse: merci. Assez juste alors.
James

1
Si vous voulez dire "amélioré" pour les boucles (aka. Pour <valeur> dans <expression> faites ...), il n'y a pas de différence en dehors de #chaque étant utilisé et d'apparence plus proche de ses cousins ​​couramment utilisés #inject, #collect, # rejeter etc. Si vous parlez de boucles indexées de style 'C' (aka. pour int i = 0; i <que ce soit; ++ i) la différence est que a) les erreurs "off by one" sont impossibles et b) qu'il clarifie l'intention de votre boucle - #chaque sens "pour chaque élément produit un effet secondaire". Une boucle for vous oblige à lire la boucle entière juste pour avoir le «sens» de son but.
Alexander Battisti

-1

J'évitais généralement les choses qui ont été ajoutées juste pour être rétrocompatibles avec d'autres langues. Par exemple, Perlismes et for x in y.


Je viens de poster une réponse sur Ruby Programmers et pour les boucles, et si vous pouvez m'expliquer, je vous serais reconnaissant :-)
James
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.