How do you list the currently available objects in the current scope in ruby?
I'm not entirely sure of what you mean by the 'current objects'. You can iterate over ObjectSpace, as has been mentioned already. But here are a few other methods.
local_variablesinstance_variablesglobal_variablesclass_variablesconstants
There's one gotcha. They must be called at the right scopes. So right in IRB, or in an object instance or at class scope (so everywhere, basically) you can call the first 3.
local_variables #=> ["_"]foo = "bar"local_variables #=> ["_", "foo"]# Note: the _ variable in IRB contains the last value evaluated_ #=> "bar"instance_variables #=> []@inst_var = 42instance_variables #=> ["@inst_var"]global_variables #=> ["$-d", "$\"", "$$", "$<", "$_", ...]$" #=> ["e2mmap.rb", "irb/init.rb", "irb/workspace.rb", ...]
But umm, what if you want your program to actually evaluate them without needing you to type them manyally? The trick is eval.
eval "@inst_var" #=> 42global_variables.each do |v| puts eval(v)end
The last 2 of the 5 mentioned at the beginning must be evaluated at the module level (a class is a descendant of a module, so that works).
Object.class_variables #=> []Object.constants #=> ["IO", "Duration", "UNIXserver", "Binding", ...]class MyClass A_CONST = 'pshh' class InnerClass end def initialize @@meh = "class_var" endendMyClass.constants #=> ["A_CONST", "InnerClass"]MyClass.class_variables #=> []mc = MyClass.newMyClass.class_variables #=> ["@@meh"]MyClass.class_eval "@@meh" #=> "class_var"
Here's are a few more tricks to explore in different directions
"".class #=> String"".class.ancestors #=> [String, Enumerable, Comparable, ...]String.ancestors #=> [String, Enumerable, Comparable, ...]def trace return callerendtrace #=> ["(irb):67:in `irb_binding'", "/System/Library/Frameworks/Ruby...", ...]
ObjectSpace.each_object could be what you are looking for.
To get a list of included modules you could use Module.included_modules.
You can also check if an object responds to a method on a case-by-case basis using object.respond_to?.
The dir()
method is not clearly defined...
Note: Because
dir()
is supplied primarily as a convenience for use at an interactive prompt, it tries to supply an interesting set of names more than it tries to supply a rigorously or consistently defined set of names, and its detailed behavior may change across releases.
...but we can create a close approximation in Ruby. Let's make a method that will return a sorted list of all methods added to our scope by included modules. We can get a list of the modules that have been included by using the included_modules
method.
Like dir()
, we want to ignore the "default" methods (like print
), and we also want to focus on the "interesting" set of names. So, we will ignore methods in Kernel
, and we will only return methods that were defined directly in the modules, ignoring inherited methods. We can accomplish the later by passing false
into the methods()
method. Putting it all together we get...
def included_methods(object=self) object = object.class if object.class != Class modules = (object.included_modules-[Kernel]) modules.collect{ |mod| mod.methods(false)}.flatten.sortend
You can pass it a class, an object, or nothing (it defaults to the current scope). Let's try it out...
irb(main):006:0> included_methods=> []irb(main):007:0> include Math=> Objectirb(main):008:0> included_methods=> ["acos", "acosh", "asin", "asinh", "atan", "atan2", "atanh", "cos", "cosh", "erf", "erfc", "exp", "frexp", "hypot", "ldexp", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh"]
dir()
also includes locally defined variables, and that's an easy one. Just call...
local_variables
...unfortunately, we can't just add the local_variables
call to included_methods
because it would give us the variables that are local to the included_methods
method, and that wouldn't be very useful. So, if you want local variables included with the included_methods, just call...
(included_methods + local_variables).sort