Como no hay ningún tipo de rubí, ¿cómo se aseguran los programadores de Ruby de que una función reciba los argumentos correctos? En este momento, estoy repitiendo las declaraciones if object.kind_of
/instance_of
para verificar y aumentar los errores de tiempo de ejecución en todas partes, lo cual es feo. Debe haber una mejor forma de hacer esto.¿Cómo hacen los programadores de Ruby la verificación de tipos?
Respuesta
Ruby es, por supuesto, tipeado dinámicamente.
Por lo tanto, la documentación del método determina el tipo de contrato; la información de tipo se mueve desde el sistema de tipo formal a la documentación del método [tipo de letra informal]. Mezclo generalidades como "actúa como una matriz" y detalles como "es una cadena". La persona que llama solo debe esperar trabajar con los tipos indicados.
Si la persona que llama viola este contrato, puede pasar cualquier cosa. El método no necesita preocuparse: se usó incorrectamente.
A la luz de lo anterior, evitar la comprobación de un tipo específico y evitar tratando de crear sobrecargas con tal comportamiento.
Pruebas unitarias pueden ayudar asegurarse de que el contrato funcione para los datos esperados.
@cjk Si bien este es un buen paradigma a seguir, todavía no responde la pregunta. Sugiero que aceptes la respuesta de Sawa en su lugar. – anthropomorphic
Mi manera personal, que no estoy seguro si es una forma recomendada en general, es verificar y hacer otras validaciones una vez que se produce un error. Puse la rutina de verificación de tipo en un bloque de rescate. De esta forma, puedo evitar la pérdida de rendimiento cuando se dan los argumentos correctos, pero todavía devuelvo el mensaje de error correcto cuando ocurre un error.
def foo arg1, arg2, arg3
...
main_routine
...
rescue
## check for type and other validations
raise "Expecting an array: #{arg1.inspect}" unless arg1.kind_of?(Array)
raise "The first argument must be of length 2: #{arg1.inspect}" unless arg1.length == 2
raise "Expecting a string: #{arg2.inspect}" unless arg2.kind_of?(String)
raise "The second argument must not be empty" if arg2.empty?
...
raise "This is `foo''s bug. Something unexpected happened: #{$!.message}"
end
Supongamos que en el main_routine
, se utiliza el método each
en arg1
arg1
suponiendo que es una matriz. Si resulta que se trata de otra cosa, a la que no se ha definido each
, el mensaje de error aparecerá como method each not defined on ...
, que, desde la perspectiva del usuario del método foo
, podría no ser útil. En ese caso, el mensaje de error original será reemplazado por el mensaje Expecting an array: ...
, que es mucho más útil.
El problema con esto, sin embargo, es que el error * real * podría ser enmascarado debido a uno de los otros problemas que se recogen. Por lo tanto, aunque podría * también * ser un problema, podría no estar relacionado con lo que realmente se planteó. Si se va a realizar una comprobación de tipos explícita, hágalo * primero *, no en recuperación. –
¿Por qué usas '# {arg1}' en lugar de '# {arg1.inspect}'? O más específicamente, '" Esperando una cadena: # {arg2} "' en lugar de '" Esperando una cadena: # {arg2.inspect} "'? –
@pst Eso se puede evitar colocando otro 'raise' al final mientras editaba. Si se genera un error interno a 'foo' pero se pasa toda la validación, entonces el caso es que la verificación de validación no fue suficiente o que hay un error interno en' foo'. – sawa
Si un método tiene un motivo para existir, se lo llamará.
Si se escriben pruebas razonables, se ejecutará todo.
Y si se llama a todos los métodos, se verificarán todos los métodos.
No pierda el tiempo realizando comprobaciones de tipo que pueden limitar innecesariamente las llamadas y solo duplicará la comprobación de tiempo de ejecución de todos modos. Pasar ese tiempo escribiendo pruebas en su lugar.
se recomienda utilizar el aumento en el principio del método para agregar la comprobación manual tipo, simple y eficaz:
def foo(bar)
raise TypeError, "You called foo without the bar:String needed" unless bar.is_a? String
bar.upcase
end
mejor manera cuando usted no tiene mucho parámetros, también una recomendación es usar palabras clave argumentos disponibles en ruby 2+ si tiene múltiples parámetros y observa sus detalles de implementación actuales/futuros, están mejorando la situación, dando al programador una manera de ver si el valor es nulo.
más: se puede utilizar una excepción personalizada
class NotStringError < TypeError
def message
"be creative, use metaprogramming ;)"
#...
raise NotStringError
Se puede utilizar un enfoque Design by Contract, con la gema contracts rubí. Me parece bastante agradable.
- 1. ¿los complementos de ruby hacen que vim arranque muy lento?
- 2. ¿Cómo maneja la programación/fechas límite alrededor de los programadores?
- 3. ¿Cuál es el significado para los programadores de Ruby de la nueva implementación de SAP de Ruby?
- 4. ¿Cómo se hacen las pruebas de rendimiento en Ruby webapps?
- 5. ¿Qué hacen los probadores?
- 6. ¿Cómo se distribuye un programa Clojure a los no programadores?
- 7. Verificación del valor por defecto utilizando los tipos genéricos
- 8. Enseñando JavaScript a los programadores de Java
- 9. Lista de todos los tipos declarados por módulo en Ruby
- 10. ¿Qué hacen los diferentes tipos de asistencia de contenido de Eclipse?
- 11. Python: se necesitan importaciones circulares para la verificación de tipos
- 12. ¿Cómo sobrevivieron los programadores Java antes de las anotaciones?
- 13. La mejor manera para que los programadores editen XAML
- 14. ¿Hay algún tutorial para los programadores de Ruby que quieran aprender Perl?
- 15. cómo borrar la casilla de verificación
- 16. ¿Qué hacen los operadores '& =' y '= &'?
- 17. ¿Qué IDE utilizan los programadores CLISP?
- 18. ¿Qué hacen exactamente los comandos de Vagrant?
- 19. Programadores de Dragon NaturallySpeaking
- 20. tipos de Ruby de colecciones en ActiveRecord
- 21. Dos preguntas para los programadores antiguos
- 22. ¿Qué hacen los refuerzos después de la nueva declaración C#?
- 23. ¿Recomendarías vim/emacs para los programadores principiantes?
- 24. ¿Cómo hacen los desarrolladores de código abierto para ganar dinero?
- 25. ¿Cómo hacen Instagram o Hipstamatic los filtros de fotos?
- 26. ¿Cómo hacen los juegos efectos de fuego y humo?
- 27. ¿Qué modismos de C++ deben usar los programadores de C++?
- 28. Computación científica en Python para los programadores de MATLAB
- 29. cómo obtener la etiqueta localizada de los tipos de teléfono?
- 30. Desactivar la verificación del certificado SSL en Ruby
¿Por qué necesita asegurarse de que la entrada sea de un tipo específico? Las funciones hacen lo que se les dice y en realidad no se las debe forzar a verificar. – Blender
buscar "pato-tipado" –
@Blender Eg. setNextNode (link). En esta función, si no tengo un control de tipo, se puede pasar cualquier cosa ... Estoy haciendo una tarea ahora y me han pedido que revise el tipo y me asegure de que esté en tiempo de ejecución. – kun