2 quick tips for IRB

In this article, we’re going to explore the following topics:

  • IRB.CurrentContext
  • Disable the output of the return value
  • Using the IRB tracer
  • Display the current context
Feel free to have a look to my new eBook: 📖RUBY OBJECT MODEL📖💎

Introduction

IRB is a pretty handy tool to quickly manipulate code gist. But sometimes, it becomes a bit complicated to use.

Fortunately, IRB is very customisable.

In the following article, we’re going to study 2 common examples that are very handy. Feel free to have a look to the links provided in the Conclusionsection for further information.

NB: The following examples are relevant with irb and the rails console.

IRB.CurrentContext

When we open an irb in the shell, an instance of IRB::Context is stored in the IRB.CurrentContext constant

irb> IRB.CurrentContext.class
=> IRB::Context
irb>

IRB::Context is in charge of wrapping the current state of an irb session.

To keep it simple, let’s focus on the fact that it contains a bunch of configurations.

Disable the output of the return value

By default, irb outputs the return value of the last executed instruction

irb> [1,2,3].map { |n| n * 2 }
=> [2, 4, 6]

The problem is that sometimes the return value is pretty big and pollutes the current irb session

rails_console> User.limit(10).each do |u|
p [u.id, u.first_name] if u.confirmed?
end
[1, "John"]
[3, "John"]
[5, "John"]
[7, "John"]
[9, "John"]
=> [#<User id: 1..>, #<User id: 2..>, #<User id: 3..>, #<User id: 4..>, #<User id: 5..>, #<User id: 6..>, #<User id: 7..>, #<User id: 8..>, #<User id: 9..>, #<User id: 10..>]

An old trick consists in forcing the last instruction to be blank

rails_console> User.limit(10).each do |u|
p [u.id, u.first_name] if u.confirmed?
end; nil
[1, "John"]
[3, "John"]
[5, "John"]
[7, "John"]
[9, "John"]
=> nil

Well, that’s a solution. But IRB::Context provides a way to temporarily disable the output of the return value. To do so, we can use the IRB::Context#echo flag

rails_console> IRB.CurrentContext.echo = false # disable
rails_console> User.limit(10).each do |u|
p [u.id, u.first_name] if u.confirmed?
end
[1, "John"]
[3, "John"]
[5, "John"]
[7, "John"]
[9, "John"]
rails_console> IRB.CurrentContext.echo = true # enable
=> true

Even if the IRB::Context#echo flag is disabled we can still retrieve the last instruction’s return value by using the IRB::Context#last_value method or the _ helper

rails_console> IRB.CurrentContext.echo = false # disable
rails_console> User.limit(10).each do |u|
p [u.id, u.first_name] if u.confirmed?
end
[1, "John"]
[3, "John"]
[5, "John"]
[7, "John"]
[9, "John"]
rails_console> p IRB.CurrentContext.last_value
[#<User id: 1..>, #<User id: 2..>, #<User id: 3..>, #<User id: 4..>, #<User id: 5..>, #<User id: 6..>, #<User id: 7..>, #<User id: 8..>, #<User id: 9..>, #<User id: 10..>]
rails_console> p _
[#<User id: 1..>, #<User id: 2..>, #<User id: 3..>, #<User id: 4..>, #<User id: 5..>, #<User id: 6..>, #<User id: 7..>, #<User id: 8..>, #<User id: 9..>, #<User id: 10..>]

Using the IRB tracer

When you’re not sure about what is called behind the scene, the IRB tracer can be very useful.

To enable the IRB tracer we can set the IRB::Context#use_tracer flag to true

rails_console> IRB.CurrentContext.use_tracer = true
=> true
rails_console> Rails.application
lib/rails.rb:36:Rails:>: def application
lib/rails.rb:37:Rails:-: @application ||= (app_class.instance if app_class)
lib/rails.rb:38:Rails:<: end
lib/rails/application.rb:363:Rails::Application:>: def config
lib/rails/application.rb:364:Rails::Application:-: @config ||= Application::Configuration.new(self.class.find_root(self.class.called_fro
lib/rails/application.rb:365:Rails::Application:<: end

The tracer traces and display all the methods implicitly called by the original statement.

Display the current context

The IRB.CurrentContext is updated (if necessary) after each evaluated statements. To look into the current context you can call p at any time

irb> p IRB.CurrentContext
conf.ap_name="irb"
conf.auto_indent_mode=true
conf.back_trace_limit=3
conf.debug_level=0
conf.echo=true
conf.ignore_eof=false
conf.ignore_sigint=true
...
irb>

Conclusion

IRB is a fully customisable REPL. I invite you to look into these 2 links for further information:

Voilà !


Thank you for taking the time to read this post :-)

Feel free to 👏 and share this Medium post if it has been useful for you.

Here is a link to my last medium post: Procs and Lambdas.