obtener nombre de variable de instancia de sí mismo en ruby

Tengo una variable de instancia @foo y quiero escribir algo de código para obtener la cadena 'foo'

alguna pista?

Si todo lo que tiene es una referencia al objeto, realmente no puede hacerlo limpiamente.

 def foo bar @something end def bar(value) value # no clean way to know this is @something end 

El único truco que se me ocurre es recorrer TODAS las variables de instancia en self , buscando coincidencias. Pero es un enfoque muy desordenado que probablemente sea lento.

 def bar(value) instance_variables.each do |ivar_name| if instance_variable_get(ivar_name) == value return ivar_name.to_s.sub(/^@/, '') # change '@something' to 'something' end end # return nil if no match was found nil end @something = 'abc123' bar @something # returns 'something' # But passing the same value, will return a value it's equal to as well bar 'abc123' # returns 'something' 

Esto funciona porque instance_variables devuelve una matriz de símbolos que son los nombres de las variables de instancia.

 instance_variables #=> [:@something, :@whatever] 

Y instance_variable_get permite obtener el valor por su nombre.

 instance_variable_get :@something # note the @ #=> 'abc123' 

Combina los dos métodos y podrás acercarte a lo que quieras.


Sólo úsalo sabiamente. Antes de usar una solución basada en esto, vea si puede refactorizar las cosas de manera que no sea necesario. La meta-progtwigción es como un arte marcial. Debe saber cómo funciona, pero tenga la disciplina de evitar usarlo siempre que sea posible.

En Ruby, solo puedes manipular objetos. Las variables (incluidas las variables de instancia) no son objetos.

Además, ¿qué quieres que devuelva tu método mágico en este caso?

 foo = Object.new bar = foo @baz = bar @qux = bar magic_method(foo) # what should the return value be and how would it know? 

Puede llamar al método instance_variables para obtener el nombre de todas las variables de instancia de un objeto. Tenga en cuenta que las variables de instancia solo se incluyen en esa lista después de que se hayan inicializado.

 >> class A; attr_accessor :foo; end => nil >> a = A.new => # >> a.instance_variables => [] >> a.foo = 42 => 42 >> a.instance_variables => ["@foo"]