Ruby: The Bad Parts [chiuso]


20

Di recente ho letto il libro di Crockford "Javascript: le parti buone" e una delle premesse sottostanti era che i linguaggi di programmazione possono avere cattive serie di funzionalità che i programmatori dovrebbero evitare.

Sono un Rubyist e mentre adoro la lingua, c'è sempre valore nell'ottenere una prospettiva. Quindi, qual è la caratteristica peggiore (ad esempio metodi, classi, pratiche) in Ruby? La mia intenzione qui non è quella di iniziare una discussione sui meriti della lingua stessa o sulla sua velocità e così via. Preferirei piuttosto una discussione su quali caratteristiche consideri pericolose / problematiche / dolorose da usare, basate su esperienze passate.


1
Non sono mai stato un fan di dover usare la parola "end", e quindi la combinazione di questo con "{" e "}" diventa ancora più fastidiosa. Mi fa apprezzare la sintassi in stile Python o quella di {&}. Anche se uno potrebbe discutere avanti e indietro su questo, e alla fine ha molto a che fare con le preferenze personali. Ho sentito qualcuno dire che Ruby prende le parti più brutte di Python e Perl e le mette insieme. Mi piace imparare Ruby, però.

In realtà mi piace abbastanza questa domanda e non vedo l'ora di rispondere, ma ho comunque votato per chiuderla. Non penso che sia adatto per Stack Overflow (perché potenzialmente troppo soggettivo / polemico, aperto, ecc.).
stakx,

Penso che valga la pena discutere perché potrebbe illuminare pratiche pericolose da evitare. Vedo il tuo punto però e ho modificato la domanda in modo da renderla più ristretta.

9
Non vedo come questa domanda sia sufficientemente distinta, ad esempio Quali sono le cose che vorresti migliorare nella lingua di Ruby? , Quali sono i Ruby Gotcha di cui un principiante dovrebbe essere avvisato? , Quali sono i problemi del mondo reale con Ruby? o una qualsiasi delle altre domande gazillion sui punti dolenti di Ruby. Inoltre, anche se questa domanda si evolve per differenziarsi da quelle degli altri, appartiene a Programmers.SE , non StackOverflow.
Jörg W Mittag,

2
Devo controllare i miei occhi - ho pensato che il titolo di questa domanda fosse "Ruby: The Brad Pitts".
Oosterwal,

Risposte:


8

Dovresti guardare Python vs Ruby: A Battle to The Death di Gary Bernhardt. Fa la citazione:

Le cose che trovo brutte in Ruby sono ciò che rende possibile un software Ruby sorprendente come RSpec e che Python non avrebbe mai potuto avere (data l'implementazione attuale).

Mentre parla molto di Python in particolare, tocca molte cose strane in Ruby. Uno dei grandi temi generali è il patching delle scimmie .

Gli oggetti Ruby (diversamente dagli oggetti in alcuni altri linguaggi orientati agli oggetti) possono essere modificati individualmente. È sempre possibile aggiungere metodi in base all'oggetto. In Ruby, il comportamento o le capacità di un oggetto possono discostarsi da quelli forniti dalla sua classe.

Mentre questo fornisce molta flessibilità e alimenta alcune delle gemme più popolari e complicate di Ruby, può morderti il ​​culo se stai cercando di eseguire il debug di un problema senza rendersi conto che alcune librerie da qualche parte hanno modificato un metodo di base.


Javascript ti consente di trattare anche gli oggetti in questo modo.
0112,

8

Alcune persone pensano solo al rubino in termini di rubino su rotaie ed è un po 'fastidioso perché la lingua si distingue abbastanza bene da sola.


7

Penso che la caratteristica peggiore sia quella open classesche ti consente di cambiare globalmente il comportamento di tutte le istanze attuali e future della classe cambiata.

La parte problematica di questa funzione è che queste modifiche (globali) avvengono durante il runtime quando l'interprete Ruby incontra la definizione, che potrebbe essere molto tempo dopo che hai già istanziato un paio di oggetti che ora cambiano il loro comportamento all'improvviso.

In una base di codice di grandi dimensioni ciò può risultare in bug molto, molto difficili da trovare, soprattutto perché questo è aggravato dalla debole storia di debug di Ruby (rispetto ad esempio al CLR o JVM) e l'uso di altre funzionalità (ad esempio eval) in questo contesto può rendere è abbastanza difficile trovare la posizione in cui si è verificato questo cambiamento globale. cioè se hai già raggiunto il punto in cui sospetti che la classe "giusta" causi il problema! Nella mia esperienza di solito inizi con una caccia all'oca selvatica, poiché i problemi iniziano a emergere su un oggetto usando il vero colpevole.

Quindi la cosa migliore sarebbe, o smettere di usare le classi aperte ( #extende mettere le modifiche in un ModuleIMHO è molto più sicuro, più facile da capire e meglio testare) o se non si può evitare di:

  • estendere solo le classi con un nuovo comportamento (ovvero non sovrascrivere il comportamento esistente)
  • avere un posto definito nella struttura del codice sorgente, in cui devono essere posizionate tutte le estensioni che utilizzano classi aperte
  • non usare #eval e gli amici per creare classi aperte
  • mettere tutti gli usi delle classi aperte su un grande grafico visibile, in cui tutti gli sviluppatori possano vederli - e chiarire che eventuali cambiamenti su di essi sono "decisioni architetturali" che interessano l'intera base di codice (cosa che fanno) e non il luogo per trucchi rapidi per il tuo compito attuale

5

Il motivo principale per cui non uso Ruby: è più lento della melassa a gennaio al Polo Nord durante un'era glaciale. Il benchmarking dei linguaggi è una scienza inesatta, ma Ruby appare drasticamente più lento di JavaScript e Python.


anche questa è stata la mia esperienza.
Chuck Stephanski,

2
qual era l'applicazione che hai sviluppato per il quale ruby ​​era troppo lento? Voglio dire, ti credo quando dici che è lento, ma come ti ha impedito di raggiungere il tuo obiettivo?
David,

1
Penso che Ruby sia eccezionale quando vuoi realizzare qualcosa di simile a un prototipo e lo vuoi fare rapidamente, qualcosa che non è enorme e non farà un enorme scricchiolio di numeri. Se ti aspetti di masticare costantemente molti cicli della CPU, qualsiasi buon programmatore sa usare qualcosa come C o C ++.
Jeff Welling,

1
@David: prenderei in considerazione l'uso di Ruby per un semplice codice di elaborazione delle sequenze di DNA, ma non perché Python riempie una nicchia simile, abbia caratteristiche simili ed è molto più veloce. Se sono disposto a passare al livello inferiore, D è ancora più veloce e comunque conveniente.
dsimcha,

1
@Jeff: D'accordo, ma C e C ++ sono un dolore da scrivere. Il punto di linguaggi di alto livello come Ruby è di evitare di affrontare questo dolore il più possibile. Più sono lenti, meno soddisfano questo obiettivo. Ruby è lento anche per un linguaggio dinamico di alto livello. Quello e NumPy / SciPy sono il motivo per cui uso Python invece quando ho bisogno di un linguaggio dinamico di alto livello.
dsimcha,

4

Se questo può essere esteso a Ruby on Rails, quindi:

  1. Il fatto che la logica del database dia ad ogni singola tabella una auto_incrementchiave primaria, comprese le tabelle che non ne hanno bisogno e che non dovrebbero averle.

  2. Il fatto che le chiavi composte non sono affatto supportate.

Per il semplice Ruby la mia lamentela sarebbe la stessa di qualsiasi linguaggio che scambia sicurezza per espressività; è facile fare molto con solo un po 'di codice, ma è altrettanto facile fare un casino enorme con qualsiasi quantità di codice.


Si prega di vedere le mie modifiche poiché ho ristretto l'ambito della domanda. Inizierò un altro parallelo per Rails se questa domanda con le modifiche è approvata.

1
Siamo spiacenti, ma ti sbagli, non tutte le tabelle in un'app Rails devono avere un auto_incrementID, in particolare si consiglia di unire le tabelle per le relazioni has_and_belongs_to_molte. Si suggerisce di NON avere esplicitamente una colonna ID.
Brett Bender,

@Brett - Sono aggiunte relativamente nuove? Quando ci giocavo all'inizio del 2008, sicuramente non aveva quelle caratteristiche. In ogni caso, è fantastico che siano disponibili ora.

1
@aroth: non sono sicuro che tutti gli altri considererebbero "relativamente nuovo" come "negli ultimi tre anni" :-)

Esiste un'alternativa all'ActiveRecord di Rails chiamato DataMapper , che non è così supponente come ActiveRecord.
Endy Tjahjono,

3

Ruby abbraccia metaprogrammazione (riflessione, introspezione), programmazione multi-paradigma e dinamismo a un livello non comune. È facile spararsi al piede con potenza e flessibilità.

Fastidioso? Ruby ha la capacità di essere estremamente leggibile o imperscrutabile. Ho visto codice che sembra appartenere a uno script Bash.

Cattive pratiche? Alcuni rubini apprezzano l'intelligenza sulla saggezza. Scrivono e condividono trucchi che mettono in mostra la loro intelligenza, ma questo crea un codice illeggibile e fragile.

A parte questo: Javascript è stato un disastro in base alla progettazione e il libro "Le parti buone" cerca di estrarre la sua bellezza nascosta. Perl, una lingua che ha reso popolare "C'è più di un modo per farlo" (ovvero flessibilità), ha un libro simile in "Perl, Best Practices". La storia di Perl è fatta di sperimentazione ed esperienza duramente vinta, "Best Practices" rappresenta la sua conoscenza. Perl 6 sarà, credo sia giusto dire, un riavvio del linguaggio basato su quella conoscenza e altro ancora. Il rubino può soffrire di problemi simili.

@James e for loop ... Quando esegui un ciclo for in ruby, allora chiama ".each". Pertanto, "for" è lo zucchero sintattico per le persone più a proprio agio con i loop in stile C. Ma come Rubyist, userai sempre iteratori come .map, .inject, .each_with_object. Non dovrai mai scrivere un ciclo for con qualcosa come "i = 0; i> 6; i ++" in ruby, e così finisci per perdere l'abitudine. @andrew ... il rubino eloquente non sostiene i loop.


-1

Questo riguarda più i programmatori che la lingua, ma perché i programmatori di Ruby odiano così tanto i loop?

Mi rendo conto che Ruby ha:

someCollection.each do |item|
   ...
end

ma non l'ho mai visto usato in situazioni in cui un ciclo for non farebbe esattamente la stessa cosa.

Ho chiesto più volte e non ho mai avuto una buona risposta a questo.

Se è solo una cosa di stile, sono felice di accettarlo, ma ho visto i programmatori di Ruby molto coinvolti su questo e sono davvero curioso.


1
Una volta ho persino ricevuto la risposta "Sono meno pressioni dei tasti", che è chiaramente falso ... :-)
James,

2
Due teorie: 1) Usare i forloop è qualcosa che fa n00bs. Persone che stanno programmando C in Ruby. 2) I blocchi sono usati molto in Ruby, quindi usare qualcosa che non sia simile a un blocco è solo uno sforzo mentale extra.
Andrew Grimm,

3
Mentre ho appena iniziato a studiare Ruby, i blocchi sono qualcosa che mi piace molto e mi manca quando provo ad usare Python. Un ciclo for farebbe la stessa cosa? Naturalmente, per me, questo tipo di stile si adatta alle mie preferenze più che a un ciclo for.
Jetti,

2
@andrew Ad essere sincero, la tua prima risposta è esattamente il tipo di immondizia che ho ricevuto quando l'ho chiesto prima. Nessun vero motivo, con un insulto sottile in cima. @Wayne, @Jetti e @andrews 2a risposta: grazie. Abbastanza giusto allora.
James,

1
Se intendi "potenziato" per i loop (ovvero per <valore> in <espressione> do ...) non vi è alcuna differenza a parte # ogni essere in uso e l'aspetto più vicino ai suoi cugini di uso comune #inject, #collect, # rifiutare ecc. Se si parla di loop indicizzati in stile 'C' (ovvero per int i = 0; i <qualunque; ++ i) la differenza è che a) errori "off by one" sono impossibili eb) che rende chiara l'intenzione del tuo ciclo - #each significa "per ogni elemento produce un effetto collaterale". Un ciclo for richiede di leggere l'intero ciclo solo per ottenere il "senso" del suo scopo.
Alexander Battisti,

-1

Generalmente eviterei cose che sono state aggiunte solo per essere retrocompatibili con altre lingue. Ad esempio, Perlismi e for x in y.


Ho appena pubblicato una risposta su Ruby Programmers e per i loop, e se puoi spiegare te ne sarei grato :-)
James
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.