irbrc for the runtime tramp
I’m taking a break from the Rubinius for the Layman series. I don’t know why my posts always spiral into multi-thousand words essays :-) Even worse, when I try to write about Rubinius it’s so easy to get into ratholes and start fiddling, poking at and exploring this wonderful beast. All of that instead of writing, of course.
Tonight’s fiddling led me to playing around with my .irbrc file. I guess we’ve all searched for examples of config files for IRB at one time or another. When you spend a lot of time into your interactive console, you naturally end up wanting to tweak it to your liking.
However you’ll start having problems as soon as you start fooling around with the different runtimes. Or when you share your irbrc between different machines. Maybe even on different OSes. Either some gems are unsupported or you haven’t installed them yet (and don’t necessarily care).
So tonight I tried to fix that problem. My solution is only a small method that I define in my irbrc, so I’m not sure it’s worth putting it on github yet :-) Let me know what you think.
Presenting tramp_require
Usage
When my irbrc requires something just so I don’t need to do it manually:
tramp_require 'pp' #=> true/false (same return value as a normal require)
Outcome if the gem is not installed:
** Unable to require 'wirble' --> LoadError: Did not find file to load: wirble
And you IRB loads without a problem (just without the gem pre-loaded).
When I require something I actually use in my .irbrc:
tramp_require('wirble') do Wirble.init(:skip_prompt=>true) Wirble.colorize end
If the gem is loaded successfully, the block is executed.
If the gem isn’t loaded successfully, the block’s not executed and the same warning message is shown.
Note that the user code passed in the block is not being rescued: if it your code fails, it’s your problem :-)
Implementation
Here I’ll paste 2 equivalent implementations. The first one is a clean and understandable version (also on pastie):
def tramp_require(what, &block) loaded, require_result = false, nil begin require_result = require what loaded = true rescue Exception => ex puts "** Unable to require '#{what}'" puts "--> #{ex.class}: #{ex.message}" end yield if loaded and block_given? require_result end
This second version is the one I actually use, if I set the debug variable to false the result is the same as the previous implementation. If I set it to true, I get much more information, including the full backtrace of the exception (also on pastie):
$debug_irbrc=false def tramp_require(what, &block) loaded, require_result = false, nil begin puts('', "requiring #{what}") if $debug_irbrc require_result = require what loaded = true puts "successfully required #{what}" if $debug_irbrc rescue Exception => ex puts "** Unable to require '#{what}'" exception_details = "#{ex.class}: #{ex.message}" if $debug_irbrc ex.backtrace.reverse.each{|l| exception_details < < "\n #{l}"} else exception_details.insert(0, "--> ") end puts exception_details end if loaded and block_given? puts "executing block for #{what}" if $debug_irbrc yield end require_result end
Feel free to use these snippets as you see fit :-)
The obligatory full paste of my irbrc is available on pastie, for the curious.
One word of warning, however. I’m guessing some of you will rename tramp_require to something more boring. Just don’t rename it to irb_require. IRB already defines a method named this way.