2011-10-04 14 views
11

Cuando invoco un método que no existe, method_missing me dirá el nombre del método. Cuando intento acceder a una variable que no se ha establecido, el valor es simplemente nil.¿Ruby tiene un method_missing equivalente para variables de instancia indefinidas?

Estoy intentando interceptar dinámicamente el acceso a variables de instancia nulas y devolver un valor basado en el nombre de la variable a la que se accede. El equivalente más cercano sería PHP __get. ¿Hay alguna funcionalidad equivalente en Ruby?

+0

¿Conoces las advertencias y cómo activarlas? –

Respuesta

0

no hay una instancia_variable_missing (al menos que yo sepa) ¿Pero por qué estás accediendo aleatoriamente a las variables de instancia nombradas de todos modos?

Si su rosca es todo el acceso al estado del objeto a través de llamadas a métodos (como debería hacerlo de todos modos), entonces no lo necesitaría.

Si está buscando una forma de definir cosas mágicas sin estropear la búsqueda de métodos, puede usar const_missing.

+0

Las variables no tienen un nombre aleatorio. Estoy jugando con la representación de un correo electrónico sin pasar por el programa de correo responsable de configurar las variables de instancia, para fines de prueba. La vista intentará acceder a elementos como '@ user.name' sin que se configure' @ user'. Pensé que podría generar dinámicamente objetos FactoryGirl para cosas como '@ user' en la primera lectura. – meagar

+0

Veo gracias. AFAICT Me temo que su única opción es leer el archivo de la plantilla y establecer los vars en consecuencia (o posiblemente darle la vuelta al problema y usar 'method_missing' en su plantilla de correo electrónico). Lo cual es una pena ya que ruby ​​incluso sabe cuándo está accediendo a una variable indefinida y le dará una advertencia. – riffraff

2

No creo que esto sea posible en Ruby. La forma recomendada sería utilizar un método de '' usuario '' en lugar de una var de instancia '' @user '' en sus plantillas.

Esto es coherente con la forma en que maneja los objetos Ruby externamente ('' obj.user '' es un método que se refiere a '' @user '', pero en realidad no es '' @user ''). Si necesita algún tipo de lógica especial con un atributo, su mejor opción es usar un método (o método_aprobar), independientemente de si está accediendo desde dentro o desde fuera del objeto.

1

Ver mi answer to another similar question. Pero solo porque puede hacerlo no significa que sea una buena idea. Un diseño sensato generalmente puede superar la necesidad de este tipo de cosas y le permite producir un código más legible y, por lo tanto, más fácil de mantener.

instance_variable_get parece ser el equivalente más cercano de PHP __get de lo que puedo ver (aunque no soy un usuario de PHP).

En cuanto al relevant Ruby source code, el único método 'que falta' para las variables es const_missing para las constantes, nada para las variables de instancia.

+1

No ayuda. Tendría que convertir todos mis usos de variables de instancia en llamadas a métodos, lo que es completamente poco práctico. – meagar

+0

Bueno, no hay tal facilidad en Ruby para acceder dinámicamente a variables de instancia distintas de las que describí en esa otra respuesta. Ver respuesta actualizada arriba. – arcresu

Cuestiones relacionadas