¿Cómo hago introspección en Ruby?


Por ejemplo, en Python, puedo hacer cosas como esta si quiero obtener todos los atributos de un objeto:

>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'gettrace', 'hexversion', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'py3kwarning', 'pydebug', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoptions']

O si quiero ver la documentación de algo, puedo usar la función de ayuda:

>>> help(str)

¿Hay alguna manera de hacer cosas similares en Ruby?

Author: Jason Baker, 2010-03-22

4 answers

Claro, es incluso más simple que en Python. Dependiendo de la información que estés buscando, prueba:

obj.methods

Y si desea solo los métodos definidos para obj (en lugar de obtener métodos en Object también)

obj.methods - Object.methods

También es interesante hacer cosas como:

obj.methods.grep /to_/

Para obtener variables de instancia, haga esto:

obj.instance_variables

Y para las variables de clase:

obj.class_variables
 39
Author: rfunduk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-22 14:30:54

Si desea todos los métodos que puede llamar a algo que use

>>> x.methods

Si desea alguna información de ayuda, llame a help antes de su clase

>>> help x.class

Help es una envoltura para ri dentro de irb.

 4
Author: Brandon Bodnar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-22 14:07:14

Si tienes un objeto, y quieres saber a qué métodos responde, puedes ejecutar obj.methods (y todos los trucos que thenduks ha mencionado en este resultado.)

Si tiene una clase, puede ejecutar klass.methods para ver qué métodos de clase están disponibles, o puede ejecutar klass.instance_methods para saber qué métodos están disponibles en instancias de esa clase. klass.instance_methods(false) es útil, porque le dice qué métodos fueron definidos por la clase y no heredados.

Ahora hay una manera de obtener texto de ayuda para un método dentro de Ruby la forma en que Python lo hace.

 1
Author: Ken Bloom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-22 14:08:03

Hay un módulo llamado ObjectSpace que se incluye en cada objeto creado en ruby. Contiene todos los métodos que le ayudan a hacer introspección del contexto actual del proceso. En irb se comienza en el contexto Object:Main que es el contexto de nivel superior para la sesión irb actual. Entonces podrías hacer algo como time = Time.now y luego hacer irb time que te llevaría al contexto de ese objeto y podrías inspeccionarlo desde dentro sin llamar a los métodos ObjectSpace en ese objeto.

 1
Author: Eimantas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-22 14:36:15