Get All Local Variables or Available Methods from Irb

Get all local variables or available methods from irb?

Look for methods in the Kernel, Object and Module : e.g. local_variables, instance_methods, instance_variables.

Other great methods in there. inspect is another one.

listing the local variables in irb

Your code is really complicated and obfuscated. First, let's clean up your code a bit so that we can see more clearly what's going on. You don't need self, since it is the default receiver anyway. And you don't need send, because you already know the name of the method you want to call. Also, Kernel#local_variables uses the current Binding anyway. Also, typically, such methods which are supposed to by called without an explicit receiver and don't actually make use of self (e.g. like puts or require) are put into Kernel. So, your code is equivalent to the following:

module Kernel
def list_vars
local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end

Now we can immediately see the problem: you are reflecting on the local variables and the Binding of list_vars and not the place where it was called from! You need to pass the Binding into the method and use that instead:

module Kernel
def list_vars(binding)
binding.local_variables.map {|var| "#{var} = " + binding.local_variable_get(var).inspect}
end
end

list_vars(binding)

Or, you could make it an instance method of Binding:

class Binding
def list_vars
local_variables.map {|var| "#{var} = " + local_variable_get(var).inspect}
end
end

binding.list_vars

How do you list the currently available objects in the current scope in 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?.

Why does load/require in irb not load local variables?

require/load is not the same as just copying and pasting the file into irb. You do run the file but files have their own scope in ruby. The local variable you create john is scoped to that file. That means when you define it it is available in the file but not outside it. This is a good feature to have: imagine you have a different file that creates a Dog class and assigns john = Dog.new. When you loaded that file it would change the assignment of john in your first file, breaking any code that depends on john being a person. Many Ruby programs contain hundreds of files -- you can imagine how this would be painful. It's the same thing when you have two methods

def method1
john = Dog.new
end

def method2
john = Person.new
method1()
puts john
end

We want to be able to define variables and do things with them without worrying the other code we call will change them. If you call method2 you'll see that john is still a Person. If calling other methods could change your local variables it would be very hard to reason about what was happening.

Local variables inside files are scoped only to those files just like local variables inside methods are scoped only to those methods. If you want to access them outside the file, just make them constants.

JOHN = Person.new

How can I access a variable defined in a Ruby file I required in IRB?

While it is true that you cannot access local variables defined in required files, you can access constants, and you can access anything stored in an object that you have access to in both contexts. So, there are a few ways to share information, depending on your goals.

The most common solution is probably to define a module and put your shared value in there. Since modules are constants, you'll be able to access it in the requiring context.

# in welcome.rb
module Messages
WELCOME = "hi there"
end

# in irb
puts Messages::WELCOME # prints out "hi there"

You could also put the value inside a class, to much the same effect. Alternatively, you could just define it as a constant in the file. Since the default context is an object of class Object, referred to as main, you could also define a method, instance variable, or class variable on main. All of these approaches end up being essentially different ways of making "global variables," more or less, and may not be optimal for most purposes. On the other hand, for small projects with very well defined scopes, they may be fine.

# in welcome.rb
WELCOME = "hi constant"
@welcome = "hi instance var"
@@welcome = "hi class var"
def welcome
"hi method"
end

# in irb
# These all print out what you would expect.
puts WELCOME
puts @welcome
puts @@welcome
puts welcome

Tab completion for methods in irb, which method is used?

Completion in IRb is provided by the irb/completion standard library, which is unfortunately undocumented. You can find the source for the case you are interested in here: https://GitHub.Com/Ruby/Ruby/blob/trunk/lib/irb/completion.rb#L149-195

How to escape scope in IRB?

You don't seem to be returning all the values from your method show_top_locals. Also, the call to Kernel#local_variables inside a method will only lookup local variables from the method scope. You should pass the binding from the place you are calling the method so that you get list of local variables at the place where method was invoked.

require "pp"

# For backward compatibility with Ruby 2.1 and below
def local_vars(binding)
if binding.respond_to? :local_variables
binding.local_variables
else
eval "Kernel.local_variables", binding
end
end

def show_top_locals(class_param, binding)
available_objects_array = ObjectSpace.each_object(class_param).to_a
local_variables_array = local_vars(binding).delete_if {|y| binding.eval(y.to_s).class != class_param}
local_variables_array_reversed = local_variables_array.reverse.map {|z| z.to_s}
objects_and_variables_array = local_variables_array_reversed.zip(available_objects_array).flatten.compact
return {
available_objs: available_objects_array,
local_vars: local_variables_array,
local_vars_reversed: local_variables_array_reversed,
objs_and_vars: objects_and_variables_array
}
end

class Foo
end

a = Foo.new
b = Foo.new

pp show_top_locals(Foo, binding)
#=> {:available_objs=>[#<Foo:0x000000027825b0>, #<Foo:0x000000027825d8>],
# :local_vars=>[:a, :b],
# :local_vars_reversed=>["b", "a"],
# :objs_and_vars=>["b", #<Foo:0x000000027825b0>, "a", #<Foo:0x000000027825d8>]}

You can place the method show_top_locals in a .rb file and refer to "Can you 'require' ruby file in irb session, automatically, on every command?" to autoload it in IRB.

How to list all the methods defined in top self Object in Ruby?

The closest I could find is to call private_methods on the main object, with false as argument

Returns the list of private methods accessible to obj. If the all
parameter is set to false, only those methods in the receiver will be
listed.

def foo
"foo"
end

def bar
"bar"
end

def baz
"baz"
end

p private_methods(false)
# [:include, :using, :public, :private, :define_method, :DelegateClass, :foo, :bar, :baz]

If you omit the argument, you also get all the private methods defined in Kernel or BasicObject.

In order to refine the list further, you could select the methods defined for Object:

p private_methods(false).select{|m| method(m).owner == Object}
#=> [:DelegateClass, :foo, :bar, :baz]

Only :DelegateClass is left, because it is defined in the top-level scope, just like :foo, :bar and :baz.



Related Topics



Leave a reply



Submit