2010-04-13 22 views
15

Tengo un método ruby ​​(¡desactivar!) Que está en una clase activeRecord. Sin embargo, parece que no puedo encontrar dónde se declara ese método.¿Cómo puedo encontrar dónde se declara un método Ruby?

Ha habido numerosos desarrolladores en este proyecto, por lo que podría estar en cualquier lugar. Hay un desactivado! en una clase no relacionada, pero no parece ser llamado.

¿Alguna idea de cómo encontrar todas las superclases para un caso o dónde encontrar el código para desactivar?

Respuesta

15

Cuando necesito para encontrar donde se declara un método en una clase, dicen 'Modelo', hago

Model.ancestors.find {|c| c.instance_methods(false).include? :deactivate! } 

Esto busca el árbol antepasado en el mismo orden que el rubí hace por primera que tiene el método en instance_methods(false), que solo incluye métodos no heredados.

Nota: Antes de Ruby 1.9, los métodos fueron catalogados como cadenas no símbolos, por lo que sería

Model.ancestors.find {|c| c.instance_methods(false).include?('deactivate!') } 
+0

¡Ja! Ancestros es un método de Clase, no un método de instancia. No es de extrañar que no pudiera encontrarlo. Thx, Joe –

+0

Otra respuesta maravillosa y concisa, @mckeed. Gracias :) –

-1

Como primera puñalada, pruebe la función Salte a la declaración de su IDE. Dependiendo de cuán buena sea la inferencia de tipo estático de su IDE, debería llevarlo allí mismo.

Si eso no funciona, establezca un punto de interrupción en esa llamada, inicie el depurador y ingrese al método.

+2

-1. La pregunta es sobre Ruby. La inferencia de tipo estático no existe. Además, hay un 99% de posibilidades de que no esté usando un IDE. – fig

+0

@ fig-gnuton: Diamondback Ruby, herramientas de desarrollo Eclipse Ruby, Aptana RadRails, CodeGear 3rdRail, SapphireSteel Ruby in Steel para Visual Studio y el complemento NetBeans Ruby han * hecho * inferencias de tipo estático para Ruby durante * años *. Y a menos que esté usando el Bloc de notas, probablemente use un IDE o un editor de texto programable como TextMate, Vim o Emacs que pueden * convertirse * en un IDE. Además, un depurador es parte de la biblioteca estándar, no requiere un IDE o incluso una biblioteca de terceros (aunque la biblioteca 'ruby-debug' es mucho mejor, pero aún no requiere un IDE). –

+0

Jorg - bien jugado. Pero es probable que no use nada que tenga inferencia de tipo estático. Y la depuración no parece ser el mejor enfoque en comparación con la de mckeed. – fig

17

primera pregunta sería: ¿es un método real? ¿obj.method(:deactivate!) produce un error?

Si no lo hace, entonces usted puede utilizar Method#source_location (en Ruby 1.9 solamente, y backports no puede soportarla):

obj.method(:deactivate!).source_location 

Si esto aumenta un NoMethodError, se gestiona a través de method_missing. Esto hace que sea difícil de seguir. Si acepta argumentos, intentaré enviar el tipo incorrecto y usar la traza inversa de la excepción planteada.

¿Está utilizando state_machine? Si tiene una transición de evento llamada :deactivate, el modelo tendrá el método #deactivate! creado automáticamente.

Cuestiones relacionadas