2009-07-09 14 views
6

Soy nuevo en Ruby y recientemente encontré un problema al comparar con los valores al crear una aplicación Ruby on Rails. En un controlador que tenía la siguiente declaración de que siempre se devuelve falso:Comprobación de la sintaxis o "Compilación" de una aplicación Ruby on Rails

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

El problema era la user.id (que es un Active Record) es un entero y params [: id] es una cadena. Me tomó un tiempo para resolver esto y finalmente lo cambié a:

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

Ahora la declaración funciona como se esperaba.

Para evitar este error en el futuro ¿hay alguna manera de "compilar" o hacer que Ruby te advierta si intentas comparar 2 tipos diferentes? Algunos otros problemas que me he encontrado que me gustaría "compilar verificación" son:

  • Avisadme si creo una variable pero no la uso. Para ayudar a verificar si hay errores tipográficos en los nombres de las variables.
  • Asegúrese de que exista un método en una clase para poder evitar los errores tipográficos del nombre del método y también para ayudar a la refactorización, por ejemplo, si cambio el nombre de un método.

Actualmente estoy usando Ruby 1.8.6-27 RC2 con Rails 2.3.2 y RadRails IDE en Windows.

+0

Por favor, no hay respuestas sobre la prueba de su código. Tuve una prueba unitaria para el fragmento de código anterior y siguió fallando (junto con mi prueba manual) y no pude entender por qué. Lo que estoy buscando es un verificador de sintaxis para Ruby que encuentre errores similares que el compilador estándar encontraría. Gracias. –

+0

Un compilador de C no le dará un error al hacer 4 == 5.5. – Chuck

+0

Echa un vistazo a jetbrains ruby ​​ide, https://www.jetbrains.com/ruby/ –

Respuesta

0

La mejor solución que encontré fue un IDE que realizaba comprobaciones de sintaxis sobre la marcha, como RubyMine. No estoy seguro de si hubiera solucionado mi problema original, pero me ha ayudado a encontrar y corregir varios otros errores de sintaxis y compilación. Gracias a todos por sus sugerencias.

5

Primero pruebe, luego codifique. Si escribe pruebas que cubren todas las ramas de su aplicación, obtiene la garantía de que su código se ejecuta y produce resultados correctos.

EDITAR: Debo señalar que la capacidad de comparar dos tipos, no depender de los nombres de los métodos hasta el último segundo, etc. son características principales de Ruby.

No llama tanto a un método como a un mensaje a un objeto. El objeto es entonces responsable de descubrir cómo manejar el método. En Rails esto se usa para acceder a las columnas de DB en ActiveRecord. No hay métodos para las columnas hasta que se envíe un mensaje con el nombre de la columna al objeto.

La tipificación estática en Ruby va en contra del sistema de tipado de patos. A menudo se puede obtener polimorfismo de forma gratuita sin preocuparse por complejos esquemas de herencia/interfaz.

Sugiero adoptar estas características y compensar la incertidumbre a través de pruebas

1

Ruby no se supone que es segura. Te permite comparar dos objetos, y de ahí proviene gran parte de su poder. Los rieles no serían posibles sin un diseño tan dinámico.

Incluso un lenguaje compilado como Java o C no le impedirá hacer == en dos objetos. Como dijo Ben, lo mejor es probar primero. Inspecciona las estructuras con las que estás trabajando. Una forma de obtener información sobre un objeto Ruby es utilizar:

puts object.class 
+0

p object, arrojará una versión más detallada de un objeto. mezclar p y puts generalmente es un ganador para obtener información de depuración. –

+0

Sí. Imprimir es mi herramienta de depuración de elección. También puede usar ./script/console para acceder a los objetos de forma interactiva. – mcandre

1

En general, la mejor manera (no conozco) para evitar este tipo de problema para los lenguajes dinámicos/script es mover "lógica" a los métodos/comandos y escribir pruebas de unidades para ellos. Básicamente, todo lo que puede fallar debe ser probado. El código en la página debe ser tonto ... en lugar de mostrar únicamente aquellos elementos que cumplen ciertos criterios, debe mostrar todos los elementos y obtener esa lista de elementos de un método que solo devuelve los que deberían mostrarse.

2

Ruby no le permite redefinir el operador == para Object.En Ruby 1.8 no se puede, se suponía que debía hacer Ruby 1.9 pero no he podido hacer que mi script funcione para las clases principales. Funciona bien para objetos definidos a medida.

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 

Suponiendo que no hice algún error de codificación estúpida, la respuesta es NO: no se puede comprobar si se está comparando diferentes tipos de objetos.

Además, yo diría que no. En realidad, Ruby no está diseñado para funcionar de esta manera, este es más un enfoque de Java que de Ruby.

+0

Tendrá que hacer la misma redefinición para las clases principales, ya que normalmente redefinen == sin referencia al Objeto # == – rampion

0

Dos cosas que me ha sugerido:

uno: Lea sobre IRB (o script/consola para rieles). Una práctica de desarrollo común en lenguajes dinámicos es probar fragmentos de código dentro de un intérprete "en vivo" (como IRB o la consola de rieles). Esta práctica se remonta a los primeros lenguajes dinámicos como Smalltalk y Lisp. Ruby-debug también es muy útil para solucionar problemas y hubiera sido una manera muy fácil de resolver el error en tu ejemplo.

Dos: Lea sobre "Duck Typing". Los "tipos" y variables funcionan un poco diferente en Ruby de lo que mucha gente espera. Según lo entiendo, una variable como user.id no tiene un "tipo". El valor apuntaba a por user.id tiene un tipo, pero la variable en sí no. Creo que eso es parte de por qué no hay una herramienta que te haya dicho cuál fue tu error antes de ejecutar el programa. Comparar esas dos variables no es un error porque las variables no tienen un tipo. user.id apuntaba a un número entero en ese punto de su programa, pero sería perfectamente legal asignar user.id para señalar una cadena, momento en el que esa comparación tendría mucho más sentido. :-)

+0

. Tampoco hay ninguna razón por la que no pueda comparar dos tipos diferentes con '=='. – Chuck

Cuestiones relacionadas