2009-07-09 3 views
6

Sono nuovo di Ruby e di recente ho riscontrato un problema rispetto ai valori durante la creazione di un'applicazione Ruby on Rails. In un controller ho avuto la seguente dichiarazione che ha sempre restituito falso:Sintassi Verifica o "Compilazione" di un'applicazione Ruby on Rails

if (user.id != params[:id]) 

Il problema era l'user.id (che è un Active Record) è un numero intero e params [: id] è una stringa. Mi ci è voluto un po 'per capirlo e finalmente l'ho cambiato:

if (user.id != params[:id].to_i) 

Ora la dichiarazione funziona come previsto.

Per evitare questo errore in futuro c'è un modo per "compilare" o ottenere Ruby per avvisare se si tenta di confrontare 2 diversi tipi? Alcuni altri problemi che ho riscontrato sono:

  • Avvisami se creo una variabile ma non la uso. Per aiutare a verificare errori di battitura nei nomi delle variabili.
  • Assicurarsi che esista un metodo in una classe in modo da evitare errori di digitazione del metodo e anche per aiutare il refactoring, ad esempio se rinominare un metodo.

Attualmente sto usando Ruby 1.8.6-27 RC2 con Rails 2.3.2 e RadRails IDE su Windows.

+0

Nessuna risposta per testare il codice. Ho avuto un test unitario per il suddetto frammento di codice e ha continuato a fallire (insieme ai miei test manuali) e non riuscivo a capire perché. Quello che sto cercando è un correttore di sintassi per Ruby che trovi errori simili che il compilatore standard avrebbe trovato. Grazie. –

+0

Un compilatore C non ti darà un errore per fare 4 == 5.5. – Chuck

+0

Dai un'occhiata a jetbrain ruby ​​ide, https://www.jetbrains.com/ruby/ –

risposta

0

La soluzione migliore che ho trovato era un IDE che eseguiva il controllo della sintassi in tempo reale, come RubyMine. Non sono sicuro se avrebbe risolto il mio problema originale ma mi ha aiutato a trovare e correggere molti altri errori di sintassi e compilazione. Grazie a tutti per i vostri suggerimenti.

5

Prima prova, quindi codice. Se si scrivono test che coprono tutti i rami della propria applicazione, si ottiene la certezza che il codice sia eseguito e produca risultati corretti.

MODIFICA: Devo sottolineare che la possibilità di confrontare due tipi, non dipende dai nomi dei metodi fino all'ultimo secondo, ecc. Sono caratteristiche fondamentali di Ruby.

Non si chiama un metodo tanto quanto si invia un messaggio a un oggetto. L'oggetto è quindi responsabile di capire come gestire il metodo. In Rails viene utilizzato per accedere alle colonne DB in ActiveRecord. Non ci sono metodi per le colonne finché non viene inviato un messaggio con il nome della colonna all'oggetto.

La digitazione statica in Ruby va contro il sistema di digitazione anatra. Spesso è possibile ottenere gratuitamente il polimorfismo senza preoccuparsi di complessi schemi di ereditarietà/interfaccia.

Suggerisco di abbracciare queste caratteristiche e compensare l'incertezza attraverso test

1

Rubino non dovrebbe essere al sicuro. Ti permette di confrontare qualsiasi due oggetti, ed è da lì che proviene gran parte del suo potere. Rails non sarebbe possibile senza un design così dinamico.

Anche un linguaggio compilato come Java o C non ti impedirà di fare == su due oggetti. Come Ben ha detto, è meglio testare prima. Ispeziona le strutture con cui lavori. Un modo per ottenere informazioni su un oggetto Ruby è da utilizzare:

puts object.class 
+0

p oggetto, scaricherà una versione più dettagliata di un oggetto. mixare p e puts è generalmente un vincitore per ottenere informazioni di debug. –

+0

Sì. La stampa è il mio strumento di debug di scelta. È anche possibile utilizzare ./script/console per accedere agli oggetti in modo interattivo. – mcandre

1

In generale, il modo migliore (che conosco) per evitare questo tipo di problema per i linguaggi dinamici/scripting è quello di spostare la "logica" per i metodi/comandi e scrivere test unitari per loro. Fondamentalmente, tutto ciò che può fallire dovrebbe essere testato. Il codice sulla pagina dovrebbe essere una logica stupida ... piuttosto che visualizzare solo quegli elementi che soddisfano determinati criteri, dovrebbe visualizzare tutti gli elementi e ottenere quell'elenco di elementi da un metodo che restituisce solo quelli che dovrebbero essere visualizzati.

2

Ruby non consente di ridefinire l'operatore == per Object.In Ruby 1.8 non si può, Ruby 1.9 avrebbe dovuto farlo, ma non sono stato in grado di far funzionare il mio script per le classi principali. Funziona bene per oggetti definiti personalizzati.

class Object 

    alias :equal_without_warning :== 

    def ==(object) 
    unless self.class == object.class 
     warn("Comparing `#{self.class}' with `#{object.class}'") 
    end 
    equal_without_warning(object) 
    end 

end 

Supponendo che non ho fatto qualche errore di codifica stupido, la risposta è NO: non si può verificare se si sta confrontando diversi tipi di oggetti.

Inoltre, direi di no. In realtà, Ruby non è progettato per funzionare in questo modo, questo è più un approccio java piuttosto che uno stile Ruby.

+0

Dovrai eseguire la stessa ridefinizione per le classi principali poiché normalmente ridefiniscono == senza riferimento all'Oggetto # == – rampion

0

due cose io suggerirei:

One: Leggi su IRB (o dello script/console per rotaie). Una pratica di sviluppo comune nei linguaggi dinamici è quella di provare snippet di codice all'interno di un interprete "live" (come IRB o la console di rails). Questa pratica risale ai primi linguaggi dinamici come Smalltalk e Lisp. Ruby-debug è anche molto utile per la risoluzione dei problemi e sarebbe stato un modo molto semplice per capire l'errore nel tuo esempio.

Due: leggere su "Duck Typing". "Tipi" e variabili funzionano in modo leggermente diverso in Ruby di quanto molti si aspettino che facciano. A quanto ho capito, una variabile come user.id non ha un "tipo". Il valore indicava da user.id ha un tipo, ma la variabile di per sé no. Credo che sia parte del motivo per cui non esiste uno strumento che ti avrebbe detto quale fosse il tuo errore prima dell'esecuzione del programma. Il confronto di queste due variabili non è un errore perché le variabili non hanno un tipo. user.id stava puntando a un intero in quel punto del tuo programma, ma sarebbe perfettamente legale assegnare user.id per puntare a una stringa, a quel punto il confronto avrebbe avuto molto più senso. :-)

+0

Inoltre, non c'è alcun motivo per cui non puoi confrontare due diversi tipi con '=='. – Chuck