<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
  <title>Tagaholic - Posts tagged 'ruby'</title>
 <link href="http://tagaholic.me/tag/ruby.xml" rel="self"/>
 <link href="http://tagaholic.me/"/>
 <updated>2013-09-13T11:46:24-07:00</updated>
 <id>http://tagaholic.me/</id>
 <author>
   <name>Gabriel Horner</name>
   <email>gabriel.horner@gmail.com</email>
 </author>
 
  
    
    
    
    
    
    
 <entry>
   <title>Tux - A Sinatra Console</title>
   <link href="http://tagaholic.me/2011/04/10/tux-a-sinatra-console.html"/>
   <updated>2011-04-10T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2011/04/10/tux-a-sinatra-console</id>
   <content type="html">&lt;p&gt;While working on a sinatra app recently, I noticed that &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;sinatra&lt;/a&gt; has no rails equivalent to rails console. So here&amp;#8217;s &lt;a href=&quot;http://github.com/cldwalker/tux&quot;&gt;tux&lt;/a&gt;, dressing your sinatra app in a console.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/post-sinatra.jpg&quot; alt=&quot;sinatra with a tux&quot; width=&quot;180&quot; height=&quot;240&quot;/&gt;&lt;/p&gt;
&lt;h2&gt;Install and Try On&lt;/h2&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ gem install tux
&lt;/pre&gt;&lt;p&gt;In the directory of your sinatra app, try on tux:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ tux

  # If app&#39;s rack config file isn&#39;t config.ru, specify it with -c
  $ tux -c app.ru

  # ruby options like -I and -r are available to tux
  $ tux -h
  Usage: tux [COMMAND] [ARGS] [OPTIONS]

  Options:
    -f                  Suppress loading ~/.irbrc
    -F                  Suppress loading ~/.riplrc
    -d, --debug         Set $DEBUG to true (same as `ruby -d&#39;)
    -I PATH             Add to front of $LOAD_PATH. Delimit multiple paths with &#39;:&#39;
    -r, --require FILE  Require file (same as `ruby -r&#39;)
    -v, --version       Print version
    -h, --help          Print help
    -c, --config FILE   Set rack config file i.e. config.ru
&lt;/pre&gt;&lt;h2 style=&quot;padding-top:30px;&quot;&gt;Interact with App Methods&lt;/h2&gt;
&lt;p&gt;Tux provides the &lt;code&gt;app&lt;/code&gt; object to interact with your app&amp;#8217;s methods. For example, to interact with helpers:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  &gt;&gt; app.my_helper_method
  ...
&lt;/pre&gt;&lt;p&gt;Since &lt;code&gt;app&lt;/code&gt; is an instance of &lt;code&gt;Sintra::Base&lt;/code&gt;, it can interact with any built-in sinatra methods i.e. request and response specific helper methods:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # depends on request
  &gt;&gt; app.uri &#39;/&#39;
  =&gt; &quot;http://:/&quot;

  # depends on response
  &gt;&gt; app.headers
  =&gt; {&quot;Content-Type&quot;=&gt;&quot;text/html&quot;}
&lt;/pre&gt;&lt;p&gt;For the above to work, tux sets up default empty request and response objects. To use custom requests and responses:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  &gt;&gt; app.request = Sinatra::Request.new({})
  =&gt; ...
  &gt;&gt; app.response = Sinatra::Response.new
  =&gt; ...
&lt;/pre&gt;&lt;p&gt;Last but not least, use &lt;code&gt;app&lt;/code&gt; to interact with views:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  &gt;&gt; app.erb :my_template
  =&gt; &#39;template rendered&#39;

  # also
  &gt;&gt; app.haml
  &gt;&gt; app.markdown
  ...
&lt;/pre&gt;&lt;h2 style=&quot;padding-top:30px;&quot;&gt;Interact with App Responses&lt;/h2&gt;
&lt;p&gt;Tux let&amp;#8217;s you make requests using http verbs thanks to &lt;a href=&quot;https://github.com/brynary/rack-test&quot;&gt;rack-test&lt;/a&gt;. Use them to interact with your app&amp;#8217;s response objects:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  &gt;&gt; get &#39;/&#39;
  =&gt; #&lt;\Rack::MockResponse:0x13d452c @headers={&quot;Content-Type&quot;=&gt;&quot;text/html;charset=utf-8&quot;,
  &quot;Content-Length&quot;=&gt;&quot;4&quot;}, @errors=&quot;127.0.0.1 - - [05/Apr/2011 02:22:27] \&quot;GET / \&quot; 200 4
  0.0015\n&quot;, @status=200, @original_headers={&quot;Content-Type&quot;=&gt;&quot;text/html;charset=utf-8&quot;,
  &quot;Content-Length&quot;=&gt;&quot;4&quot;}, @body=&quot;dude&quot;&gt;

  &gt;&gt; _.headers
  =&gt; {&quot;Content-Type&quot;=&gt;&quot;text/html;charset=utf-8&quot;, &quot;Content-Length&quot;=&gt;&quot;4&quot;}

  # last_response saves the response of your last request
  &gt;&gt; puts last_response.body
  dude

  &gt;&gt; post &#39;/create&#39;, :user =&gt; &#39;cow&#39;, :password =&gt; &#39;abunga&#39;
  ...
&lt;/pre&gt;&lt;p&gt;All http verb methods can take optional params and request headers as &lt;a href=&quot;https://github.com/brynary/rack-test/blob/2add7d87995b7e9e28560efb4ff65b43432e509e/lib/rack/test.rb#L55-58&quot;&gt;rack-test reveals&lt;/a&gt;. To see the full list of rack-test actions you can make:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  &gt;&gt; rack.actions
  =&gt; [:request, :get, :post, :put, :delete, :head, :follow_redirect!, :header, :set_cookie,
  :clear_cookies, :authorize, :basic_authorize, :digest_authorize, :last_response, :last_request]
&lt;/pre&gt;&lt;h2 style=&quot;padding-top:30px;&quot;&gt;Commands and Configuration&lt;/h2&gt;
&lt;p&gt;Tux comes with commands to give you a good overview of your app:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Displays routes defined by HTTP verb and order they were defined
  &gt;&gt; routes
  HEAD  &quot;/&quot;
  HEAD  &quot;/book/:id&quot;
  GET   &quot;/&quot;
  GET   &quot;/book/:id&quot;

  # Displays app settings configured via sinatra&#39;s #set method
  &gt;&gt; settings
  absolute_redirects  true
  add_charset         [/^text\//, &quot;application/javascript&quot;, &quot;application/xml&quot;,
  &quot;application/xhtml+xml&quot;]
  app_file            &quot;./sample.rb&quot;
  bind                &quot;0.0.0.0&quot;
  default_encoding    &quot;utf-8&quot;
  dump_errors         true
  empty_path_info     nil
  environment         :development
  lock                false
  logging             false
  method_override     false
  port                4567
  prefixed_redirects  false
  public              &quot;/my/path/public&quot;
  raise_errors        false
  reload_templates    true
  root                &quot;/my/path&quot;
  run                 false
  running             false
  server              [&quot;thin&quot;, &quot;mongrel&quot;, &quot;webrick&quot;]
  session_secret      &quot;XXX&quot;
  sessions            false
  show_exceptions     true
  static              true
  views               &quot;/my/path/views&quot;
&lt;/pre&gt;&lt;p&gt;Since tux is a &lt;a href=&quot;http://github.com/cldwalker/ripl&quot;&gt;ripl shell&lt;/a&gt;, tux is highly configurable. You can create tux commands in the format &lt;code&gt;tux-COMMAND&lt;/code&gt; and enhance your shell by adding ripl plugins to ~/.riplrc. Read &lt;a href=&quot;http://github.com/cldwalker/ripl#readme&quot;&gt;ripl&amp;#8217;s readme&lt;/a&gt; for more.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
 <entry>
   <title>One9 - Upgrade to Ruby 1.9 Now</title>
   <link href="http://tagaholic.me/2011/03/05/one9-upgrade-to-ruby-19-now.html"/>
   <updated>2011-03-05T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2011/03/05/one9-upgrade-to-ruby-19-now</id>
   <content type="html">&lt;p&gt;So &lt;a href=&quot;http://www.ruby-lang.org/en/downloads/&quot;&gt;ruby 1.9.2&lt;/a&gt; is the future and your still stuck on 1.8 at work.  Why? It&amp;#8217;s a pain &amp;#8230; Well, let&amp;#8217;s change that. Introducing &lt;a href=&quot;http://github.com/cldwalker/one9&quot;&gt;one9&lt;/a&gt; &amp;#8211; a gem to find 1.9 method changes and make the upgrade process smoother.&lt;/p&gt;
&lt;h2&gt;Install&lt;/h2&gt;
&lt;p&gt;No surprises here.&lt;br /&gt;
&lt;pre class=&quot;console&quot;&gt;
  gem install one9
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Well almost. If you&amp;#8217;re using bundler (the default in rails3), add one9 to your Gemfile if your&lt;br /&gt;
tests are invoked by bundler i.e. one9 test, one9 test rake * or one9 test bundle exec *.&lt;/p&gt;
&lt;h2&gt;How it works&lt;/h2&gt;
&lt;p&gt;one9 runs your 1.8 test suite, spies on methods that have changed and saves the locations of their calls&lt;br /&gt;
for later viewing. If you have a supported editor, it drops into an editor to let you sequentially&lt;br /&gt;
view and possibly fix each change. Although one9 gives you a brief message for each change, I&lt;br /&gt;
recommend familiarizing yourself with &lt;a href=&quot;http://eigenclass.org/hiki/Changes+in+Ruby+1.9&quot;&gt;1.9&lt;/a&gt; &lt;a href=&quot;https://github.com/ruby/ruby/raw/ruby_1_9_1/NEWS&quot;&gt;changes&lt;/a&gt;. To see what one9 knows about 1.9 changes:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ one9 changes
  +-----------------------------------+------------------------------------------------------------------+--------+
  | method                            | message                                                          | type   |
  +-----------------------------------+------------------------------------------------------------------+--------+
  | Module#constants                  | Returns array of symbols instead of array of strings             | change |
  | Module#public_methods             | Returns array of symbols instead of array of strings             | change |
  | Module#instance_methods           | Returns array of symbols instead of array of strings             | change |
  | Module#singleton_methods          | Returns array of symbols instead of array of strings             | change |
  | Module#public_instance_methods    | Returns array of symbols instead of array of strings             | change |
  | Module#protected_methods          | Returns array of symbols instead of array of strings             | change |
  ...
&lt;/pre&gt;&lt;h2&gt;Run tests&lt;/h2&gt;
&lt;p&gt;First off, run your tests in the root directory of a gem or Rails app:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Runs `rake test` by default
  $ one9 test

  # To run any other test command, just prefix it with one9 test:
  # Run all cucumber specs
  $ one9 test cucumber

  # Only run model specs
  $ one9 test rspec spec/models
&lt;/pre&gt;&lt;p&gt;After your tests run, one9 prints a report. Here&amp;#8217;s what it all looks like for &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ one9 test
  ...............................................................................................
  ...............................................................................................
  ...............................................................................................
  ...............
  Finished in 0.704555 seconds.

  300 tests, 580 assertions, 0 failures, 0 errors

  ** One9 Report **
  +---------------------------------+-------+--------------------------------------------------------------+--------+--------------------------------------------------------------+
  | method                          | count | message                                                      | type   | lines                                                        |
  +---------------------------------+-------+--------------------------------------------------------------+--------+--------------------------------------------------------------+
  | Module#instance_methods         | 5     | Returns array of symbols instead of array of strings         | change | lib/boson/util.rb:39:in `detect&#39;,lib/boson/util.rb:40:in ... |
  | Module#private_instance_methods | 2     | Returns array of symbols instead of array of strings         | change | lib/boson/inspectors/argument_inspector.rb:23:in `scrape_... |
  | Hash#to_s                       | 4     | An alias of #inspect instead of a spaceless join of the e... | change | lib/boson/loader.rb:87:in `initialize_library_module&#39;,lib... |
  | Hash#select                     | 4     | Returns a hash instead of an association array               | change | lib/boson/loader.rb:109:in `set_library_commands&#39;,lib/bos... |
  +---------------------------------+-------+--------------------------------------------------------------+--------+--------------------------------------------------------------+
  4 rows in set
&lt;/pre&gt;&lt;p&gt;As you can see the report lists changed methods, how many times they were&lt;br /&gt;
called and where they were called from. To reprint this list any time later, run &lt;code&gt;one9 list&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note: When you run &lt;code&gt;one9 test&lt;/code&gt; it &lt;em&gt;overwrites&lt;/em&gt; the previous &lt;code&gt;one test&lt;/code&gt; result.&lt;/p&gt;
&lt;h2&gt;Edit Changes&lt;/h2&gt;
&lt;p&gt;Now that you have a list of changed method calls, editing those changes is easy:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Open all changes
  $ one9 edit

  # To only open a subset of changes:
  # Only open Hash changes
  $ one9 edit Hash

  # Only open Hash#to_s changes
  $ one9 edit Hash#to_s
&lt;/pre&gt;&lt;p&gt;Currently this opens the quickfix list in vim. (For vim noobs, navigate between changes with &lt;code&gt;:cn&lt;/code&gt;&lt;br /&gt;
and &lt;code&gt;:cp&lt;/code&gt;.) &lt;a href=&quot;https://github.com/cldwalker/one9/pulls&quot;&gt;Patches&lt;/a&gt; for emacs and other editors welcome :)&lt;br /&gt;
Remember each change is a &lt;strong&gt;possible&lt;/strong&gt; change. Only change the code if the new 1.9 behavior is going&lt;br /&gt;
to break the existing code.&lt;/p&gt;
&lt;p&gt;For those without editing support, you can still view each line where there&amp;#8217;s a method change:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ one9 lines
  +---------------------------------+---------------------------------------------------------------------+
  | method                          | line                                                                |
  +---------------------------------+---------------------------------------------------------------------+
  | Module#instance_methods         | lib/boson/util.rb:39:in `detect&#39;                                    |
  | Module#instance_methods         | lib/boson/util.rb:40:in `detect&#39;                                    |
  | Module#instance_methods         | lib/boson/loader.rb:101:in `check_for_method_conflicts&#39;             |
  | Module#instance_methods         | lib/boson/util.rb:44:in `detect&#39;                                    |
  | Module#instance_methods         | lib/boson/namespace.rb:28:in `boson_commands&#39;                       |
  ...
&lt;/pre&gt;&lt;p&gt;Once you&amp;#8217;ve fixed your changes, give your code a 1.9 test run. If tests are still broken, then jump&lt;br /&gt;
down to &lt;a href=&quot;#additional_changes&quot;&gt;this section&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Rails Tips&lt;/h2&gt;
&lt;p&gt;Skip this section if you&amp;#8217;re not on a Rails app.&lt;/p&gt;
&lt;p&gt;So you&amp;#8217;ve finished editing your code and tests pass. You&amp;#8217;re done, right? Not in my opinion. My code&lt;br /&gt;
is only as good as the code it depends on. I&amp;#8217;d check each of my app&amp;#8217;s dependencies and check for any&lt;br /&gt;
1.9 breakages. For each gem:&lt;/p&gt;
&lt;p&gt;1. cd to the gem: &lt;code&gt;cd `bundle show $GEM`&lt;/code&gt;&lt;br /&gt;
2. Install the gem&amp;#8217;s development dependencies: &lt;code&gt;gem install $GEM --dev&lt;/code&gt;&lt;br /&gt;
3. Run tests with one9: &lt;code&gt;one9 test WITH PROPER COMMAND&lt;/code&gt;&lt;br /&gt;
4. Edit gem&amp;#8217;s changes : &lt;code&gt;one9 edit&lt;/code&gt;&lt;br /&gt;
5. Verify tests pass on 1.9.&lt;br /&gt;
6. Fork, patch, pull as needed&lt;/p&gt;
&lt;h2&gt;Configure&lt;/h2&gt;
&lt;p&gt;one9 comes with a decent list of 1.9 changes and descriptions. If you&amp;#8217;d like to add your&lt;br /&gt;
own changes, add them to your ~/.one9rc. For example:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # For methods that have changed in 1.9
  change &#39;Class#instance_method&#39;, &#39;Some description&#39;

  # For methods that have been deleted in 1.9
  delete &#39;Class.class_method&#39;, &#39;Some description&#39;
&lt;/pre&gt;&lt;p&gt;For more examples, &lt;a href=&quot;https://github.com/cldwalker/one9/blob/master/lib/one9/defaults.rb&quot;&gt;see the defaults that one9 defines&lt;/a&gt;. If I&amp;#8217;ve missed an important 1.9 change, &lt;a href=&quot;https://github.com/cldwalker/one9/pulls&quot;&gt;feel free to fork and pull&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;additional_changes&quot;&gt;&lt;a href=&quot;#additional_changes&quot;&gt;Additional 1.9 Changes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So even if you&amp;#8217;ve dealt with all changed methods, there are still other changes that could effect your code:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Encoding: Probably the most significant and thus well documented. See &lt;a href=&quot;http://blog.grayproductions.net/articles/understanding_m17n&quot;&gt;JEG&amp;#8217;s thorough articles&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://dablog.rubypal.com/2009/1/14/10-things-to-be-aware-of-in-moving-to-ruby-1-9&quot;&gt;scoping of block variables, splat operator and block arguments&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;files in &lt;code&gt;$LOAD_PATH&lt;/code&gt; and &lt;code&gt;$LOADED_FEATURES&lt;/code&gt; are expanded&lt;/li&gt;
	&lt;li&gt;using colon (:) instead of &amp;#8220;then&amp;#8221; in an if/unless/case is deprecated&lt;/li&gt;
	&lt;li&gt;retry in a loop or iterator is deprecated&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;$KCODE&lt;/code&gt;, &lt;code&gt;$=&lt;/code&gt; and &lt;code&gt;VERSION*&lt;/code&gt; constants are deprecated&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;?x&lt;/code&gt; now returns a single character string instead of an integer&lt;/li&gt;
	&lt;li&gt;For anything I may have missed see &lt;a href=&quot;https://github.com/ruby/ruby/raw/ruby_1_9_1/NEWS&quot;&gt;the official changelog&lt;/a&gt; or the &lt;a href=&quot;http://eigenclass.org/hiki/Changes+in+Ruby+1.9&quot;&gt;unoffical one&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Motivation&lt;/h2&gt;
&lt;p&gt;This gem aims to get the ruby community to seriously use 1.9.2 and to port as many of the 1.8 gems&lt;br /&gt;
to 1.9. Since this gem maintains a list of 1.9 changes, it could be used as a multi-purpose tool.&lt;br /&gt;
Some ideas for future commands:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;grep command to grep code for changed methods. Basically for porting test-deprived code.&lt;/li&gt;
	&lt;li&gt;info command to explain a method&amp;#8217;s change in detail with examples and possible solutions&lt;/li&gt;
	&lt;li&gt;rails command to ease porting a rails app and all its dependencies.&lt;/li&gt;
	&lt;li&gt;automating code changes like &lt;a href=&quot;http://docs.python.org/py3k/library/2to3.html&quot;&gt;python&amp;#8217;s 2to3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;#8217;re interested in implementing these or other such commands, &lt;a href=&quot;https://github.com/cldwalker/one9/pulls&quot;&gt;please do contribute&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Ruby 1.9.2 isn&amp;#8217;t the future, it&amp;#8217;s already here. So why are you waiting?&lt;/p&gt;</content>
 </entry>
    
    
    
 <entry>
   <title>One9 - Upgrade to Ruby 1.9 Now</title>
   <link href="http://tagaholic.me/2011/03/05/one9-upgrade-to-ruby-19-now.html"/>
   <updated>2011-03-05T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2011/03/05/one9-upgrade-to-ruby-19-now</id>
   <content type="html">&lt;p&gt;So &lt;a href=&quot;http://www.ruby-lang.org/en/downloads/&quot;&gt;ruby 1.9.2&lt;/a&gt; is the future and your still stuck on 1.8 at work.  Why? It&amp;#8217;s a pain &amp;#8230; Well, let&amp;#8217;s change that. Introducing &lt;a href=&quot;http://github.com/cldwalker/one9&quot;&gt;one9&lt;/a&gt; &amp;#8211; a gem to find 1.9 method changes and make the upgrade process smoother.&lt;/p&gt;
&lt;h2&gt;Install&lt;/h2&gt;
&lt;p&gt;No surprises here.&lt;br /&gt;
&lt;pre class=&quot;console&quot;&gt;
  gem install one9
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Well almost. If you&amp;#8217;re using bundler (the default in rails3), add one9 to your Gemfile if your&lt;br /&gt;
tests are invoked by bundler i.e. one9 test, one9 test rake * or one9 test bundle exec *.&lt;/p&gt;
&lt;h2&gt;How it works&lt;/h2&gt;
&lt;p&gt;one9 runs your 1.8 test suite, spies on methods that have changed and saves the locations of their calls&lt;br /&gt;
for later viewing. If you have a supported editor, it drops into an editor to let you sequentially&lt;br /&gt;
view and possibly fix each change. Although one9 gives you a brief message for each change, I&lt;br /&gt;
recommend familiarizing yourself with &lt;a href=&quot;http://eigenclass.org/hiki/Changes+in+Ruby+1.9&quot;&gt;1.9&lt;/a&gt; &lt;a href=&quot;https://github.com/ruby/ruby/raw/ruby_1_9_1/NEWS&quot;&gt;changes&lt;/a&gt;. To see what one9 knows about 1.9 changes:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ one9 changes
  +-----------------------------------+------------------------------------------------------------------+--------+
  | method                            | message                                                          | type   |
  +-----------------------------------+------------------------------------------------------------------+--------+
  | Module#constants                  | Returns array of symbols instead of array of strings             | change |
  | Module#public_methods             | Returns array of symbols instead of array of strings             | change |
  | Module#instance_methods           | Returns array of symbols instead of array of strings             | change |
  | Module#singleton_methods          | Returns array of symbols instead of array of strings             | change |
  | Module#public_instance_methods    | Returns array of symbols instead of array of strings             | change |
  | Module#protected_methods          | Returns array of symbols instead of array of strings             | change |
  ...
&lt;/pre&gt;&lt;h2&gt;Run tests&lt;/h2&gt;
&lt;p&gt;First off, run your tests in the root directory of a gem or Rails app:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Runs `rake test` by default
  $ one9 test

  # To run any other test command, just prefix it with one9 test:
  # Run all cucumber specs
  $ one9 test cucumber

  # Only run model specs
  $ one9 test rspec spec/models
&lt;/pre&gt;&lt;p&gt;After your tests run, one9 prints a report. Here&amp;#8217;s what it all looks like for &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ one9 test
  ...............................................................................................
  ...............................................................................................
  ...............................................................................................
  ...............
  Finished in 0.704555 seconds.

  300 tests, 580 assertions, 0 failures, 0 errors

  ** One9 Report **
  +---------------------------------+-------+--------------------------------------------------------------+--------+--------------------------------------------------------------+
  | method                          | count | message                                                      | type   | lines                                                        |
  +---------------------------------+-------+--------------------------------------------------------------+--------+--------------------------------------------------------------+
  | Module#instance_methods         | 5     | Returns array of symbols instead of array of strings         | change | lib/boson/util.rb:39:in `detect&#39;,lib/boson/util.rb:40:in ... |
  | Module#private_instance_methods | 2     | Returns array of symbols instead of array of strings         | change | lib/boson/inspectors/argument_inspector.rb:23:in `scrape_... |
  | Hash#to_s                       | 4     | An alias of #inspect instead of a spaceless join of the e... | change | lib/boson/loader.rb:87:in `initialize_library_module&#39;,lib... |
  | Hash#select                     | 4     | Returns a hash instead of an association array               | change | lib/boson/loader.rb:109:in `set_library_commands&#39;,lib/bos... |
  +---------------------------------+-------+--------------------------------------------------------------+--------+--------------------------------------------------------------+
  4 rows in set
&lt;/pre&gt;&lt;p&gt;As you can see the report lists changed methods, how many times they were&lt;br /&gt;
called and where they were called from. To reprint this list any time later, run &lt;code&gt;one9 list&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note: When you run &lt;code&gt;one9 test&lt;/code&gt; it &lt;em&gt;overwrites&lt;/em&gt; the previous &lt;code&gt;one test&lt;/code&gt; result.&lt;/p&gt;
&lt;h2&gt;Edit Changes&lt;/h2&gt;
&lt;p&gt;Now that you have a list of changed method calls, editing those changes is easy:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Open all changes
  $ one9 edit

  # To only open a subset of changes:
  # Only open Hash changes
  $ one9 edit Hash

  # Only open Hash#to_s changes
  $ one9 edit Hash#to_s
&lt;/pre&gt;&lt;p&gt;Currently this opens the quickfix list in vim. (For vim noobs, navigate between changes with &lt;code&gt;:cn&lt;/code&gt;&lt;br /&gt;
and &lt;code&gt;:cp&lt;/code&gt;.) &lt;a href=&quot;https://github.com/cldwalker/one9/pulls&quot;&gt;Patches&lt;/a&gt; for emacs and other editors welcome :)&lt;br /&gt;
Remember each change is a &lt;strong&gt;possible&lt;/strong&gt; change. Only change the code if the new 1.9 behavior is going&lt;br /&gt;
to break the existing code.&lt;/p&gt;
&lt;p&gt;For those without editing support, you can still view each line where there&amp;#8217;s a method change:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ one9 lines
  +---------------------------------+---------------------------------------------------------------------+
  | method                          | line                                                                |
  +---------------------------------+---------------------------------------------------------------------+
  | Module#instance_methods         | lib/boson/util.rb:39:in `detect&#39;                                    |
  | Module#instance_methods         | lib/boson/util.rb:40:in `detect&#39;                                    |
  | Module#instance_methods         | lib/boson/loader.rb:101:in `check_for_method_conflicts&#39;             |
  | Module#instance_methods         | lib/boson/util.rb:44:in `detect&#39;                                    |
  | Module#instance_methods         | lib/boson/namespace.rb:28:in `boson_commands&#39;                       |
  ...
&lt;/pre&gt;&lt;p&gt;Once you&amp;#8217;ve fixed your changes, give your code a 1.9 test run. If tests are still broken, then jump&lt;br /&gt;
down to &lt;a href=&quot;#additional_changes&quot;&gt;this section&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Rails Tips&lt;/h2&gt;
&lt;p&gt;Skip this section if you&amp;#8217;re not on a Rails app.&lt;/p&gt;
&lt;p&gt;So you&amp;#8217;ve finished editing your code and tests pass. You&amp;#8217;re done, right? Not in my opinion. My code&lt;br /&gt;
is only as good as the code it depends on. I&amp;#8217;d check each of my app&amp;#8217;s dependencies and check for any&lt;br /&gt;
1.9 breakages. For each gem:&lt;/p&gt;
&lt;p&gt;1. cd to the gem: &lt;code&gt;cd `bundle show $GEM`&lt;/code&gt;&lt;br /&gt;
2. Install the gem&amp;#8217;s development dependencies: &lt;code&gt;gem install $GEM --dev&lt;/code&gt;&lt;br /&gt;
3. Run tests with one9: &lt;code&gt;one9 test WITH PROPER COMMAND&lt;/code&gt;&lt;br /&gt;
4. Edit gem&amp;#8217;s changes : &lt;code&gt;one9 edit&lt;/code&gt;&lt;br /&gt;
5. Verify tests pass on 1.9.&lt;br /&gt;
6. Fork, patch, pull as needed&lt;/p&gt;
&lt;h2&gt;Configure&lt;/h2&gt;
&lt;p&gt;one9 comes with a decent list of 1.9 changes and descriptions. If you&amp;#8217;d like to add your&lt;br /&gt;
own changes, add them to your ~/.one9rc. For example:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # For methods that have changed in 1.9
  change &#39;Class#instance_method&#39;, &#39;Some description&#39;

  # For methods that have been deleted in 1.9
  delete &#39;Class.class_method&#39;, &#39;Some description&#39;
&lt;/pre&gt;&lt;p&gt;For more examples, &lt;a href=&quot;https://github.com/cldwalker/one9/blob/master/lib/one9/defaults.rb&quot;&gt;see the defaults that one9 defines&lt;/a&gt;. If I&amp;#8217;ve missed an important 1.9 change, &lt;a href=&quot;https://github.com/cldwalker/one9/pulls&quot;&gt;feel free to fork and pull&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;additional_changes&quot;&gt;&lt;a href=&quot;#additional_changes&quot;&gt;Additional 1.9 Changes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So even if you&amp;#8217;ve dealt with all changed methods, there are still other changes that could effect your code:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Encoding: Probably the most significant and thus well documented. See &lt;a href=&quot;http://blog.grayproductions.net/articles/understanding_m17n&quot;&gt;JEG&amp;#8217;s thorough articles&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://dablog.rubypal.com/2009/1/14/10-things-to-be-aware-of-in-moving-to-ruby-1-9&quot;&gt;scoping of block variables, splat operator and block arguments&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;files in &lt;code&gt;$LOAD_PATH&lt;/code&gt; and &lt;code&gt;$LOADED_FEATURES&lt;/code&gt; are expanded&lt;/li&gt;
	&lt;li&gt;using colon (:) instead of &amp;#8220;then&amp;#8221; in an if/unless/case is deprecated&lt;/li&gt;
	&lt;li&gt;retry in a loop or iterator is deprecated&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;$KCODE&lt;/code&gt;, &lt;code&gt;$=&lt;/code&gt; and &lt;code&gt;VERSION*&lt;/code&gt; constants are deprecated&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;?x&lt;/code&gt; now returns a single character string instead of an integer&lt;/li&gt;
	&lt;li&gt;For anything I may have missed see &lt;a href=&quot;https://github.com/ruby/ruby/raw/ruby_1_9_1/NEWS&quot;&gt;the official changelog&lt;/a&gt; or the &lt;a href=&quot;http://eigenclass.org/hiki/Changes+in+Ruby+1.9&quot;&gt;unoffical one&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Motivation&lt;/h2&gt;
&lt;p&gt;This gem aims to get the ruby community to seriously use 1.9.2 and to port as many of the 1.8 gems&lt;br /&gt;
to 1.9. Since this gem maintains a list of 1.9 changes, it could be used as a multi-purpose tool.&lt;br /&gt;
Some ideas for future commands:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;grep command to grep code for changed methods. Basically for porting test-deprived code.&lt;/li&gt;
	&lt;li&gt;info command to explain a method&amp;#8217;s change in detail with examples and possible solutions&lt;/li&gt;
	&lt;li&gt;rails command to ease porting a rails app and all its dependencies.&lt;/li&gt;
	&lt;li&gt;automating code changes like &lt;a href=&quot;http://docs.python.org/py3k/library/2to3.html&quot;&gt;python&amp;#8217;s 2to3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;#8217;re interested in implementing these or other such commands, &lt;a href=&quot;https://github.com/cldwalker/one9/pulls&quot;&gt;please do contribute&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Ruby 1.9.2 isn&amp;#8217;t the future, it&amp;#8217;s already here. So why are you waiting?&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
    
    
 <entry>
   <title>Documentation-Generated Irb Autocompletions With Bond and Yard</title>
   <link href="http://tagaholic.me/2010/05/19/documentation-generated-irb-autocompletions-with-bond-and-yard.html"/>
   <updated>2010-05-19T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2010/05/19/documentation-generated-irb-autocompletions-with-bond-and-yard</id>
   <content type="html">&lt;p&gt;Since it&amp;#8217;s &lt;a href=&quot;/2010/05/07/screencast-of-argument-autocompletion-for-methods-in-irb.html&quot;&gt;last release&lt;/a&gt;, &lt;a href=&quot;http://github.com/cldwalker/bond&quot;&gt;bond&lt;/a&gt; has gained a number of features. The most novel of these is the ability to generate gem-specific autocompletions from a gem&amp;#8217;s &lt;a href=&quot;http://yardoc.org&quot;&gt;yard documentation&lt;/a&gt;. This release also lets &lt;a href=&quot;#gems_with_custom_autocompletions&quot;&gt;gems ship with their own irb autocompletions&lt;/a&gt; and introduces bond to &lt;a href=&quot;#emacs_inf_ruby&quot;&gt;emacs&amp;#8217; inf-ruby mode&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;yard_based_irb_autocompletions&quot;&gt;&lt;a href=&quot;#yard_based_irb_autocompletions&quot;&gt;Yard-Based Irb Autocompletions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Yard functionality has been moved to &lt;a href=&quot;http://github.com/cldwalker/bond-yard&quot;&gt;bond-yard&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This feature generates autocompletions for a gem&amp;#8217;s methods from a gem&amp;#8217;s yard documentation. The only arguments it currently autocompletes are hash keys for a hash argument that has been documented with @option. Let&amp;#8217;s take a look:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ gem install bond yard bond-yard

  $ irb
  &gt;&gt; require &#39;bond&#39;; Bond.start
  =&gt; true

  # Load autocompletions for yard methods
  &gt;&gt; Bond.load_yard_gems &#39;yard&#39;
  Bond: Building/loading yard&#39;s .yardoc database ...
  =&gt; [&quot;yard&quot;]

  # Let&#39;s see what yard methods we can autocomplete
  &gt;&gt; Bond.list_methods.grep /YARD/
  =&gt; [&quot;YARD::CodeObjects::Base#format&quot;, &quot;YARD::CodeObjects::ClassObject#constants&quot;, &quot;YARD::CodeObjects::ClassObject#meths&quot;,   
  &quot;YARD::CodeObjects::NamespaceObject#constants&quot;, &quot;YARD::CodeObjects::NamespaceObject#included_meths&quot;, 
  &quot;YARD::CodeObjects::NamespaceObject#meths&quot;, &quot;YARD::Serializers::FileSystemSerializer.new&quot;, &quot;YARD::Templates::Engine.render&quot;, 
  &quot;YARD::Templates::Engine.set_default_options&quot;]

  # Trying one of the above
  &gt;&gt; YARD::Templates::Engine.render :[TAB]
  :format    :template  :type
  &gt;&gt; YARD::Templates::Engine.render :f[TAB]
  &gt;&gt; YARD::Templates::Engine.render :format=&gt;:html, :te[TAB]
  &gt;&gt; YARD::Templates::Engine.render :format=&gt;:html, :template
  # ...
&lt;/pre&gt;&lt;p&gt;Are there any other gems besides yard that use yard documentation? Sure:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # gem install spidr
  &gt;&gt; Bond.load_yard_gems &#39;spidr&#39;
  Bond: Building/loading spidr&#39;s .yardoc database ...
  =&gt; [&quot;spidr&quot;]
  &gt;&gt; require &#39;spidr&#39;
  =&gt; true

  &gt;&gt; Spidr::Agent.new :h[TAB]
  :history       :host          :host_header   :host_headers
  &gt;&gt; Spidr::Agent.new :hi[TAB]
  &gt;&gt; Spidr::Agent.new :history
  # ...

  # gem install haml
  &gt;&gt; Bond.load_yard_gems &#39;haml&#39;
  Bond: Building/loading haml&#39;s .yardoc database ...
  =&gt; [&quot;haml&quot;]
  &gt;&gt; require &#39;haml/html&#39;
  =&gt; true

  &gt;&gt; Haml::HTML.new :[TAB]
  :erb     :xhtml
  &gt;&gt; Haml::HTML.new :x[TAB]
  &gt;&gt; Haml::HTML.new :xhtml
  # ...

  # gem install rdf
  &gt;&gt; Bond.load_yard_gems &#39;rdf&#39;
  Bond: Building/loading rdf&#39;s .yardoc database ...
  =&gt; [&quot;rdf&quot;]
  &gt;&gt; require &#39;rdf&#39;
  =&gt; true

  &gt;&gt; RDF::Repository.new :[TAB]
  :title   :uri
  &gt;&gt; RDF::Repository.new :t[TAB]
  &gt;&gt; RDF::Repository.new :title
  # ...
&lt;/pre&gt;&lt;p&gt;For more gems that use yard documentation, &lt;a href=&quot;http://wiki.github.com/lsegal/yard/whos-using-yard&quot;&gt;see here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;gems_with_custom_autocompletions&quot;&gt;&lt;a href=&quot;#gems_with_custom_autocompletions&quot;&gt;Gems with Custom Autocompletions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If your gem doesn&amp;#8217;t use yard documentation, no worries. You can still ship your gems with custom autocompletions. Completion files are  under lib/bond/completions/ which is relative your gem&amp;#8217;s base directory. For the format of a completion file, &lt;a href=&quot;http://tagaholic.me/bond/doc/classes/Bond/Rc.html&quot;&gt;see here&lt;/a&gt;. For an example of a gem that ships with autocompletions, let&amp;#8217;s use &lt;a href=&quot;/2009/03/13/hirb-irb-on-the-good-stuff.html&quot;&gt;hirb&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Install latest hirb
  $ gem install hirb

  $ irb
  &gt;&gt; require &#39;bond&#39;; Bond.start
  =&gt; true
  &gt;&gt; Bond.load_gems &#39;hirb&#39;
  =&gt; [&quot;hirb&quot;]
  &gt;&gt; require &#39;hirb&#39;
  =&gt; true

  # Autocomplete all options to hirb&#39;s tables
  &gt;&gt; puts Hirb::Helpers::AutoTable.render [1,2,3], :[TAB]
  :all_fields            :filter_any            :hide_empty            :table_class
  :change_fields         :filter_classes        :max_fields            :vertical
  :description           :filters               :max_width             
  :escape_special_chars  :header_filter         :number                
  :fields                :headers               :resize                
  &gt;&gt; puts Hirb::Helpers::AutoTable.render [1,2,3], :d[TAB]
  &gt;&gt; puts Hirb::Helpers::AutoTable.render [1,2,3], :description
  # ...

  # Let&#39;s use hirb&#39;s console methods
  &gt;&gt; extend Hirb::Console
  =&gt; main

  # Autocomplete all options to hirb&#39;s menus
  &gt;&gt; menu [1,2,3], :[TAB]
  :action         :command        :helper_class   :readline       
  :action_object  :default_field  :multi_action   :two_d          
  :ask            :directions     :prompt         
  &gt;&gt; menu [1,2,3], :p[TAB]
  &gt;&gt; menu [1,2,3], :prompt
  # ...

  # If you want to have gem completions defined at start up, just pass :gems to Bond.start.
  # Bond.start :gems=&gt;%w{hirb}
&lt;/pre&gt;&lt;p&gt;Since this is the initial release of this feature, probably no other gems ship with bond&amp;#8217;s irb autocompletions. So what can you do if you want to autocomplete your favorite gem&amp;#8217;s methods? Just make your own completion files under ~/.bond/completions/. If you want to share your favorite gem&amp;#8217;s completions with others, fork the gem, copy your completion file(s) to the gem&amp;#8217;s lib/bond/completions/ directory and send the patch to the author.&lt;/p&gt;
&lt;h2 id=&quot;emacs_inf_ruby&quot;&gt;&lt;a href=&quot;#emacs_inf_ruby&quot;&gt;Emacs Inf-Ruby and Bond&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bond can be used within emacs&amp;#8217; inf-ruby mode thanks to &lt;a href=&quot;http://github.com/pd/inf-ruby-bond&quot;&gt;pd&amp;#8217;s inf-ruby-bond&lt;/a&gt;. Since I don&amp;#8217;t use emacs, I won&amp;#8217;t try to go into an example. If any vim gurus are listening, a vim plugin to use bond within vim would be awesome :).&lt;/p&gt;
&lt;h2 id=&quot;final_thoughts&quot;&gt;&lt;a href=&quot;#final_thoughts&quot;&gt;Final Thoughts&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Although the idea of creating autocompletion functionality from documentation &lt;a href=&quot;http://limpet.net/mbrubeck/2009/10/30/compleat.html&quot;&gt;isn&amp;#8217;t new&lt;/a&gt;, &lt;a href=&quot;http://tagaholic.me/bond&quot;&gt;bond&lt;/a&gt; is probably the first to do so among ruby gems. This isn&amp;#8217;t anything too special given that bond currently only autocompletes hash keys of hash arguments.  But with yard&amp;#8217;s &lt;a href=&quot;http://yardoc.org/docs/yard/YARD/CodeObjects/MethodObject:parameters&quot;&gt;excellent api&lt;/a&gt;, there isn&amp;#8217;t anything stopping a future release from autocompleting any arguments to a method!&lt;/p&gt;
&lt;p&gt;Although &lt;a href=&quot;http://yardoc.org&quot;&gt;yard&lt;/a&gt; isn&amp;#8217;t currently the commonly used documentation tool in the ruby world, this post shows the benefits it provides by letting gem authors easily associate meta-data per method. Yard makes it possible to ask: what gem-specific functionality can someone build from gem&amp;#8217;s documentation? Bond&amp;#8217;s irb autocompletions is one such answer. Perhaps in a future post another answer will be &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&amp;#8217;s&lt;/a&gt; ability to make a command from any documented method and its options.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>Screencast Of Argument Autocompletion for Methods in Irb</title>
   <link href="http://tagaholic.me/2010/05/07/screencast-of-argument-autocompletion-for-methods-in-irb.html"/>
   <updated>2010-05-07T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2010/05/07/screencast-of-argument-autocompletion-for-methods-in-irb</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://github.com/cldwalker/bond&quot;&gt;Bond&lt;/a&gt;, a gem to improve irb&amp;#8217;s autocompletion, just hit &lt;a href=&quot;http://github.com/cldwalker/bond/blob/master/CHANGELOG.rdoc&quot;&gt;version 0.2.0&lt;/a&gt;. With this version comes a completion configuration system similar to bash/zsh, more fixes to irb&amp;#8217;s incorrect completions and most importantly, &lt;b&gt;any method&lt;/b&gt; can have its arguments autocompleted! The screencast demonstrates most of this.&lt;/p&gt;
&lt;h2&gt;Screencast&lt;/h2&gt;
&lt;p&gt;&lt;object width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=11547817&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1&quot; /&gt;&lt;embed src=&quot;http://vimeo.com/moogaloop.swf?clip_id=11547817&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href=&quot;http://vimeo.com/11547817&quot;&gt;Bond &amp;#8211; Argument Autocompletion for Methods in Irb&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/user1889677&quot;&gt;cldwalker&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;h2&gt;Screencast Notes&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;Bond.list_methods&lt;/code&gt;: Lists all methods (80+) that have argument autocompletion.&lt;/li&gt;
	&lt;li&gt;Examples of methods with argument completion: &lt;code&gt;Kernel#require, Array#delete, Hash#[], Module#const_get, Object#instance_variable_get&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;Object#send&lt;/code&gt;: Exemplifies an argument completion that varies per argument. Can be used to invoke argument completions for private methods.&lt;/li&gt;
	&lt;li&gt;Rails examples: &lt;code&gt;ActiveRecord::Base.attr_accessible, ActiveRecord::Base.create, ActiveRecord::Base.where, ActiveRecord::Base.all&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;Basic argument completion example: &lt;code&gt;Bond.complete(:method=&amp;gt;&quot;Array#jump&quot;) { %w{foo bar baz} }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Install&lt;/h2&gt;
&lt;p&gt;Install the gem with:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
    sudo gem install bond
&lt;/pre&gt;&lt;p&gt;In your irbrc, replace irb&amp;#8217;s completion (require &amp;#8216;irb/completion&amp;#8217;) with :&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  require &#39;bond&#39;
  Bond.start
  #Bond.start replaces require &#39;bond/completion&#39; from previous bond versions
&lt;/pre&gt;&lt;p&gt;If using wirble, place the above after wirble.&lt;/p&gt;
&lt;h2&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/cldwalker/bond#readme&quot;&gt;The &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt;&lt;/a&gt; contains a thorough introduction to Bond and a section on irb&amp;#8217;s incorrect autocompletions.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://tagaholic.me/bond/doc/&quot;&gt;Official documentation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://tagaholic.me/bond/&quot;&gt;Official homepage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>Lightning - Speed For The User</title>
   <link href="http://tagaholic.me/2010/04/09/lightning-speed-for-the-user.html"/>
   <updated>2010-04-09T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2010/04/09/lightning-speed-for-the-user</id>
   <content type="html">&lt;p&gt;The &lt;a href=&quot;/2010/04/08/lightning-speed-for-your-shell.html&quot;&gt;previous post&lt;/a&gt; explained what &lt;a href=&quot;http://github.com/cldwalker/lightning&quot;&gt;lightning&lt;/a&gt; does. This post explains how you, the user, can use and customize lightning to speed up your commandline experience.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#default_functions&quot;&gt;Default Functions&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#create_and_delete_functions&quot;&gt;Create and Delete Functions&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#aliases&quot;&gt;Aliases&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#creating_your_own_bolt&quot;&gt;Creating Your Own Bolt&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#generating_bolts&quot;&gt;Generating Bolts&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#misc&quot;&gt;Miscellaneous&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;default_functions&quot;&gt;&lt;a href=&quot;#default_functions&quot;&gt;Default Functions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After having &lt;a href=&quot;/2010/04/08/lightning-speed-for-your-shell.html#install&quot;&gt;installed lightning&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # We&#39;ll use these aliases throughout this post
  $ alias lg=lightning
  $ alias lgr=lightning-reload

  # List available commands
  $ lg -h
  # ...

  # List default functions generated from install
  $ lg function
  cd-gem
  cd-local_ruby
  cd-ruby
  cd-wild
  echo-gem
  echo-local_ruby
  echo-ruby
  echo-wild

  # Lightning lets you abbreviate commands and subcommands
  # so the above can also be
  $ lg f
&lt;/pre&gt;&lt;p&gt;These functions are in the default format &lt;code&gt;SHELL_COMMAND-BOLT&lt;/code&gt;. Lightning generates these defaults by combining the commands &lt;code&gt;echo&lt;/code&gt; and &lt;code&gt;cd&lt;/code&gt; with global bolts gem, ruby, local_ruby and wild. If you don&amp;#8217;t want ruby-related functions, turn them off with: &lt;code&gt;lg bolt global off gem ruby local_ruby&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/2010/04/08/lightning-speed-for-your-shell.html&quot;&gt;The previous post&lt;/a&gt; had plenty of examples demonstrating the ruby and gem bolts. Let&amp;#8217;s look at the other two default bolts, wild and local_ruby. These two bolts are different than the others:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg bolt show wild   # or lg b s wild
  globs: 
  - &quot;**/*&quot;
  global: true

  $ lg b s local_ruby
  globs: 
  - &quot;**/*.rb&quot;
  - bin/**
  global: true
&lt;/pre&gt;&lt;p&gt;What&amp;#8217;s different about them is that their globs are local i.e. based on what&amp;#8217;s in the current directory. Let&amp;#8217;s try the wild bolt:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # In the base directory of the lightning gem
  $ echo-wild [TAB]
  Display all 274 possibilities? (y or n)

  $ echo-wild comm[TAB]
  command_has_required_args_i.dat  commands                         commands_i.dat                   commands_util.rb                 
  command_usage_i.dat              commands.rb                      commands_test.rb                 common.css
  $ echo-wild command_h[TAB]
  $ echo-wild command_has_required_args_i.dat
  .yardoc/objects/Lightning/CommandsUtil/command_has_required_args_i.dat

  # Functions with an infinitely deep glob can be dangerous
  $ cd /
  # TAB if you feel like autocompleting your whole filesystem
  $ echo-wild [DARE_YA]
&lt;/pre&gt;&lt;p&gt;As you can see, the wild bolt can be &lt;em&gt;wild&lt;/em&gt;. But if you use it in the right places, it can save you from navigating several directories.&lt;/p&gt;
&lt;p&gt;The local_ruby bolt is a good example of a specialized local glob. It&amp;#8217;s main purpose is let the user jump into any ruby related project and instantly command any ruby files regardless of their directory depth:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # In the base directory of the lightning gem
  $ echo-local_ruby [TAB]
  bolt.rb//lib/lightning               commands_util.rb                     core.rb                              lightning                            test_helper.rb
  bolt.rb//lib/lightning/commands      completion.rb                        function.rb//lib/lightning           lightning-complete                   util.rb
  bolt_test.rb                         completion_map.rb                    function.rb//lib/lightning/commands  lightning-translate                  version.rb
  builder.rb                           completion_map_test.rb               function_test.rb                     lightning.rb                         
  builder_test.rb                      completion_test.rb                   generator.rb                         misc.rb                              
  commands.rb                          config.rb                            generator_test.rb                    ruby.rb                              
  commands_test.rb                     config_test.rb                       generators.rb                        shell_command.rb

  $ echo-local_ruby m[TAB]
  $ echo-local_ruby misc.rb
  lib/lightning/generators/misc.rb
&lt;/pre&gt;&lt;p&gt;Note how the local_ruby bolt makes autocompleting in this directory much more relevant than wild. If you&amp;#8217;re a programmer, making a specialized local bolt for your language is only one command away: &lt;code&gt;lg bolt create local_language &#39;**/*.my_language_extension&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Although these two bolts don&amp;#8217;t do much with &lt;code&gt;echo&lt;/code&gt;, they can, when combined with more useful commands i.e. vim, grep, less.&lt;/p&gt;
&lt;h2 id=&quot;create_and_delete_functions&quot;&gt;&lt;a href=&quot;#create_and_delete_functions&quot;&gt;Create and Delete Functions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We can create and delete functions in three nonexclusive ways. The first way to create/delete a function is by individual combinations of one bolt and one shell command:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg function create cd gem &amp;&amp; lgr
  Created function &#39;cd-gem&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh

  # Give it a spin
  $ cd-gem b[TAB]
  bacon-1.1.0    bond-0.1.4     builder-2.1.2  bundler-0.9.7
  $ cd-gem ba[TAB]
  $ cd-gem bacon-1.1.0
  $ pwd
  /Library/Ruby/Gems/1.8/gems/bacon-1.1.0

  # Delete it
  $ lg function delete cd-gem
  Deleted function &#39;cd-gem&#39;
&lt;/pre&gt;&lt;p&gt;The second way is to use global commands and global bolts. When lightning generates functions, it combines each global command with each global bolt. For the default functions this means 2 commands * 4 bolts = 8 functions. Global commands are a great way of mass-assigning commands to a group of bolts.&lt;/p&gt;
&lt;p&gt;To compare these two ways, say we have bolts python, clojure, ruby and want to combine them each with commands vim and grep:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # The first and longer way
  $ lg function create vim python  # or lg f c vim python
  Created function &#39;vim-python&#39;
  $ lg function create vim clojure
  Created function &#39;vim-clojure&#39;
  # 4 more times ...

  # With global commands and bolts:
  # First make the bolts global since bolts aren&#39;t global by default
  $ lg bolt global on python clojure ruby
  Global on for bolts python, clojure, ruby

  # Then add the global commands
  $ lg shell_command create vim   # or lg s c create vim
  Created shell command &#39;vim&#39;
  $ lg shell_command create grep
  Created shell command &#39;grep&#39;
  $ lgr
  # ...

  # Expected functions show up
  $ lg f
  grep-clojure
  grep-python
  grep-ruby
  vim-clojure
  vim-python
  vim-ruby

  # If we want to create or delete global commands across global
  # bolts later, we can do that in one place:
  # Remove grep across global bolts
  $ lg shell_command delete grep
  Deleted shell command &#39;grep&#39;

  # No more grep
  $ lg f
  vim-clojure
  vim-ruby
  vim-ru
&lt;/pre&gt;&lt;p&gt;The third and not usually recommended way is to edit lightning&amp;#8217;s config file, ~/.lightningrc. Since ~/.lightningrc is &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt;, it&amp;#8217;s easy to read and modify. However, lightning depends on this file to function and will fail if the file has a syntax error. Modifying this file is recommended if you need to update existing bolts. Before doing this, read the &lt;a href=&quot;http://tagaholic.me/lightning/doc/Lightning/Config.html&quot;&gt;docs on its format&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;aliases&quot;&gt;&lt;a href=&quot;#aliases&quot;&gt;Aliases&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As we&amp;#8217;ve seen, function naming defaults to &lt;code&gt;SHELL_COMMAND-BOLT&lt;/code&gt;. While this is fine for bolts and commands with short names, it can get annoying for long names i.e. &lt;code&gt;echo-local_ruby&lt;/code&gt;. To shorten these defaults, you can alias bolts:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg function list --bolt=local_ruby  # or lg f l --bolt=local_ruby
  cd-local_ruby
  echo-local_ruby

  $ lg bolt alias local_ruby rb   # or lg b al local_ruby rb
  Aliased bolt &#39;local_ruby&#39; to &#39;rb&#39;
  $ lgr
  # ...

  $ lg f l --bolt=local_ruby
  cd-rb
  echo-rb

  # To list bolts with their aliases
  $ lg bolt list --alias  # or lg b l -a
  local_ruby      rb
  # ...
&lt;/pre&gt;&lt;p&gt;As you can see, the bolt alias is used in place of the bolt name when generating functions.&lt;/p&gt;
&lt;p&gt;When creating global commands, you can alias them as well:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg shell_command create less l
  Created shell command &#39;less&#39;

  $ lg function list --command=less   # or lg f l --command=less
  l-gem
  l-rb
  l-ruby
  l-wild

  # List commands and their aliases
  $ lg shell_command list --alias
  cd    cd
  echo  echo
  less  l
&lt;/pre&gt;&lt;p&gt;Note these aliases won&amp;#8217;t effect functions that have an explicit function name.&lt;/p&gt;
&lt;h2 id=&quot;creating_your_own_bolt&quot;&gt;&lt;a href=&quot;#creating_your_own_bolt&quot;&gt;Creating Your Own Bolt&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To show you how to create your own bolt with its functions, I&amp;#8217;ll show you one I made.&lt;/p&gt;
&lt;p&gt;Being a programmer, I have a number of projects spread across directories that I go between several times a day. Here&amp;#8217;s a tree view of the directories that organize my projects:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  ~/code/
  |-- fork
  |   |-- bacon/
  |   |-- ...
  |   `-- rip/
  |-- gems
  |   |-- hirb/
  |   |-- ...
  |   `-- my_core/
  |-- todo
  |   |-- gems
  |   |   |-- g-outline/
  |   |   `-- mp-tree/
  |   |-- ...
  |   `-- hooks.rb
  |-- repo
  |   |-- bin/
  |   |-- ...
  |   `-- queriac/
  # ....
&lt;/pre&gt;&lt;p&gt;There are only 2-3 levels of directories or 2-3 tabs to get to the point where I can autocomplete the project name. But as my number of projects grow, I find myself pausing more to remember which subdirectory a project is in. To me, this mental pause and doing 2-3 tabs is a waste of time. Enter lightning.&lt;/p&gt;
&lt;p&gt;To create a bolt and its functions, here&amp;#8217;s the steps I took:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Identify a group of paths that I use often.&lt;/strong&gt;&lt;br /&gt;
  Directories of coding projects&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Create a bolt that represents those paths using globs.&lt;/strong&gt;&lt;br /&gt;
  &lt;code&gt;lightning bolt create code &#39;~/code/fork/*&#39; ...&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Create function(s) for that bolt.&lt;/strong&gt;&lt;br /&gt;
  &lt;code&gt;lightning function create cd code c&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Generate and load functions into my shell.&lt;/strong&gt;&lt;br /&gt;
  &lt;code&gt;lightning-reload&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;#8217;s see these steps played out in the shell:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Quote arguments to prevent file expansion
  $ lg bolt create code &#39;~/code/fork/*&#39; &#39;~/code/gems/*&#39; &#39;~/code/todo/gems/*&#39; &#39;~/code/repo/*&#39;
  Created bolt &#39;code&#39;

  $ lg function create cd code c &amp;&amp; lgr
  Created function &#39;c&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh

  # Test drive c
  $ c [TAB]
  19it                  console_update        github_user_page.js   local_gem             rip
  alias                 core                  has_machine_tags      machinetag.js         shellable
  bacon                 dm_rails3_app         heroku_twilio_app     mp_tree               snips
  # ...

  $ c h[TAB]
  has_machine_tags   heroku_twilio_app  hirb
  $ c hi[TAB]
  $ c hirb[ENTER]
  # Verify it worked
  $ pwd
  /Users/bozo/code/gems/hirb
&lt;/pre&gt;&lt;p&gt;Nice! If I want to add another command to this bolt, say &lt;code&gt;grep&lt;/code&gt;, we know the drill:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg function create grep code &amp;&amp; lgr
  Created function &#39;grep-code&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh

  $ grep-code -r attr li[TAB]
  $ grep-code -r attr lightning
  $ grep-code -r attr lightning/lib
  /Users/bozo/code/gems/lightning/lib/lightning/bolt.rb:    attr_reader :name, :aliases, :desc
  /Users/bozo/code/gems/lightning/lib/lightning/bolt.rb:    attr_accessor :globs, :commands
  /Users/bozo/code/gems/lightning/lib/lightning/completion_map.rb:    attr_accessor :map
  # ...
&lt;/pre&gt;&lt;h2 id=&quot;generating_bolts&quot;&gt;&lt;a href=&quot;#generating_bolts&quot;&gt;Generating Bolts&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the last post &lt;a href=&quot;/2010/04/08/lightning-speed-for-your-shell.html#generators&quot;&gt;we saw how generators&lt;/a&gt; are implicitly used to create bolts and functions. But sometimes we need to use generators explicitly to generate bolts:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s use the gem generator with `lightning bolt generate` to generate bolts

  # Generates a bolt named ruby using the ruby generator
  # This is done implicitly for us with `lightning function create`
  $ lg bolt generate ruby    # or lg b g ruby
  Generated following globs for bolt &#39;ruby&#39;:
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/**/*.{rb,bundle,so,c}
    /Library/Ruby/Site/1.8/**/*.{rb,bundle,so,c}
  
  # Generates a bolt named ruby19 using the ruby generator
  $ lg bolt generate ruby19 ruby
  Generated following globs for bolt &#39;ruby19&#39;:
    /Users/bozo/.rvm/ruby-1.9.1-p378/lib/ruby/1.9.1/**/*.{rb,bundle,so,c}
    /Users/bozo/.rvm/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/**/*.{rb,bundle,so,c}

  # To test what a generator generates without making a bolt
  $ lg bolt generate ruby --test
  /Users/bozo/.rvm/ruby-1.9.1-p378/lib/ruby/1.9.1/**/*.{rb,bundle,so,c}
  /Users/bozo/.rvm/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/**/*.{rb,bundle,so,c}
&lt;/pre&gt;&lt;p&gt;As you can see, if you&amp;#8217;re testing a generator or generating a bolt with a name different than the generator&amp;#8217;s, use &lt;code&gt;lightning bolt generate&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;misc&quot;&gt;&lt;a href=&quot;#misc&quot;&gt;Miscellaneous&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Some miscellaneous notes:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Make your own lightning commands i.e. &lt;code&gt;lg YOUR_COMMAND&lt;/code&gt; with &lt;a href=&quot;http://tagaholic.me/lightning/doc/Lightning/Commands.html&quot;&gt;command plugins&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;Use the &lt;code&gt;translate&lt;/code&gt; lightning command to test the translation of arguments for a given function:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Command to test:
  $ cp-gem -r rubygems-update-1.3.6 .

  # Just prefix the above with lg t (lg translate)
  # Each argument is printed on a separate line
  $ lg t cp-gem -r rubygems-update-1.3.6 .
  -r
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.6
  .
&lt;/pre&gt;&lt;ul&gt;
	&lt;li&gt;Use the &lt;code&gt;echo&lt;/code&gt; shell command combined with a bolt to pass a bolt&amp;#8217;s translating ability to any command:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ echo-gem -r rubygems-update-1.3.6 .
  -r /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.6 .
  
  # Emulate cp-gem from the previous example
  $ cp `echo-gem -r rubygems-update-1.3.6 .`
&lt;/pre&gt;&lt;h2&gt;Wrap Up&lt;/h2&gt;
&lt;p&gt;This post has been a thorough introduction to using &lt;a href=&quot;http://github.com/cldwalker/lightning&quot;&gt;lightning&lt;/a&gt;. For more about lightning, visit its &lt;a href=&quot;http://tagaholic.me/lightning/&quot;&gt;homepage&lt;/a&gt; and &lt;a href=&quot;http://tagaholic.me/lightning/doc/&quot;&gt;docs&lt;/a&gt;. For questions about using lightning, feel free to leave a comment below or &lt;a href=&quot;http://github.com/cldwalker/lightning/issues&quot;&gt;open an issue&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>Lightning - Speed For Your Shell</title>
   <link href="http://tagaholic.me/2010/04/08/lightning-speed-for-your-shell.html"/>
   <updated>2010-04-08T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2010/04/08/lightning-speed-for-your-shell</id>
   <content type="html">&lt;p&gt;Introducing &lt;a href=&quot;http://github.com/cldwalker/lightning&quot;&gt;lightning&lt;/a&gt;, a commandline framework that could revolutionize how fast you are on the commandline.  Lightning lets you &lt;b&gt;easily&lt;/b&gt; define and generate shell functions which autocomplete and interpret paths (files and directories) by their basenames. With these functions you don&amp;#8217;t have to ever type the full path to &lt;b&gt;any&lt;/b&gt; file for &lt;b&gt;any&lt;/b&gt; command again.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/post-lightning.jpg&quot; alt=&quot;lightning over water&quot; width=&quot;200&quot; height=&quot;250&quot;/&gt;&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#intro&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#install&quot;&gt;Install&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#lightning_bolts&quot;&gt;Lightning Bolts&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#everything_is_local&quot;&gt;Everything is Local&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#generators&quot;&gt;Generators&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;intro&quot;&gt;&lt;a href=&quot;#intro&quot;&gt;Intro&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Lightning generates shell functions which can interpret paths by their basenames. So instead of carpal-typing&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ less /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb.rb
&lt;/pre&gt;&lt;p&gt;just type&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ less-ruby irb.rb
&lt;/pre&gt;&lt;p&gt;&lt;code&gt;less-ruby&lt;/code&gt; is a lightning function which wraps &lt;code&gt;less&lt;/code&gt; with the ability to refer to system ruby files by their basenames. Being a lightning function, it can also autocomplete system ruby files:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # 1112 available system ruby files
  $ less-ruby [TAB]
  Display all 1112 possibilities? (y or n)

  $ less-ruby a[TAB]
  abbrev.rb                  abstract.rb                abstract_index_builder.rb
  $ less-ruby abb[TAB]
  $ less-ruby abbrev.rb
  # Pages /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/abbrev.rb ...

  # Autocompletion works regardless of the number of arguments
  $ less-ruby -I abbrev.rb y[TAB]
  yaml.rb      yamlnode.rb  ypath.rb
  $ less-ruby -I abbrev.rb yp[TAB]
  $ less-ruby -I abbrev.rb ypath.rb
  # Pages /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/abbrev.rb and
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml/ypath.rb ...
&lt;/pre&gt;&lt;p&gt;The &amp;#8216;-I&amp;#8217; being passed to &lt;code&gt;less-ruby&lt;/code&gt; demonstrates an important point. A lightning function &lt;i&gt;only touches and translates&lt;/i&gt; the arguments it knows how to translate to full paths. This allows a lightning function to be used the same as the command it wraps i.e. with any mix of options, local files or non-file arguments.&lt;/p&gt;
&lt;p&gt;Perhaps you noticed &lt;code&gt;less-ruby&lt;/code&gt; can refer to 1112 files by basename. Are they all in one directory? Nope. They&amp;#8217;re in &lt;strong&gt;118 directories&lt;/strong&gt;. So what happens when two files from different directories have the same basename? Lightning lets you pick the right file in an autocomplete-friendly way:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ less-ruby date[TAB]
  date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8
  date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse
  date2.rb
  dateentry.rb
  datefield.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/tkextlib/iwidgets
  datefield.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/tkextlib/tcllib
  datetime.rb

  $ less-ruby date.rb[TAB]
  $ less-ruby date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8
  date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8
  date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse

  $ less-ruby date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/[TAB]
  $ less-ruby date.rb///System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse
  # Pages /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/optparse/date.rb ...
&lt;/pre&gt;&lt;p&gt;Note the format for displaying conflicting basenames is &lt;code&gt;basename//directory&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is cool but what if we want a &lt;code&gt;grep-ruby&lt;/code&gt;, &lt;code&gt;vim-ruby&lt;/code&gt;, or &lt;code&gt;*-ruby&lt;/code&gt; to search, edit or do anything to our 1100+ system ruby files? No problem. It&amp;#8217;s a one-liner: &lt;code&gt;lightning function create grep ruby &amp;amp;&amp;amp; lightning-reload&lt;/code&gt;. What if we want nothing to do with ruby files and want to define our own group of paths to autocomplete and type minimally? No problem. It&amp;#8217;s really quite easy.&lt;/p&gt;
&lt;h2 id=&quot;install&quot;&gt;&lt;a href=&quot;#install&quot;&gt;Install&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Lightning works with &lt;a href=&quot;http://www.gnu.org/software/bash/&quot;&gt;bash&lt;/a&gt; or &lt;a href=&quot;http://zsh.sourceforge.net/&quot;&gt;zsh&lt;/a&gt; shells and since it&amp;#8217;s written in &lt;a href=&quot;http://www.ruby-lang.org/&quot;&gt;ruby&lt;/a&gt;, you&amp;#8217;ll need ruby 1.8.6 or later. To install lightning, use &lt;a href=&quot;http://hellorip.com&quot;&gt;rip&lt;/a&gt; or &lt;a href=&quot;http://rubygems.org&quot;&gt;rubygems&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ rip install lightning
  # OR  
  $ sudo gem install yard # if you want lightning&#39;s documentation generated correctly
  $ sudo gem install lightning
&lt;/pre&gt;&lt;p&gt;If you&amp;#8217;ve installed with rubygems and &lt;code&gt;`time lightning`&lt;/code&gt; takes longer than 0.05 seconds, I &lt;strong&gt;strongly recommend&lt;/strong&gt; installing with rip. rubygems is known to have a hefty startup lag with older versions of ruby. Since lightning&amp;#8217;s autocompletion depends on this startup time, accepting this lag makes lightning slow as molasses.&lt;/p&gt;
&lt;p&gt;Once lightning is installed, we need to do a one-time setup:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # To see available install options
  $ lightning install -h

  # Installs lightning&#39;s core files and sources the needed lightning functions
  $ lightning install &amp;&amp; source ~/.lightning/functions.sh
  Created ~/.lightningrc
  Created ~/.lightning/functions.sh for bash
  # Or for zsh
  $ lightning install --shell=zsh &amp;&amp; source ~/.lightning/functions.sh

  # To have lightning&#39;s functionality loaded when your shell starts up
  echo source ~/.lightning/functions.sh &gt;&gt; ~/.bashrc
  # or for zsh
  echo source ~/.lightning/functions.sh &gt;&gt; ~/.zshrc

  # For all future examples I&#39;ll be using this alias
  $ alias lg=lightning
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Updated&lt;/strong&gt;: To install and view lightning&amp;#8217;s man page:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # If installed with rip, man pages are automatically installed
  $ man lightning

  # If installed with rubygems
  $ sudo gem install gem-man
  $ gem man lightning
&lt;/pre&gt;&lt;h2 id=&quot;lightning_bolts&quot;&gt;&lt;a href=&quot;#lightning_bolts&quot;&gt;Lightning Bolts&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create a function (less-ruby) from scratch that can autocomplete and access by basename 1112 files across 118 directories must take a lot of effort. Right? Not really:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # These globs are specific to my filesystem
  # Arguments are quoted to prevent shell expansion
  $ lg bolt create ruby &#39;/Library/Ruby/Site/1.8/**/*.{rb,bundle,so,c}&#39;
    &#39;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/**/*.{rb,bundle,so,c}&#39;
  Created bolt &#39;ruby&#39;

  # Creates less-ruby and loads it into the shell
  $ lg function create less ruby &amp;&amp; lightning-reload
  Created function &#39;less-ruby&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh
&lt;/pre&gt;&lt;p&gt;The first command creates the &amp;#8216;ruby&amp;#8217; lightning bolt with two globs. This is &lt;strong&gt;all the information&lt;/strong&gt; that a lightning function needs to know about the filesystem. The second command creates the lightning function by combining the bolt with the desired shell command, &lt;code&gt;less&lt;/code&gt; in this case. &lt;code&gt;lightning-reload&lt;/code&gt; creates and reloads lightning&amp;#8217;s functions into the current shell session.&lt;/p&gt;
&lt;p&gt;Although these steps are fairly easy, you may have noticed that the globs were specific to my system. Fortunately, lightning provides &lt;a href=&quot;#generators&quot;&gt;generators&lt;/a&gt; to generate fileysystem-specific globs for bolts. Since lightning has a generator for the ruby bolt, the previous example can be even shorter:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg function create less ruby &amp;&amp; lightning-reload
  Generated following globs for bolt &#39;ruby&#39;:
    /Library/Ruby/Site/1.8/**/*.{rb,bundle,so,c}
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/**/*.{rb,bundle,so,c}
  Created function &#39;less-ruby&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh
&lt;/pre&gt;&lt;p&gt;Keep this one-liner in mind for following along with examples in this post. If you see a function you don&amp;#8217;t have i.e. &lt;code&gt;less-gem&lt;/code&gt;, create it: &lt;code&gt;lg function create less gem &amp;amp;&amp;amp; lightning-reload&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lightning bolts aren&amp;#8217;t limited to one shell command i.e. &lt;code&gt;less&lt;/code&gt;. To make a lightning function which wraps around &lt;i&gt;any shell command&lt;/i&gt;, just repeat the above one-liner. For example, let&amp;#8217;s make a function that edits system ruby files:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ lg function create vim ruby &amp;&amp; lightning-reload
  Created function &#39;vim-ruby&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh

  $ vim-ruby abbrev.rb
  # Opens /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/abbrev.rb in vim
&lt;/pre&gt;&lt;p&gt;In this section we&amp;#8217;ve seen that a bolt takes globs and converts them to paths to be accessed locally by basename. Since bolts can be used with any command, we can think of a bolt as a virtual, local directory whose &lt;i&gt;contents change&lt;/i&gt; depending on what its globs match. For more about bolts and globs, &lt;a href=&quot;http://tagaholic.me/lightning/doc/Lightning/Bolt.html&quot;&gt;read here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;everything_is_local&quot;&gt;&lt;a href=&quot;#everything_is_local&quot;&gt;Everything is Local&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If a bolt is a virtual, &lt;em&gt;local&lt;/em&gt; directory, can we autocomplete and execute commands around any bolt path as if we were right there? Sure!&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # echo-ruby calls `echo` with the ruby bolt
  $ echo-ruby abbrev.rb
  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/abbrev.rb

  # Note: This kind of completion doesn&#39;t work for zsh yet
  # Autocomplete the directory containing abbrev.rb
  $ echo-ruby abbrev.rb/../[TAB]
  Display all 136 possibilities? (y or n)
  $ echo-ruby abbrev.rb/../md[TAB]
  $ echo-ruby abbrev.rb/../md5.rb
  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/md5.rb

  # Autocomplete multiple levels up or down
  $ echo-ruby abbrev.rb/../../[TAB]
  abbrev.rb/../../1.8/        abbrev.rb/../../gems/       abbrev.rb/../../site_ruby/  abbrev.rb/../../user-gems/
  $ echo-ruby abbrev.rb/../../../
  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib
  $ echo-ruby abbrev.rb/../irb/ext/s[TAB]
  $ echo-ruby abbrev.rb/../irb/ext/save-history.rb
  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/irb/ext/save-history.rb
&lt;/pre&gt;&lt;p&gt;Bolt paths that are directories can also autocomplete and execute this way:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # less-gem calls `less` with the gem bolt (contains directories of rubygems)
  # less-gem ba[TAB]
  $ less-gem bacon-1.1.0
  $ less-gem bacon-1.1.0/l[TAB]
  $ less-gem bacon-1.1.0/lib/
  $ less-gem bacon-1.1.0/lib/b[TAB]
  $ less-gem bacon-1.1.0/lib/bacon.rb
  # Pages /Library/Ruby/Gems/1.8/gems/bacon-1.1.0/lib/bacon.rb ...
&lt;/pre&gt;&lt;p&gt;If we can use filename expansion on local paths, why not bolt paths?&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s search in different versions of a gem for the use of method_missing()
  # grep-gem calls `grep` on the gem bolt
  $ grep-ruby -r def.*method_missing rai[TAB]
  rails-1.2.6  rails-2.1.0  rails-2.2.2  rails-2.3.4
  $ grep-ruby -r def.*method_missing rails-

  # Traditional filename expansion doesn&#39;t work
  $ grep-ruby -r def.*method_missing rails-*
  grep: rails-*: No such file or directory

  # Append &#39;..&#39; instead
  $ grep-ruby -r def.*method_missing rails-..
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/initializer.rb:  def method_missing(name, *args)
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/rails_generator/manifest.rb:      def method_missing(action, *args, &amp;block)
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/rails_generator/simple_logger.rb:        def method_missing(method, *args, &amp;block)
  /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/initializer.rb:  def method_missing(name, *args)
  # ...

  # Why not use &#39;*&#39; for lightning as well?
  # Say you use a liberal expansion:
  #   $ grep-ruby -r def.*method_missing r*
  # If there happens to be a local file starting with &#39;r&#39; i.e. &#39;readme&#39;,
  # the shell expands &#39;r*&#39; to &#39;readme&#39; and lightning will never see &#39;r*&#39;.
&lt;/pre&gt;&lt;p&gt;So lightning does filename expansion but only for arguments ending in &lt;code&gt;..&lt;/code&gt;. When expanding matches, lightning treats everything before &lt;code&gt;..&lt;/code&gt; as a regular expression:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ grep-gem -r def.*method_missing rubygems-u[TAB]
  rubygems-update-1.3.1  rubygems-update-1.3.2  rubygems-update-1.3.5  rubygems-update-1.3.6
  $ grep-gem -r def.*method_missing rubygems-update-1.3.
  # Only search two versions
  $ grep-gem -r def.*method_missing rubygems-update-1.3.[56]..
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.5/lib/rubygems/package.rb:  def method_missing(meth, *args, &amp;block)
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.5/lib/rubygems/specification.rb:  def method_missing(sym, *a, &amp;b) # :nodoc:
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.5/lib/rubygems/test_utilities.rb:  def method_missing(meth, *args, &amp;block)
  # ...

  # To search either rubygems or rails
  $ grep-gem -r def.*method_missing &#39;(rails|rubygems)..&#39;
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/initializer.rb:  def method_missing(name, *args)
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/rails_generator/manifest.rb:      def method_missing(action, *args, &amp;block)
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0/lib/rails_generator/simple_logger.rb:        def method_missing(method, *args, &amp;block)
  /Library/Ruby/Gems/1.8/gems/rails-2.2.2/lib/initializer.rb:  def method_missing(name, *args)
  # ...

  # If you&#39;re unsure of what you&#39;re executing, test it with `lightning translate`
  # Prints arguments to be passed to grep, one per line
  $ lg translate grep-gem -r def.*method_missing &#39;(rails|rubygems)..&#39;
  -r
  def.*method_mis
  /Library/Ruby/Gems/1.8/gems/rails-2.1.0
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.1
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.2
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.5
  /Library/Ruby/Gems/1.8/gems/rubygems-update-1.3.6
  /Library/Ruby/Gems/1.8/gems/rails-2.2.2
  /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/rails-1.2.6
  /Library/Ruby/Gems/1.8/gems/rubygems-sing-1.0.0
  /Library/Ruby/Gems/1.8/gems/rails-2.3.4
&lt;/pre&gt;&lt;h2 id=&quot;generators&quot;&gt;&lt;a href=&quot;#generators&quot;&gt;Generators&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Generators generate filesystem-specific bolts. When creating a function, this is done for us automatically if the bolt and generator have the same name. Let&amp;#8217;s create a function with one of lightning&amp;#8217;s default generators:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # List default generators
  $ lg generator
  bin         Files in $PATH
  gem         Directories of gems
  local_ruby  *ALL* local ruby files. Careful where you do this.
  rails       Files in a rails project
  ruby        System ruby files
  test_ruby   Test or spec files in a ruby project
  wild        *ALL* files and directories under the current directory. Careful where you do this.

  # Try the test_ruby generator with the Test::Unit runner
  $ lg function create testrb test_ruby &amp;&amp; lightning-reload
  Generated following globs for bolt &#39;test_ruby&#39;:
    {spec,test}/**/*_{test,spec}.rb
    {spec,test}/**/{test,spec}_*.rb
    spec/**/*.spec
  Created function &#39;testrb-test_ruby&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh

  # Runs any number of local ruby test files, no matter how many directories deep
  # $ testrb-test_ruby  ...
&lt;/pre&gt;&lt;p&gt;If you&amp;#8217;re a rubyist, I &lt;strong&gt;highly recommend&lt;/strong&gt; checking out all the ruby-related generators.&lt;/p&gt;
&lt;p&gt;Since generators are important in distributing bolts that work for everyone, lightning lets users make their own generators and store them under ~/.lightning/generators. &lt;a href=&quot;http://tagaholic.me/lightning/doc/Lightning/Generators.html&quot;&gt;Read the docs&lt;/a&gt; to learn how to make generator plugins. What if we want to try out someone else&amp;#8217;s generators? Not too hard:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s try out my mac-specific generators
  $ mkdir -p ~/.lightning/generators
  $ curl http://github.com/cldwalker/dotfiles/raw/master/.lightning/generators/mac.rb &gt; ~/.lightning/generators/mac.rb

  $ lg generator
  app             Mac apps
  bin             Files in $PATH
  brew            Homebrew formulas under /usr/local
  # ...

  # Let&#39;s combine open with mac apps
  $ lg function create open app &amp;&amp; lightning-reload
  Generated following globs for bolt &#39;app&#39;:
    /Applications/*.app
    /Applications/Utilities/*.app
  Created function &#39;open-app&#39;
  Created /Users/bozo/.lightning/functions.sh
  Loaded /Users/bozo/.lightning/functions.sh

  # Let&#39;s open a mac app
  $ open-app Co[TAB]
  Cog.app                 Colloquy.app            ColorSync\ Utility.app  Console.app
  $ open-app Coll[TAB]
  $ open-app Colloquy.app
  # Opens Colloquy
&lt;/pre&gt;&lt;p&gt;To try out more generators, &lt;a href=&quot;http://github.com/cldwalker/dotfiles/tree/master/.lightning/generators&quot;&gt;see my public ones&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hopefully this post has shown that &lt;a href=&quot;http://github.com/cldwalker/lightning&quot;&gt;lightning&lt;/a&gt; can revolutionize how you interact with your filesystem on the commandline. By abstracting a group of paths to a bolt&amp;#8217;s name and its globs, &lt;i&gt;any group of paths is only a bolt&amp;#8217;s name away&lt;/i&gt; from being used as if they were in the current directory. Although the examples have been specific to ruby paths, lightning can generate functions for any group of paths. Lightning&amp;#8217;s generators provide a way for users to share their bolts and thus how they use their filesystem.&lt;/p&gt;
&lt;p&gt;This post was mostly an introduction to lightning and what it&amp;#8217;s capable of. The &lt;a href=&quot;/2010/04/09/lightning-speed-for-the-user.html&quot;&gt;next post&lt;/a&gt; will cover using it in more depth. For more about lightning, visit its &lt;a href=&quot;http://tagaholic.me/lightning/&quot;&gt;homepage&lt;/a&gt; and &lt;a href=&quot;http://tagaholic.me/lightning/doc/&quot;&gt;docs&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
 <entry>
   <title>Hirb - And Tables for All</title>
   <link href="http://tagaholic.me/2010/03/11/hirb-and-tables-for-all.html"/>
   <updated>2010-03-11T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2010/03/11/hirb-and-tables-for-all</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;/2009/03/13/hirb-irb-on-the-good-stuff.html&quot;&gt;Almost a year ago&lt;/a&gt;, &lt;a href=&quot;http://github.com/cldwalker/hirb&quot;&gt;hirb&lt;/a&gt; started as an itch to get mysql-like tables for Rails&amp;#8217; &lt;code&gt;ActiveRecord&lt;/code&gt; models. Now, &lt;a href=&quot;http://github.com/cldwalker/hirb/blob/v0.3.0/CHANGELOG.rdoc#readme&quot;&gt;hirb 0.3.0&lt;/a&gt; provides table views for &lt;i&gt;ten additional&lt;/i&gt; database gems. Whether you use hirb with couch, mongo, riak or any of the databases supported by &lt;a href=&quot;http://github.com/jeremyevans/sequel&quot;&gt;sequel&lt;/a&gt; or &lt;a href=&quot;datamapper&quot;&gt;datamapper&lt;/a&gt;, hirb essentially turns irb into a database-agnostic database shell.&lt;/p&gt;
&lt;h2&gt;Database Gems&lt;/h2&gt;
&lt;p&gt;Here are the list of additional database gems and their modules/classes that now have table views:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/datamapper/dm-core&quot;&gt;datamapper&lt;/a&gt;: &lt;code&gt;DataMapper::Resource&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/jeremyevans/sequel&quot;&gt;sequel&lt;/a&gt;: &lt;code&gt;Sequel::Model&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/jamesgolick/friendly&quot;&gt;friendly&lt;/a&gt;: &lt;code&gt;Friendly::Document&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/jnunemaker/mongomapper&quot;&gt;mongomapper&lt;/a&gt;: &lt;code&gt;MongoMapper::Document, MongoMapper::EmbeddedDocument&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/durran/mongoid&quot;&gt;mongoid&lt;/a&gt;: &lt;code&gt;Mongoid::Document&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/georgepalmer/couch_foo&quot;&gt;couch_foo&lt;/a&gt;: &lt;code&gt;CouchFoo::Base&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/jchris/couchrest&quot;&gt;couchrest&lt;/a&gt;: &lt;code&gt;CouchRest::ExtendedDocument&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/langalex/couch_potato&quot;&gt;couch_potato&lt;/a&gt;: &lt;code&gt;CouchPotato::Persistence&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://github.com/seancribbs/ripple&quot;&gt;ripple&lt;/a&gt;: &lt;code&gt;Ripple::Document&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://ruby-dbi.rubyforge.org/&quot;&gt;dbi&lt;/a&gt;: &lt;code&gt;DBI::Row&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Examples&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s all you need in your ~/.irbrc for hirb to work with the above gems and the following examples:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;hirb&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Hirb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Keep in mind that while that the following examples are simple, your models/tables can be as complex as you&amp;#8217;d like and hirb will still render your tables cleanly.&lt;/p&gt;
&lt;h3 id=&quot;sequel&quot;&gt;&lt;a href=&quot;#sequel&quot;&gt;Sequel&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For this example, you need to have &lt;a href=&quot;http://www.sqlite.org/&quot;&gt;sqlite3&lt;/a&gt; installed.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ sudo gem install sqlite3-ruby sequel
  $ irb -rubygems -rsequel

  # Setup db and a model
  &gt;&gt; DB = Sequel.sqlite
  =&gt; #&lt; Sequel::SQLite::Database: &quot;sqlite:/&quot;&gt;
  &gt;&gt; DB.create_table(:urls) { primary_key :id; String :name }
  =&gt; []
  &gt;&gt; class Url &lt; Sequel::Model; end
  =&gt; nil

  # Nicely formatted tables!
  &gt;&gt; Url.create :name=&gt;&#39;example.com&#39;
  +----+-------------+
  | id | name        |
  +----+-------------+
  | 1  | example.com |
  +----+-------------+
  1 row in set
  # Same as above
  &gt;&gt; Url.all
&lt;/pre&gt;&lt;h3 id=&quot;data_mapper&quot;&gt;&lt;a href=&quot;#data_mapper&quot;&gt;DataMapper&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For this example, you need to have &lt;a href=&quot;http://www.sqlite.org/&quot;&gt;sqlite3&lt;/a&gt; installed.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ sudo gem install sqlite3-ruby dm-core do_sqlite3
  $ irb -rubygems -rdm-core

  # Setup db and a model
  &gt;&gt; DataMapper.setup(:default, &#39;sqlite3::memory:&#39;)
  =&gt; #&lt; DataMapper::Adapters::Sqlite3Adapter:0x188ceac ... &gt;
  &gt;&gt; class Url
  &gt;&gt;  include DataMapper::Resource
  &gt;&gt;  property :id, Serial
  &gt;&gt;  property :name, String
  &gt;&gt; end
  =&gt; #&lt; DataMapper::Property @model=Url @name=:name&gt;
  &gt;&gt; Url.auto_migrate!
  =&gt; true

  # Nicely formatted tables!
  &gt;&gt; Url.create :name=&gt;&#39;example.com&#39;
  +----+-------------+
  | id | name        |
  +----+-------------+
  | 1  | example.com |
  +----+-------------+
  1 row in set
  # Same as above
  &gt;&gt; Url.all
&lt;/pre&gt;&lt;h3 id=&quot;mongo_mapper&quot;&gt;&lt;a href=&quot;#mongo_mapper&quot;&gt;MongoMapper&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For this example you need to have &lt;a href=&quot;http://www.mongodb.org/display/DOCS/Home&quot;&gt;MongoDB&lt;/a&gt; installed.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ sudo gem install mongo_mapper
  $ irb -rubygems -rmongo_mapper

  # Setup db and a model
  &gt;&gt; MongoMapper.connection = Mongo::Connection.new
  =&gt; #&lt; Mongo::Connection:0x1123d28 ... &gt;
  &gt;&gt; MongoMapper.database = &#39;test&#39;
  =&gt; &#39;test&#39;
  &gt;&gt; class Url
  &gt;&gt;   include MongoMapper::Document
  &gt;&gt;   key :name, String
  &gt;&gt; end
  =&gt; #&lt; MongoMapper::Plugins::Keys::Key:0x5a3520 ... &gt;

  # Nicely formatted tables!
  &gt;&gt; Url.create :name=&gt;&#39;example.com&#39;
  +-------------+--------------------------+
  | name        | _id                      |
  +-------------+--------------------------+
  | example.com | 4b97cf2978c2ec2854000001 |
  +-------------+--------------------------+
  1 row in set
  # Same as above
  &gt;&gt; Url.all
&lt;/pre&gt;&lt;h3 id=&quot;couchrest&quot;&gt;&lt;a href=&quot;#couchrest&quot;&gt;CouchRest&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For this example you need to have &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt; installed.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ sudo gem install couchrest
  $ irb -rubygems -rcouchrest

  # Setup db and a model
  &gt;&gt; class Url &lt; CouchRest::ExtendedDocument
  &gt;&gt;   property :name
  &gt;&gt;   view_by :name
  &gt;&gt; end
  =&gt; false
  &gt;&gt; Url.database = CouchRest.database(&quot;http://127.0.0.1:5984/urls&quot;)
  =&gt; #&lt; CouchRest::Database:0x170541c ... &gt;

  # Nicely formatted tables!
  &gt;&gt; Url.create :name=&gt;&#39;example.com&#39;
  +----------------------------------+-------------+
  | _id                              | name        |
  +----------------------------------+-------------+
  | af990a562a9a96703dd6ef0442a73db8 | example.com |
  +----------------------------------+-------------+
  1 row in set
  # Same as above
  &gt;&gt; Url.all  
&lt;/pre&gt;&lt;h2&gt;Dynamic Views&lt;/h2&gt;
&lt;h3&gt;Creating Them&lt;/h3&gt;
&lt;p&gt;All default views for the new database gems are due to hirb&amp;#8217;s &lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/DynamicView.html&quot;&gt;dynamic views&lt;/a&gt;. So what if you&amp;#8217;re using a database gem that isn&amp;#8217;t supported? Let&amp;#8217;s answer this using &lt;a href=&quot;http://github.com/jamesgolick/friendly&quot;&gt;friendly&lt;/a&gt; as an example (even though hirb already supports it):&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Identify the module or class that the database gem uses to define models. For friendly, this module is &lt;code&gt;Friendly::Document&lt;/code&gt;.&lt;/li&gt;
	&lt;li&gt;Determine &lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/Helpers/Table.html#M000007&quot;&gt;what table options&lt;/a&gt; to pass to tables and how to generate them from the database gem&amp;#8217;s model/table object. Although you can define as many options as you want, you must define the &lt;code&gt;:fields&lt;/code&gt; option. To generate fields for a given friendly &lt;code&gt;model&lt;/code&gt; object: &lt;code&gt;model.attributes.keys&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;Using the last two steps, define a dynamic view using &lt;code&gt;Hirb.add_dynamic_view&lt;/code&gt; that returns a hash of table options:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;no&quot;&gt;Hirb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_dynamic_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Friendly::Document&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:helper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:auto_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:fields&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/DynamicView.html&quot;&gt;Read the docs&lt;/a&gt; for more about dynamic views.&lt;/p&gt;
&lt;h3&gt;Submitting Them&lt;/h3&gt;
&lt;p&gt;If you&amp;#8217;ve created a dynamic view for a somewhat popular database gem, feel free to fork and add it to hirb&amp;#8217;s default dynamic views. Since hirb&amp;#8217;s default dynamic views are in module form, &lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/DynamicView.html&quot;&gt;read the docs&lt;/a&gt; to understand how to write them. Although I do appreciate any forking, I&amp;#8217;m looking mainly to add default views for commonly used database gems.&lt;/p&gt;</content>
 </entry>
    
    
    
    
    
    
 
    
    
    
    
 <entry>
   <title>Two Dimensional Console Menus with Hirb</title>
   <link href="http://tagaholic.me/2010/02/16/two-dimensional-console-menus-with-hirb.html"/>
   <updated>2010-02-16T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2010/02/16/two-dimensional-console-menus-with-hirb</id>
   <content type="html">&lt;p&gt;If you&amp;#8217;re familiar with &lt;a href=&quot;http://github.com/cldwalker/hirb&quot;&gt;hirb&lt;/a&gt;, you know it&amp;#8217;s good at &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#hirbs_handy_tables&quot;&gt;displaying objects as tables&lt;/a&gt;. Hirb&amp;#8217;s &lt;a href=&quot;http://github.com/cldwalker/hirb/blob/master/CHANGELOG.rdoc#readme&quot;&gt;latest release&lt;/a&gt; takes a table&amp;#8217;s usefulness a step further by turning them into two-dimensional menus, menus that can pick values from &lt;i&gt;any&lt;/i&gt; table cell. &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;Boson&lt;/a&gt;, in turn, provides these menus to &lt;i&gt;any&lt;/i&gt; of its commands with a flick of the switch.&lt;/p&gt;
&lt;h2&gt;Intro&lt;/h2&gt;
&lt;p&gt;Hirb&amp;#8217;s menus can be &lt;a href=&quot;/2009/06/19/page-irb-output-and-improve-ri-with-hirb.html#ri&quot;&gt;traditional one-dimensional menus&lt;/a&gt;. But what we&amp;#8217;re interested in here are 2D menus:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ irb -rubygems -rhirb
  # import menu()
  &gt;&gt; extend Hirb::Console
  =&gt; self

  # Let&#39;s make a menu from the first ten local gemspecs.
  # We don&#39;t care what versions they are for simplicity sake.
  # Of course your list will be different
  &gt;&gt; menu Gem.source_index.gems.values[0,10], :fields=&gt;[:name, :homepage], :two_d=&gt;true
  +--------+-----------------------------------+------------------------------------------------------+
  | number | name                              | homepage                                             |
  +--------+-----------------------------------+------------------------------------------------------+
  | 1      | ruby-debug                        | http://rubyforge.org/projects/ruby-debug/            |
  | 2      | net-ssh-gateway                   | http://net-ssh.rubyforge.org/gateway                 |
  | 3      | mspec                             | http://rubyspec.org                                  |
  | 4      | yard                              | http://yardoc.org                                    |
  | 5      | rubyforge                         | http://codeforpeople.rubyforge.org/rubyforge/        |
  | 6      | midiator                          | http://projects.bleything.net/projects/show/midiator |
  | 7      | collectiveidea-awesome_nested_set | http://collectiveidea.com                            |
  | 8      | hirb                              | http://github.com/cldwalker/hirb                     |
  | 9      | boson                             | http://tagaholic.me/boson/                           |
  | 10     | linecache                         | http://rubyforge.org/projects/rocky-hacks/linecache  |
  +--------+-----------------------------------+------------------------------------------------------+
  10 rows in set
  Choose:
  # Possible answers from user ...

  # By default selections are applied to the first column, name in this case
  Choose: 1,4
  =&gt; [&#39;ruby-debug&#39;, &#39;yard&#39;]

  # To choose from the homepage column simply append &#39;:homepage&#39; after choices
  Choose : 1,4:homepage  # or 1,4:h
  =&gt; [&#39;http://rubyforge.org/projects/ruby-debug/&#39;, &#39;http://yardoc.org&#39;]

  # To select values from different columns, simply separate them with spaces
  Choose: 1-3 4:homepage  # or 1-3 4:h
  =&gt; [&#39;ruby-debug&#39;, &#39;net-ssh-gateway&#39;, &#39;mspec&#39;, &#39;http://yardoc.org&#39;]
&lt;/pre&gt;&lt;p&gt;Nice! We can pick out values from table cell(s) simply by typing &lt;code&gt;rows&lt;/code&gt;:&lt;code&gt;column&lt;/code&gt;, where column is optional and can be abbreviated.&lt;/p&gt;
&lt;h2&gt;2D Action Menus&lt;/h2&gt;
&lt;p&gt;So why bother with a 2D menu? Well, for the above, we can perform different actions depending on the column:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  &gt;&gt; choices = menu Gem.source_index.gems.values[0,10], :fields=&gt;[:name, :homepage], :two_d=&gt;true
  +--------+-----------------------------------+------------------------------------------------------+
  | number | name                              | homepage                                             |
  +--------+-----------------------------------+------------------------------------------------------+
  | 1      | ruby-debug                        | http://rubyforge.org/projects/ruby-debug/            |
  | 2      | net-ssh-gateway                   | http://net-ssh.rubyforge.org/gateway                 |
  | 3      | mspec                             | http://rubyspec.org                                  |
  | 4      | yard                              | http://yardoc.org                                    |
  | 5      | rubyforge                         | http://codeforpeople.rubyforge.org/rubyforge/        |
  | 6      | midiator                          | http://projects.bleything.net/projects/show/midiator |
  | 7      | collectiveidea-awesome_nested_set | http://collectiveidea.com                            |
  | 8      | hirb                              | http://github.com/cldwalker/hirb                     |
  | 9      | boson                             | http://tagaholic.me/boson/                           |
  | 10     | linecache                         | http://rubyforge.org/projects/rocky-hacks/linecache  |
  +--------+-----------------------------------+------------------------------------------------------+
  10 rows in set
  Choose:
  # Possible answers from user ...

  # Choose some gems and uninstall them
  Choose: 5-6
  =&gt; [&#39;rubyforge&#39;, &#39;midiator&#39;]
  &gt;&gt; system(&#39;sudo&#39;, &#39;gem&#39;, &#39;uninstall&#39;, *choices)
  =&gt; true

  # Choose some gems and open them in a browser
  Choose: 5-6:h
  =&gt; [&#39;http://codeforpeople.rubyforge.org/rubyforge/&#39;, &#39;http://projects.bleything.net/projects/show/midiator&#39;]
  # works in mac osx
  &gt;&gt; system(&#39;open&#39;, *choices)
  =&gt; true
&lt;/pre&gt;&lt;p&gt;Okay. 2D menus seem like a good way to perform multiple actions from one menu. But is there a more natural way to do this? Yes. How about at the menu prompt?:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s make methods out of the actions we used above
  &gt;&gt; def uninstall(gems); system(&#39;sudo&#39;, &#39;gem&#39;, &#39;uninstall&#39;, *gems); end
  =&gt; nil
  &gt;&gt; def browser(urls); system(&#39;open&#39;, *urls); end
  =&gt; nil

  # Passing an :action option makes menu expect an action (method) with menu choices as the argument
  &gt;&gt; menu Gem.source_index.gems.values[0,10], :fields=&gt;[:name, :homepage], :two_d=&gt;true, :action=&gt;true
  +--------+-----------------------------------+------------------------------------------------------+
  | number | name                              | homepage                                             |
  +--------+-----------------------------------+------------------------------------------------------+
  | 1      | ruby-debug                        | http://rubyforge.org/projects/ruby-debug/            |
  | 2      | net-ssh-gateway                   | http://net-ssh.rubyforge.org/gateway                 |
  | 3      | mspec                             | http://rubyspec.org                                  |
  | 4      | yard                              | http://yardoc.org                                    |
  | 5      | rubyforge                         | http://codeforpeople.rubyforge.org/rubyforge/        |
  | 6      | midiator                          | http://projects.bleything.net/projects/show/midiator |
  | 7      | collectiveidea-awesome_nested_set | http://collectiveidea.com                            |
  | 8      | hirb                              | http://github.com/cldwalker/hirb                     |
  | 9      | boson                             | http://tagaholic.me/boson/                           |
  | 10     | linecache                         | http://rubyforge.org/projects/rocky-hacks/linecache  |
  +--------+-----------------------------------+------------------------------------------------------+
  10 rows in set
  Choose:
  # Possible answers from user ...

  # Uninstall rubyforge + midiator using uninstall()
  Choose: uninstall 5-6
  =&gt; true

  # Open rubyforge and midiator urls using browser()
  Choose: browser 5-6:h
  =&gt; true
&lt;/pre&gt;&lt;p&gt;Note that by default, menu actions call top-level &lt;code&gt;main&lt;/code&gt; methods and pass all to the choices to the method as one array. &lt;code&gt;menu()&lt;/code&gt; can be configured to call another object&amp;#8217;s methods and pass menu choices in different ways with additional options. &lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/Menu.html&quot;&gt;See the documentation for more info&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;examples_with_boson&quot;&gt;&lt;a href=&quot;#examples_with_boson&quot;&gt;Examples with Boson&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we understand how 2d menus are used, let&amp;#8217;s look at some examples with &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt;. Boson&amp;#8217;s integration with hirb allows menus to be invoked on &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#github_boson_library&quot;&gt;any&lt;/a&gt; &lt;a href=&quot;/2010/02/03/using-gemcutters-api-from-the-commandline.html&quot;&gt;rendered&lt;/a&gt; &lt;a href=&quot;/2009/11/07/ruby-reference-commands-with-boson.html&quot;&gt;commands&lt;/a&gt; with the flick of a switch (-m).&lt;/p&gt;
&lt;p&gt;To follow along with these examples you&amp;#8217;ll need to:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ gem install boson boson-more
  $ echo &quot;require &#39;boson/more&#39;&quot; &gt;&gt; ~/.bosonrc
  # Note that --default rewrites your boson config to make menu_pipe a default library
  $ boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/plugins/menu_pipe.rb --default
&lt;/pre&gt;&lt;p&gt;The Examples:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#chaining_apis&quot;&gt;Chaining APIs&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#tag-tree&quot;&gt;Opening and Editing Bookmarks within Rails&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#playing_songs&quot;&gt;Playing Songs&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#gemspecs_revisited&quot;&gt;Gemspecs Revisited&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;chaining_apis&quot;&gt;Chaining APIs&lt;/h3&gt;
&lt;p&gt;If you&amp;#8217;re a rubyist, there&amp;#8217;s a good chance your gems are on github and gemcutter. Using the &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#github_boson_library&quot;&gt;github&lt;/a&gt; and &lt;a href=&quot;/2010/02/03/using-gemcutters-api-from-the-commandline.html&quot;&gt;gemcutter&lt;/a&gt; libraries, let&amp;#8217;s look up a github user&amp;#8217;s projects and then pass them to gemcutter to get their stats:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # To follow along
  $ boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/site/gemcutter.rb
  $ boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/site/github.rb

  $ boson user_repos -u=wycats - -m  # or boson user_repos -u=wycats - --menu
  +--------+---------------------------+----------+-------+---------------------------------------+----------------------------------------------------------------------------------+--------------------+
  | number | name                      | watchers | forks | homepage                              | description                                                                      | url                |
  +--------+---------------------------+----------+-------+---------------------------------------+----------------------------------------------------------------------------------+--------------------+
  | 1      | bundler                   | 586      | 53    |                                       |                                                                                  | http://github.c... |
  | 2      | merb-core                 | 570      | 55    | http://www.merbivore.com              | Merb Core: All you need. None you don&#39;t.                                         | http://github.c... |
  | 3      | merb                      | 478      | 89    | http://www.merbivore.com              | master merb branch                                                               | http://github.c... |
  | 4      | thor                      | 429      | 34    | http://www.yehudakatz.com             | A scripting framework that replaces rake and sake                                | http://github.c... |
  | 5      | moneta                    | 323      | 24    | http://www.yehudakatz.com             | a unified interface to key/value stores                                          | http://github.c... |
  | 6      | merb-more                 | 295      | 30    | http://www.merbivore.com              | Merb More: The Full Stack. Take what you need; leave what you don&#39;t.             | http://github.c... |
  | 7      | merb-plugins              | 282      | 38    | http://www.merbivore.com              | Merb Plugins: Even more modules to hook up your Merb installation                | http://github.c... |
  | 8      | textmate                  | 134      | 8     | http://www.yehudakatz.com             | Command-line package manager for textmate                                        | http://github.c... |
  | 9      | jspec                     | 45       | 1     | http://www.yehudakatz.com             | A JavaScript BDD Testing Library                                                 | http://github.c... |
  | 10     | irb2                      | 44       | 1     |                                       |                                                                                  | http://github.c... |
  # ...
  38 rows in set
  Default command: browser
  Default field: url
  Choose:
  # Possible answers from user ...

  # To get gemcutter stats we use cuts()
  Choose: cuts 1-5:n
  Fetching gem &#39;bundler&#39;
  Fetching gem &#39;merb-core&#39;
  Fetching gem &#39;merb&#39;
  Fetching gem &#39;thor&#39;
  Fetching gem &#39;moneta&#39;
  +-----------+-----------+-------------------------------------+------------------------------------------------------------+
  | name      | downloads | project_uri                         | info                                                       |
  +-----------+-----------+-------------------------------------+------------------------------------------------------------+
  | bundler   | 36890     | http://gemcutter.org/gems/bundler   | Bundles are fun                                            |
  | merb-core | 10281     | http://gemcutter.org/gems/merb-core | Merb. Pocket rocket web framework.                         |
  | merb      | 5923      | http://gemcutter.org/gems/merb      | (merb-core + merb-more + DM) == Merb stack                 |
  | thor      | 33921     | http://gemcutter.org/gems/thor      | A scripting framework that replaces rake, sake and rubigen |
  | moneta    | 1073      | http://gemcutter.org/gems/moneta    | A unified interface to key/value stores                    |
  +-----------+-----------+-------------------------------------+------------------------------------------------------------+
  5 rows in set

  # Since this is a 2d menu we could have done other actions like open repository urls
  # Notice that we don&#39;t have to pass a command since user_repos() already sets the default menu action to browser
  Choose: 1,3,5:u
  # Opens http://github.com/wycats/bundler, http://github.com/wycats/merb and http://github.com/wycats/moneta in browser

  # Or opened repository homepages
  Choose: 3,4:h
  # Opens http://www.merbivore.com and http://www.yehudakatz.com in browser
&lt;/pre&gt;&lt;p&gt;Nice! This is an easy way to see how popular (by downloads) a user&amp;#8217;s gems are, as well as to open multiple projects quickly in a browser.&lt;/p&gt;
&lt;h3 id=&quot;tag-tree&quot;&gt;Opening and Editing Bookmarks within Rails&lt;/h3&gt;
&lt;p&gt;If you don&amp;#8217;t use github or gemcutter much, perhaps menus used within a Rails project will be more interesting. Direct from &lt;a href=&quot;http://github.com/cldwalker/tag-tree&quot;&gt;tag-tree&lt;/a&gt;, my Rails bookmarking project:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ script/console

  # url_tagged_with() is a wrapper around a Url model&#39;s method to fetch records by machine tags
  # this fetches urls tagged as being articles with a class attribute
  &gt;&gt; url_tagged_with &#39;article:class --menu&#39;   # or ut &#39;ar:cla -m&#39;
  +--------+------+---------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
  | number | id   | name                                                          | description                                                   | quick_mode_tag_list                                           |
  +--------+------+---------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
  | 1      | 1877 | http://pivotallabs.com/users/jdean/blog/articles/911-equal... | explains what to override to have arrays of your objects e... | article:plang=ruby;class=array                                |
  | 2      | 1617 | http://blog.grayproductions.net/articles/understanding_m17n   | character encoding tutorial series                            | article:plang=ruby;class=string                               |
  | 3      | 1929 | http://yokolet.blogspot.com/2009/07/design-and-implementat... | decent overview of ruby&#39;s multilinguilization/encoding        | article:class=string                                          |
  | 4      | 1760 | http://timetobleed.com/5-things-you-dont-know-about-user-i... | explains why Process.euid is dangerous, decent intro to ni... | article:plang=ruby;class=process                              |
  | 5      | 1956 | http://www.engineyard.com/blog/2009/key-value-stores-in-ruby/ | decent intro to pstore from key/value perspective             | article:class=pstore                                          |
  | 6      | 1488 | http://redhanded.hobix.com/inspect/hoppingThroughPipesAndC... | piping with procs                                             | article:plang=ruby;class=proc                                 |
  | 7      | 1152 | http://innig.net/software/ruby/closures-in-ruby.rb            | closures in ruby                                              | article:plang=ruby;tutorial;class=proc                        |
  | 8      | 1278 | http://www.robertsosinski.com/2008/12/21/understanding-rub... | good overview of ruby lambdas +procs                          | article:plang=ruby;tutorial;class=proc                        |
  | 9      | 1292 | http://weblog.raganwald.com/2007/10/stringtoproc.html         | handy string proc method                                      | article:plang=ruby;class=proc                                 |
  | 10     | 2283 | http://yehudakatz.com/2010/02/07/the-building-blocks-of-ruby/ | nuanced but interesting blocks comparison w/ python           | article:class=proc                                            |
  | 11     | 2040 | http://blog.rubybestpractices.com/posts/rklemme/017-Struct... | points out some useful array + hash-like behavior for stru... | article:class=struct                                          |
  | 12     | 2056 | http://www.michaelharrison.ws/weblog/?p=163                   | easy lazy evaluation                                          | article:class=enumerator                                      |
  | 13     | 2079 | http://blog.rubybestpractices.com/posts/rklemme/018-Comple... | tips on common object overrides: equivalence,cloning,persi... | article:method=to_yaml_properties;method=eql;method=marsha... |
  | 14     | 2081 | http://blog.segment7.net/articles/2008/12/17/friendly-ruby... | common overrides for objects: marshal,pp,equality,exception   | article:class=object;method=exception;method=_dump            |
  +--------+------+---------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
  14 rows in set
  Default field: name
  Default command: browser
  Choose:
  # Possible answers from user ...

  # Opens last 3 urls in browser
  Choose: 12-14

  # Opens first five records in an editor to edit their attributes using console_update gem
  Choose: console_update 1-5:i

  # Add tag article:todo to urls 3-5
  Choose: ta 3-5 tag:todo
&lt;/pre&gt;&lt;h3 id=&quot;playing_songs&quot;&gt;Playing Songs&lt;/h3&gt;
&lt;p&gt;This one is more for fun. I like to pick and play songs in the console using &lt;a href=&quot;http://wiki.xmms2.xmms.se/wiki/Main_Page&quot;&gt;xmms2&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # If you have xmms2 and want to follow along
  $ boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/personal/xmms2.rb

  # Choose a directory to play
  $ boson play /mnt/m/rap

  # Search and choose a song
  $ boson search_songs Jay
  +--------+-------+----------------------------------------------------------------------+-------+
  | number | track | title                                                                | time  |
  +--------+-------+----------------------------------------------------------------------+-------+
  | 1      | 8     | Memphis Bleek ft. Jay Z - Is That Your Bitch                         | 04:38 |
  | 2      | 10    | Jay-Z - December 4Th                                                 | 04:34 |
  | 3      | 40    | Jay-Z - Kingdom Come (Produced By Just Blaze)                        | 04:24 |
  | 4      | 62    | Jay-Z - Big Pimpin                                                   | 04:43 |
  | 5      | 63    | Jay-Z - Lucifer                                                      | 03:12 |
  | 6      | 81    | Jay-Z - Lost Ones (Feat. Chrissette Michelle) (Produced By Dr. Dre)  | 03:44 |
  +--------+-------+----------------------------------------------------------------------+-------+
  Default field: track
  Default command: play_track
  Choose: 6
  # Starts playing last song
&lt;/pre&gt;&lt;h3 id=&quot;gemspecs_revisited&quot;&gt;Gemspecs Revisited&lt;/h3&gt;
&lt;p&gt;Now that we&amp;#8217;ve seen some menu examples, let&amp;#8217;s make a boson command that can take a menu option using the above gemspecs example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# You can just drop this in a local Bosonfile&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Bosonfile&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# @render_options :fields=&amp;gt;{:values=&amp;gt;[:name, :summary, :homepage, :authors], :default=&amp;gt;[:name, :homepage]}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# @options :limit=&amp;gt;50&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# @config :menu=&amp;gt;{:command=&amp;gt;&amp;#39;browser&amp;#39;, :default_field=&amp;gt;:homepage}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gemspecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Gem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source_index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gems&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:limit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see, &lt;code&gt;render_options&lt;/code&gt; takes the :fields option we were passing to &lt;code&gt;menu()&lt;/code&gt;. I also added an optional gemspec limit. Notice the configuration for menu, which will come in handy soon. Let&amp;#8217;s give this command a shot:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # By default this displays the same table as before
  $ boson gemspecs
  +-----------------------------------+------------------------------------------------------+
  | name                              | homepage                                             |
  +-----------------------------------+------------------------------------------------------+
  | ruby-debug                        | http://rubyforge.org/projects/ruby-debug/            |
  | net-ssh-gateway                   | http://net-ssh.rubyforge.org/gateway                 |
  | mspec                             | http://rubyspec.org                                  |
  | yard                              | http://yardoc.org                                    |
  | rubyforge                         | http://codeforpeople.rubyforge.org/rubyforge/        |
  # ...
  50 rows in set

  # Now let&#39;s turn on a menu
  $ boson gemspecs -m
  +--------+-----------------------------------+------------------------------------------------------+
  | number | name                              | homepage                                             |
  +--------+-----------------------------------+------------------------------------------------------+
  | 1      | ruby-debug                        | http://rubyforge.org/projects/ruby-debug/            |
  | 2      | net-ssh-gateway                   | http://net-ssh.rubyforge.org/gateway                 |
  | 3      | mspec                             | http://rubyspec.org                                  |
  | 4      | yard                              | http://yardoc.org                                    |
  | 5      | rubyforge                         | http://codeforpeople.rubyforge.org/rubyforge/        |
  # ...
  50 rows in set
  Default field: homepage
  Default command: browser
  Choose:

  # Notice that the menu config set the menu&#39;s defaults.
  # With these defaults, we can open urls simply:
  # Open first five urls
  Choose: 1-5
  # To commit browser suicide by opening all homepages
  Choose: *
&lt;/pre&gt;&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;As we&amp;#8217;ve seen, hirb&amp;#8217;s 2D menus provide a useful way of picking multiple values from table cells. Combining this with menu actions makes for a quick and interactive way to pass values between methods. Boson takes advantage of all this by allowing &lt;em&gt;any&lt;/em&gt; of its commands to pipe values to &lt;em&gt;any&lt;/em&gt; other command. From the gemspec example, we saw that &lt;em&gt;no extra code&lt;/em&gt; is required to give a boson command access to this powerful menu system. If you&amp;#8217;re interested in playing with more menu-based commands, &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site/github.rb&quot;&gt;try the github library&lt;/a&gt;. With it you can use menus to perform actions on user gists, user and repository searches, repository commit lists, repository networks and more.&lt;/p&gt;</content>
 </entry>
    
    
    
    
    
    
    
    
 
    
    
    
    
 <entry>
   <title>Using Gemcutter's Api from the Commandline</title>
   <link href="http://tagaholic.me/2010/02/03/using-gemcutters-api-from-the-commandline.html"/>
   <updated>2010-02-03T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2010/02/03/using-gemcutters-api-from-the-commandline</id>
   <content type="html">&lt;p&gt;Gemcutter &lt;a href=&quot;http://update.gemcutter.org/2010/02/01/january-changelog.html&quot;&gt;recently added&lt;/a&gt; a sweet search call to &lt;a href=&quot;http://gemcutter.org/pages/api_docs&quot;&gt;its &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;. With gemcutter&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; and &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt;, we&amp;#8217;ll see how to search gems, get a gem&amp;#8217;s information and compare multiple gems on the commandline. Also, I&amp;#8217;ll explain how some of this was done so you&amp;#8217;re able to make commands for any &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re more interested in how this library is built, &lt;a href=&quot;#explanation&quot;&gt;skip to here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To use this boson library:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ gem install boson boson-more
  $ echo &quot;require &#39;boson/more&#39;&quot; &gt;&gt; ~/.bosonrc
  $ boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/site/gemcutter.rb
&lt;/pre&gt;&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site/gemcutter.rb&quot;&gt;This gemcutter &lt;span class=&quot;caps&quot;&gt;CLI&lt;/span&gt;&lt;/a&gt; comes with three commands. The first command is &lt;code&gt;gem_search&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # basic search
  bash&gt; boson gem_search command
  +---------------------+-----------+---------------------------------------------------------------------------------------+---------------------------------------------------------------+
  | name                | downloads | info                                                                                  | authors                                                       |
  +---------------------+-----------+---------------------------------------------------------------------------------------+---------------------------------------------------------------+
  | rubyforge           | 70823     | A script which automates a limited set of rubyforge operations.\n\n* Run &#39;rubyforg... | Ryan Davis, Eric Hodel, Ara T Howard, Tom Copeland            |
  | gemcutter           | 69607     | Adds several commands to RubyGems for managing gems and more on Gemcutter.org.        | Nick Quaranto                                                 |
  | hoe                 | 68058     | Hoe is a rake/rubygems helper for project Rakefiles. It helps you\nmanage and main... | Ryan Davis                                                    |
  | capistrano          | 55740     | Capistrano is a utility and framework for executing commands in parallel on multip... | Jamis Buck, Lee Hambley                                       |
  # ...
  30 rows in set

  # Let&#39;s go the second page of the previous query
  bash&gt; boson gem_search command -p2
  +--------------+-----------+------------------------------------------------------------------------------------------+--------------------------------------------------------------+
  | name         | downloads | info                                                                                     | authors                                                      |
  +--------------+-----------+------------------------------------------------------------------------------------------+--------------------------------------------------------------+
  | vlad         | 2173      | Vlad the Deployer is pragmatic application deployment automation,\nwithout mercy. Muc... | Ryan Davis, Eric Hodel, Wilson Bilkovich                     |
  | sys-uname    | 2161      |     The sys-uname library provides an interface for gathering information\n    about ... | Daniel J. Berger                                             |
  | cmdparse     | 1943      | cmdparse provides classes for parsing commands on the command line; command line opti... | Thomas Leitner                                               |
  | backup       | 1862      | \n                            Backup is a Ruby Gem written for Unix and Rails environ... | Michael van Rooijen                                          |
  # ...
  30 rows in set

  # multi word search
  bash&gt; boson gem_search rails plugin
  +--------------------------------+-----------+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
  | name                           | downloads | info                                                                           | authors                                                                        |
  +--------------------------------+-----------+--------------------------------------------------------------------------------+--------------------------------------------------------------------------------+
  | will_paginate                  | 42886     | The will_paginate library provides a simple, yet powerful and extensible AP... | Mislav Marohnić, PJ Hyett                                                      |
  | aasm                           | 7638      | AASM is a continuation of the acts as state machine rails plugin, built for... | Scott Barron, Scott Petersen, Travis Tilley                                    |
  | after_commit                   | 7016      | \n    A Ruby on Rails plugin to add an after_commit callback. This can be u... | Nick Muerdter, David Yip, Pat Allan                                            |
  | rails_datamapper               | 2124      | Rails Plugin for DataMapper                                                    | Tom Malone                                                                     |
  # ...
  30 rows in set
  
  # with no search term, defaults to all-time top-downloaded gems
  # no surprises here
  bash&gt; boson gem_search
  +-----------------+-----------+----------------------------------------------------------------------------------------+----------------------------------------------------+
  | name            | downloads | info                                                                                   | authors                                            |
  +-----------------+-----------+----------------------------------------------------------------------------------------+----------------------------------------------------+
  | activesupport   | 319341    | Utility library which carries commonly used classes and goodies from the Rails fram... | David Heinemeier Hansson                           |
  | activerecord    | 293266    | Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database table... | David Heinemeier Hansson                           |
  | actionpack      | 287332    | Eases web-request routing, handling, and response as a half-way front, half-way pag... | David Heinemeier Hansson                           |
  | rails           | 287005    |     Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or... | David Heinemeier Hansson                           |
  | rack            | 285612    | Rack provides minimal, modular and adaptable interface for developing\nweb applicat... | Christian Neukirchen                               |
  # ...
  30 rows in set
&lt;/pre&gt;&lt;p&gt;If you&amp;#8217;re not familiar with &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt;, you may be surprised with how many options are available by default to control how and what you see:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Only see the name and info fields
  bash&gt; boson gem_search tag -f=n,i   # or --fields=name,info
 +---------------------+------------------------------------------------------------------------------------------------------------------------------+
  | name                | info                                                                                                                         |
  +---------------------+------------------------------------------------------------------------------------------------------------------------------+
  | haml                |       Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML\n      that&#39;s designed to express the str... |
  | libxml-ruby         | The Libxml-Ruby project provides Ruby language bindings for the GNOME Libxml2 XML toolkit. It is free software, released ... |
  | win32-api           |       The Win32::API library is meant as a replacement for the Win32API\n      library that ships as part of the standard... |
  | haml-edge           |       Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML\n      that&#39;s designed to express the str... |
   # ...
   30 rows in set
  
   # Sort by authors
   bash&gt; boson gem_search tag -s=a   # or --sort=authors
   +---------------------+-----------+--------------------------------------------------------+--------------------------------------------------------+
   | name                | downloads | info                                                   | authors                                                |
   +---------------------+-----------+--------------------------------------------------------+--------------------------------------------------------+
   | calais              | 489       | A Ruby interface to the Calais Web Service             | Abhay Kumar                                            |
   | stage               | 506       | Code template generator for Rails and Merb that DRY... | Andrew Stone                                           |
   | tagz                | 779       |         tagz.rb is generates html, xml, or any sgml... | Ara T. Howard                                          |
   | dm-tags             | 1985      | This package brings tagging to DataMapper.  It is i... | Bobby Calderwood                                       |
   | libxml-ruby         | 21789     | The Libxml-Ruby project provides Ruby language bind... | Charlie Savage                                         |
   | win32-api           | 14810     |       The Win32::API library is meant as a replacem... | Daniel J. Berger, Park Heesob                          |
   # ...
   30 rows in set

  # Show all fields, displaying a paged vertical table
  bash&gt; boson gem_search tag -f=* -V
  ************************* 1. row *************************
            authors: Nathan Weizenbaum, Hampton Catlin
       dependencies: {&quot;development&quot;=&gt;[{&quot;name&quot;=&gt;&quot;maruku&quot;, &quot;requirements&quot;=&gt;&quot;&gt;= 0.5.9&quot;}, {&quot;name&quot;=&gt;&quot;yard&quot;, &quot;requirements&quot;=&gt;&quot;&gt;= 0.4.0&quot;}], &quot;runtime&quot;=&gt;[]}
          downloads: 85590
            gem_uri: http://gemcutter.org/gems/haml-2.2.17.gem
               info:       Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML
        that&#39;s designed to express the structure of XHTML or XML documents
        in a non-repetitive, elegant, easy way,
        using indentation rather than closing tags
        and allowing Ruby to be embedded with ease.
        It was originally envisioned as a plugin for Ruby on Rails,
        but it can function as a stand-alone templating engine.

               name: haml
        project_uri: http://gemcutter.org/gems/haml
            version: 2.2.17
  version_downloads: 25104
  ************************* 2. row *************************
  # Remaining records are paged ...

  # To get more help on this command
  bash&gt; boson gem_search -hv
  # ...
&lt;/pre&gt;&lt;p&gt;The second command we&amp;#8217;ll look at is &lt;code&gt;cut&lt;/code&gt;, which displays gemcutter&amp;#8217;s information on a gem:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson cut rails
  +-------------------+--------------------------------------------------------------------------------------------------------------------------------+
  | field             | value                                                                                                                          |
  +-------------------+--------------------------------------------------------------------------------------------------------------------------------+
  | name              | &quot;rails&quot;                                                                                                                        |
  | downloads         | 287086                                                                                                                         |
  | info              | &quot;    Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\n    on top of either MySQL, P... |
  | version           | &quot;2.3.5&quot;                                                                                                                        |
  | project_uri       | &quot;http://gemcutter.org/gems/rails&quot;                                                                                              |
  | gem_uri           | &quot;http://gemcutter.org/gems/rails-2.3.5.gem&quot;                                                                                    |
  | version_downloads | 189219                                                                                                                         |
  | authors           | &quot;David Heinemeier Hansson&quot;                                                                                                     |
  | dependencies      | {&quot;development&quot;=&gt;[], &quot;runtime&quot;=&gt;[{&quot;name&quot;=&gt;&quot;activeresource&quot;, &quot;requirements&quot;=&gt;&quot;= 2.3.5&quot;}, {&quot;name&quot;=&gt;&quot;actionmailer&quot;, &quot;requiremen... |
  +-------------------+--------------------------------------------------------------------------------------------------------------------------------+
  9 rows in set
&lt;/pre&gt;&lt;p&gt;The third command is &lt;code&gt;cuts&lt;/code&gt;, which lists multiple gems. This command is perfect for comparing gems i.e. &lt;a href=&quot;http://ruby-toolbox.com/categories/mocking.html&quot;&gt;mocking gems&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson cuts rr mocha flexmock facon
  Fetching gem &#39;rr&#39;
  Fetching gem &#39;mocha&#39;
  Fetching gem &#39;flexmock&#39;
  Fetching gem &#39;facon&#39;
  +----------+-----------+------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
  | name     | downloads | project_uri                        | info                                                                                                                                              |
  +----------+-----------+------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
  | rr       | 4973      | http://gemcutter.org/gems/rr       | RR (Double Ruby) is a double framework that features a rich selection of double techniques and a terse syntax. http://xunitpatterns.com/Test%2... |
  | mocha    | 19703     | http://gemcutter.org/gems/mocha    |       Mocking and stubbing library with JMock/SchMock syntax, which allows mocking and stubbing of methods on real (non-mock) classes.\n          |
  | flexmock | 4527      | http://gemcutter.org/gems/flexmock | FlexMock is a extremely simple mock object class compatible with the Test::Unit framework.  Although the FlexMock&#39;s  interface is simple, it i... |
  | facon    | 291       | http://gemcutter.org/gems/facon    | A mocking library in the spirit of the Bacon spec library. Small, compact, and works with Bacon.                                                  |
  +----------+-----------+------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
  4 rows in set
&lt;/pre&gt;&lt;p&gt;Now, if you want to use these commands but with shorter command names or different default fields displayed, &lt;a href=&quot;http://tagaholic.me/boson/doc/&quot;&gt;you should&lt;/a&gt; &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#just_alias_it&quot;&gt;read up&lt;/a&gt; &lt;a href=&quot;/2009/11/21/boson-command-your-ruby-universe-part-deux.html#social_libraries&quot;&gt;on boson&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So how hard was it to create this &lt;span class=&quot;caps&quot;&gt;CLI&lt;/span&gt;? Not hard at all &amp;#8230;&lt;/p&gt;
&lt;h2 id=&quot;explanation&quot;&gt;&lt;a href=&quot;#explanation&quot;&gt;Explanation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To understand &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site/gemcutter.rb&quot;&gt;this console interface&lt;/a&gt; to gemcutter, let&amp;#8217;s look at creating the &lt;code&gt;gem_search&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;First, as &lt;a href=&quot;http://gemcutter.org/pages/api_docs&quot;&gt;gemcutter&amp;#8217;s api docs&lt;/a&gt; explain, a search request looks like  &lt;code&gt;/api/v1/search.(json|xml)?query=[QUERY]&lt;/code&gt;. Let&amp;#8217;s consider what we&amp;#8217;ll do with this api call:&lt;/p&gt;
&lt;p&gt;1. Make a get request to get back a string.&lt;br /&gt;
2. Convert the string into a ruby object by parsing the format (xml or json).&lt;br /&gt;
3. Display the ruby object in a well-formatted, useful way.&lt;/p&gt;
&lt;p&gt;Step 1 can be done with the standard library net/http i.e. &lt;code&gt;Net::HTTP.get(URI.parse(url))&lt;/code&gt;. We&amp;#8217;ll just use boson&amp;#8217;s &lt;code&gt;get()&lt;/code&gt; command which wraps around this. For step 2, we&amp;#8217;ll parse json using &lt;code&gt;JSON.parse&lt;/code&gt;. If you&amp;#8217;re on 1.9, you should already have the json library. Otherwise, &lt;code&gt;sudo gem install json&lt;/code&gt; should set you up. For step 3, we&amp;#8217;ll use &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#hirbs_handy_tables&quot;&gt;hirb&amp;#8217;s handy tables which integrate nicely with boson&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Taking the first two steps, the boson command looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;json&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Gemcutter&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gem_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://gemcutter.org/api/v1/search.json?query=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pretty straightforward. To try this command, drop it in a local Bosonfile and &amp;#8230;&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Knowing nothing about the returned data structure, boson attempts to format it
  bash&gt; boson gem_search tag
  +---------------------------+---------------------------+-----------+---------------------------+---------------------------+---------------------+---------------------------+-----------+-------------------+
  | authors                   | dependencies              | downloads | gem_uri                   | info                      | name                | project_uri               | version   | version_downloads |
  +---------------------------+---------------------------+-----------+---------------------------+---------------------------+---------------------+---------------------------+-----------+-------------------+
  | Nathan Weizenbaum, Ham... | developmentnamemarukur... | 85521     | http://gemcutter.org/g... |       Haml (HTML Abstr... | haml                | http://gemcutter.org/g... | 2.2.17    | 25048             |
  | Charlie Savage            | developmentruntime        | 21769     | http://gemcutter.org/g... | The Libxml-Ruby projec... | libxml-ruby         | http://gemcutter.org/g... | 1.1.3     | 18167             |
  | Daniel J. Berger, Park... | developmentnametest-un... | 14794     | http://gemcutter.org/g... |       The Win32::API l... | win32-api           | http://gemcutter.org/g... | 1.4.5     | 3973              |
  # ...
  # It&#39;s a mess.

  # Knowing that we&#39;re supposed to be getting back an array of gems
  # let&#39;s inspect one of the results
  bash&gt; boson -e &quot;p gem_search(&#39;tag&#39;)[0]&quot;
  {&quot;name&quot;=&gt;&quot;haml&quot;, &quot;downloads&quot;=&gt;85525, &quot;info&quot;=&gt;&quot;      Haml (HTML Abstraction Markup Language) is a layer on top of XHTML or XML\n      
  that&#39;s designed to express the structure of XHTML or XML documents\n      in a non-repetitive, elegant, easy way,\n      using indentation 
  rather than closing tags\n      and allowing Ruby to be embedded with ease.\n      It was originally envisioned as a plugin for Ruby on 
  Rails,\n      but it can function as a stand-alone templating engine.\n&quot;, &quot;version&quot;=&gt;&quot;2.2.17&quot;, 
  &quot;project_uri&quot;=&gt;&quot;http://gemcutter.org/gems/haml&quot;, &quot;gem_uri&quot;=&gt;&quot;http://gemcutter.org/gems/haml-2.2.17.gem&quot;, &quot;version_downloads&quot;=&gt;25052, 
  &quot;authors&quot;=&gt;&quot;Nathan Weizenbaum, Hampton Catlin&quot;, &quot;dependencies&quot;=&gt;{&quot;development&quot;=&gt;[{&quot;name&quot;=&gt;&quot;maruku&quot;, &quot;requirements&quot;=&gt;&quot;&gt;= 0.5.9&quot;}, 
  {&quot;name&quot;=&gt;&quot;yard&quot;, &quot;requirements&quot;=&gt;&quot;&gt;= 0.4.0&quot;}], &quot;runtime&quot;=&gt;[]}}

  # Ok, a gem is a hash. But with what fields?
  bash&gt; boson -e &quot;p gem_search(&#39;tag&#39;)[0].keys&quot;
  [&quot;name&quot;, &quot;downloads&quot;, &quot;info&quot;, &quot;version&quot;, &quot;project_uri&quot;, &quot;gem_uri&quot;, &quot;version_downloads&quot;, &quot;authors&quot;, &quot;dependencies&quot;]
&lt;/pre&gt;&lt;p&gt;Now for the third step. Let&amp;#8217;s configure the table fields rendered for our api call with &lt;code&gt;render_options()&lt;/code&gt;. In keeping with &lt;a href=&quot;/2009/10/19/how-boson-enhances-your-irb-experience.html#organization_and_philosophy&quot;&gt;boson&amp;#8217;s philosophy&lt;/a&gt;, we&amp;#8217;ll write it in commented form:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;json&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Gemcutter&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# @render_options :fields=&amp;gt;{:default=&amp;gt;%w{name downloads info authors},&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#  :values=&amp;gt;%w{name authors version_downloads info project_uri gem_uri version downloads dependencies} },&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#  :filters=&amp;gt;{:default=&amp;gt;{&amp;#39;dependencies&amp;#39;=&amp;gt;:inspect}}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Search gemcutter&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gem_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://gemcutter.org/api/v1/search.json?query=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that we passed two keys to &lt;code&gt;render_options&lt;/code&gt;: :fields and :filters. For :fields we pass :default to specify default fields and :values to specify all values for :fields. Now let&amp;#8217;s give this command a test drive:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson gem_search tagging
  +---------------------------------+-----------+---------------------------------------------------------------------+--------------------------------+
  | name                            | downloads | info                                                                | authors                        |
  +---------------------------------+-----------+---------------------------------------------------------------------+--------------------------------+
  | dm-tags                         | 1989      | This package brings tagging to DataMapper.  It is inspired by Ac... | Bobby Calderwood               |
  | sup                             | 1840      | Sup is a console-based email client for people with a lot of ema... | William Morgan                 |
  | tagomatic                       | 634       | = tagomatic\n\nSimple command-line mp3 tagger based on mp3info g... | Daniel Lukic                   |
  | CachedSupermodel                | 610       | Based on cached_model by &amp;lt;a href=&amp;quot;http://dev.robotcoop.c... | adocca Entertainment AB        |
  # ...
  30 rows in set

  # Having specified available fields above, we can use aliased versions of fields
  # when referring to them.

  # Let&#39;s only see the numerical fields
  bash&gt; boson gem_search tag -f=n,do,version_d,v  # or --fields=name,downloads,version_downloads,version
  +---------------------+-----------+-------------------+-----------+
  | name                | downloads | version_downloads | version   |
  +---------------------+-----------+-------------------+-----------+
  | haml                | 85579     | 25097             | 2.2.17    |
  | libxml-ruby         | 21784     | 18180             | 1.1.3     |
  | win32-api           | 14809     | 3978              | 1.4.5     |
  | haml-edge           | 11241     | 3555              | 2.3.100   |
  # ...
  30 rows in set
&lt;/pre&gt;&lt;p&gt;Success! How about the pagination option and multi-word search we saw above? &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site/gemcutter.rb&quot;&gt;Source code&lt;/a&gt; says it all.&lt;/p&gt;
&lt;h2&gt;Wrap Up&lt;/h2&gt;
&lt;p&gt;As we&amp;#8217;ve seen with the gemcutter &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt; makes it dead easy to interface to an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; from the commandline. If you&amp;#8217;re interested in more boson-wrapped APIs, I&amp;#8217;d recommend &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#github_boson_library&quot;&gt;github&lt;/a&gt; or anything under &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site&quot;&gt;here&lt;/a&gt;. And if you don&amp;#8217;t already know, we can use any of these api commands in irb thanks to &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#shell_and_irb_duality&quot;&gt;boson&amp;#8217;s shell/irb duality&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
    
    
    
    
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>Typing Less in Irb with method_missing</title>
   <link href="http://tagaholic.me/2010/01/26/typing-less-in-irb-with-method_missing.html"/>
   <updated>2010-01-26T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2010/01/26/typing-less-in-irb-with-method_missing</id>
   <content type="html">&lt;p&gt;First off, Happy New Year! Now back to our regularly scheduled program.&lt;/p&gt;
&lt;p&gt;Being the console-efficient prick I am, let&amp;#8217;s look at a &lt;code&gt;method_missing&lt;/code&gt; that let&amp;#8217;s us type less where underscored methods are involved. This means that instead of typing &lt;code&gt;some_really_long_ass_method&lt;/code&gt; we can type the shortcut method &lt;code&gt;s_r_l_a_s&lt;/code&gt;. Instant aliasing! As you can see this works by typing the beginning letter of each word separated by underscores.&lt;/p&gt;
&lt;p&gt;So why do this if we have autocompletion? For starters, try typing the &lt;code&gt;Object&lt;/code&gt; method &lt;code&gt;instance_variable_get&lt;/code&gt; in five keystrokes (tabs included). Or for more inefficiency, try typing &lt;code&gt;ActiveRecord&lt;/code&gt; class methods that start with &lt;code&gt;before_*&lt;/code&gt; and &lt;code&gt;validate_*&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Explanation&lt;/h2&gt;
&lt;p&gt;To write this &lt;code&gt;method_missing&lt;/code&gt;, we&amp;#8217;re going to need a method that finds methods given a shortcut method we type:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;underscore_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;underscore_regex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Regexp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;escape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;([^_]+)?_&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;underscore_regex&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;escaped_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Regexp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;escape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;escaped_input&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you try this out in irb, it works as follows:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Doing the same as autocompletion would
  &gt;&gt; underscore_search &#39;si&#39;, %w{set_trace_func singleton_methods select}%
  =&gt; [&#39;singleton_methods&#39;]

  # Doing something autocompletion can&#39;t do
  &gt;&gt; underscore_search &#39;i_v_g&#39;, %w{instance_of? instance_variables instance_variable_get instance_eval}%
  =&gt; [&#39;instance_variable_get&#39;]

  # If our shortcut method is too broad we get multiple results
  &gt;&gt; underscore_search &#39;i_v&#39;, %w{instance_of? instance_variables instance_variable_get instance_eval}%
  =&gt; [&#39;instance_variables&#39;, &#39;instance_variable_get&#39;]

  # Multiple letters can be typed per underscore
  &gt;&gt; underscore_search &#39;re_o_ag&#39;, %w{reflect_on_aggregation reflect_on_association raise_on_association}
  =&gt; [&#39;reflect_on_aggregation&#39;]
&lt;/pre&gt;&lt;p&gt;Now that we have a way of querying underscore methods, let&amp;#8217;s wrap a method_missing around it:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;method_missing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;possible_methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sort&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;meths&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;underscore_search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;possible_methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;meths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Multiple methods match: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meths&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After pasting &lt;code&gt;method_missing()&lt;/code&gt; and &lt;code&gt;underscore_search()&lt;/code&gt; in irb:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Calls private_methods()
  &gt;&gt; pri_m
  =&gt; [...]

  # Method queries that match multiple methods don&#39;t get executed
  &gt;&gt; pr_m
  Multiple methods match: private_methods, protected_methods
  =&gt; nil

  # method_missing works as normal for method queries that don&#39;t match anything
  &gt;&gt; blah
  NameError: undefined local variable or method `blah&#39; for main:Object
          from /Users/bozo/.boson/commands/public/underscore_alias.rb:57:in `method_missing&#39;
          from (irb):8
&lt;/pre&gt;&lt;h2&gt;Finished Snippet&lt;/h2&gt;
&lt;p&gt;To make this snippet easy to apply to any object or class of objects, I wrapped &lt;code&gt;method_missing&lt;/code&gt;&lt;br /&gt;
into a module and did a little more meta programming. The result is &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/underscore_alias.rb&quot;&gt;this&lt;br /&gt;
module&lt;/a&gt;.&lt;br /&gt;
If you use &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;boson&lt;/a&gt; to manage your ruby snippets: &lt;code&gt;boson install
https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/underscore_alias.rb&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s how I use the finished snippet in a Rails console session:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; script/console

  # Load UnderscoreAlias
  &gt;&gt; load &#39;path/to/underscore_alias.rb&#39;
  # If using boson
  &gt;&gt; load_library &#39;underscore_alias&#39;

  # Let&#39;s give an ActiveRecord model class (i.e. Url) underscore aliasing abilities
  &gt;&gt; Url.extend UnderscoreAlias
  =&gt; Url

  # Call Url.original_table_name
  &gt;&gt; Url.o_t
  =&gt; &#39;urls&#39;

  # Call Url.columns_hash
  &gt;&gt; Url.col_h
  =&gt; {&quot;name&quot;=&gt; #&lt; ActiveRecord::ConnectionAdapters::MysqlColumn:0x23766d8 @type=:string, @precision=nil ...&gt;,
  &quot;updated_at&quot;=&gt; ...}

  # Now let&#39;s give ActiveRecord objects underscore aliasing abilities
  &gt;&gt; Url.send :include, UnderscoreAlias
  =&gt; Url

  # Call Url#to_json
  &gt;&gt; Url.first.t_j
  =&gt; &quot;{\&quot;url\&quot;:{\&quot;name\&quot;:\&quot;http://github.com\&quot;, ... }&quot;

  # Call Url#clear_association_cache
  &gt;&gt; Url.first.c_as
  =&gt; [...]

  # Call Url#has_attribute?
  &gt;&gt; Url.first.h_a &#39;name&#39;
  =&gt; true
&lt;/pre&gt;&lt;p&gt;When using the above snippet, you may find it annoying that sometimes a shortcut method results in a multiple choices that vary only by ending i.e. &lt;code&gt;updated_at? updated_at updated_at=&lt;/code&gt;. If only there was a way to autocomplete like this &amp;#8230; Actually, &lt;a href=&quot;http://github.com/cldwalker/bond&quot;&gt;bond&lt;/a&gt; &lt;a href=&quot;http://tagaholic.me/2009/07/16/bond-from-irb-with-completion-love.html#autocompletion_aliasing&quot;&gt;accomplished this a while ago&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now a general question to you all: Would you find it useful to apply this same instant aliasing technique to your rake/thor commandline tasks? For example, typing r:u:s instead of rails:update:scripts? I have found this instant aliasing technique to be quite handy with &lt;a href=&quot;http://github.com/cldwalkwer/boson&quot;&gt;boson&amp;#8217;s&lt;/a&gt; commands, arguments and options.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>Boson - Command Your Ruby Universe - Part Deux</title>
   <link href="http://tagaholic.me/2009/11/21/boson-command-your-ruby-universe-part-deux.html"/>
   <updated>2009-11-21T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2009/11/21/boson-command-your-ruby-universe-part-deux</id>
   <content type="html">&lt;p&gt;With the latest release of &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;Boson&lt;/a&gt;, there are a slew of new features that need some explaining. Yes, there is a &lt;a href=&#39;http://github.com/cldwalker/boson/tree/master/CHANGELOG.rdoc&#39;&gt;changelog&lt;/a&gt; and &lt;a href=&#39;http://tagaholic.me/boson/doc/&#39;&gt;documentation&lt;/a&gt;, but some of these features are novel enough that a good intro is in order.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s an overview of features:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#command_options&quot;&gt;Command Options&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#pipe_options&quot;&gt;Pipe Options&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#query_option&quot;&gt;Query Option&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#libraries&quot;&gt;Libraries&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#local_libraries&quot;&gt;Local Libraries&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#directory_spaced_libraries&quot;&gt;Directory-Spaced Libraries&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#social_libraries&quot;&gt;Social Libraries&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#plugin_libraries&quot;&gt;Plugin Libraries&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#invoking_commands&quot;&gt;Invoking Commands&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#library_dependencies&quot;&gt;Library Dependencies&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#option_parser&quot;&gt;Option Parser&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#option_to_object_mapper&quot;&gt;Option to Object Mapper&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#custom_option_types&quot;&gt;Custom Option Types&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#miscellaneous&quot;&gt;Miscellaneous&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#custom_consoles&quot;&gt;Custom Consoles&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#powerful_one_liners&quot;&gt;Powerful One-Liners&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#method_commandification&quot;&gt;Method Commandification&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;command_options&quot;&gt;&lt;a href=&quot;#command_options&quot;&gt;Command Options&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Boson is unique among command frameworks for providing commands with global options. Global options are options that are common to all commands (that enable options). There are three types of global options: &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/OptionCommand.html&quot;&gt;basic options&lt;/a&gt;, &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/View.html&quot;&gt;render options&lt;/a&gt; and &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Pipe.html&quot;&gt;pipe options&lt;/a&gt;. The first two were covered in &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html&quot;&gt;this previous post&lt;/a&gt;. Now let&amp;#8217;s a take a look at the newcomer, pipe options.&lt;/p&gt;
&lt;h3 id=&quot;pipe_options&quot;&gt;&lt;a href=&quot;#pipe_options&quot;&gt;Pipe Options&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Whereas render options generate different views from a command&amp;#8217;s return value, pipe options pipe a command&amp;#8217;s return value to command(s). Since a pipe option maps directly to a command, using piping options is much like piping between unix commands but asynchronously.&lt;/p&gt;
&lt;p&gt;For example, say we have pipe options &lt;code&gt;--browser&lt;/code&gt; and &lt;code&gt;--copy&lt;/code&gt; which given a url, open it in a browser and copy it to clipboard respectively:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; irb
  # Assume a command generate_url which returns a url string
  &gt;&gt; generate_url
  =&gt; &#39;http://example.com&#39;

  # With the assumed global pipe options, let&#39;s apply them to the return value of generate_url
  &gt;&gt; generate_url &#39;-bC&#39;   #  or generate_url &#39;--browser --copy&#39;
  =&gt; &#39;http://example.com&#39;

  # The above one liner is functionally equivalent to the following three lines
  &gt;&gt; url = generate_url
  &gt;&gt; browser(url)
  &gt;&gt; copy(url)

  # In a unix shell assuming boson commands are shell commands we could do the above as
  bash&gt; generate_url | browser
  bash&gt; generate_url | copy
&lt;/pre&gt;&lt;p&gt;Now that you understand what pipe options do, here&amp;#8217;s how you set it up:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s set up the commands for mac osx:
  # browser() already ships with boson.

  # Drop this in a library that gets loaded with :defaults config key
  def copy(str)
    IO.popen(&#39;pbcopy&#39;, &#39;w+&#39;) {|clipboard| clipboard.write(str)}
  end

  # Configure them in ~/.boson/config/boson.yml
  :pipe_options:
    :browser:
      :type: :boolean
      :desc: Open in browser
    :copy:
      :type: :boolean
      :desc: Copy to clipboard
&lt;/pre&gt;&lt;p&gt;As you&amp;#8217;ve noticed, pipe options are returning the command&amp;#8217;s original return value. To have pipe options behave like unix pipes (i.e. the return value changes per pipe), add a &lt;code&gt;:filter: true&lt;/code&gt; to a pipe option&amp;#8217;s config. &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Pipe.html&quot;&gt;See here&lt;/a&gt; for more pipe docs.&lt;/p&gt;
&lt;h3 id=&quot;query_option&quot;&gt;&lt;a href=&quot;#query_option&quot;&gt;Query Option&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As explained &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html&quot;&gt;at the end of a previous post&lt;/a&gt;, this option used to be &lt;code&gt;--query_fields&lt;/code&gt;. This option is a default pipe option that queries an array of anything with a search hash. Since this option is a :hash option type, &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/OptionParser.html&quot;&gt;check the docs&lt;/a&gt; for a syntax overview. Some examples with default commands:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # A query field is delimited from its query value with &#39;:&#39;
  # Like arrays, hash keys can be aliased if the field keys are known.
  bash&gt; boson commands -q=f:lib     # or commands --query=full_name:lib

  # With the new format all fields can be queried using a &#39;*&#39;.
  # Searches library fields: gems,dependencies,commands,loaded,module,name,namespace,indexed_namespace,library_type
  bash&gt; boson libraries -q=*:core   # or libraries --query=*:core

  # Multiple searches to be joined together by &#39;,&#39;. This query searches for libraries that
  # have the name matching core or a library_type matching gem.
  bash&gt; boson libraries -q=n:core,l:gem   # or libraries --query=name:core,library_type:gem
&lt;/pre&gt;&lt;p&gt;For examples of the different kinds of arrays that query can search, &lt;a href=&quot;/2009/11/07/ruby-reference-commands-with-boson.html&quot;&gt;see the previous post&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;libraries&quot;&gt;&lt;a href=&quot;#libraries&quot;&gt;Libraries&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Boson&amp;#8217;s libraries, which are just modules, are loaded by being included in &lt;code&gt;main&lt;/code&gt; &amp;#8216;s eigenclass. During its loading process, a module&amp;#8217;s include callbacks are called i.e. &lt;code&gt;included&lt;/code&gt; as well as boson-specific ones i.e. &lt;code&gt;after_included&lt;/code&gt;. &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Loader.html&quot;&gt;Read the docs&lt;/a&gt; for an explanation of these callbacks.&lt;/p&gt;
&lt;h3 id=&quot;local_libraries&quot;&gt;&lt;a href=&quot;#local_libraries&quot;&gt;Local Libraries&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Like most command frameworks, Boson now supports local command libraries. For just one library, simply create a Bosonfile and write commands as you would for any &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/FileLibrary.html&quot;&gt;Boson::FileLibrary&lt;/a&gt;. For multiple libraries, create the directory lib/boson/commands or .boson/commands and place libraries under the directory. For more, &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/LocalFileLibrary.html&quot;&gt;see the docs&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;directory_spaced_libraries&quot;&gt;&lt;a href=&quot;#directory_spaced_libraries&quot;&gt;Directory-Spaced Libraries&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Like &lt;a href=&quot;http://github.com/wycats/thor&quot;&gt;Thor&lt;/a&gt;, Boson has a central repository for its libraries so that the user can invoke commands from any directory. For Boson, these libraries are stored at ~/.boson/commands/. With this release, any subdirectory in this directory is automatically namespaced when loaded. What this means for the user is that they can create any number/depth of directories without worry that a module in one directory will conflict with a module in another. As an example say that I use the module &lt;code&gt;Misc&lt;/code&gt; in two different directories, ~/.boson/commands/public and ~/.boson/commands/personal. Boson will load &lt;code&gt;Misc&lt;/code&gt; as &lt;code&gt;Boson::Commands::Public::Misc&lt;/code&gt; and &lt;code&gt;Boson::Commands::Personal::Misc&lt;/code&gt; respectively. This makes it very convenient to collect and organize a large number of libraries. If it means anything, my &lt;a href=&quot;http://github.com/cldwalker/irbfiles&quot;&gt;main repository&amp;#8217;s&lt;/a&gt; current count is 87 libraries and 284 commands.&lt;/p&gt;
&lt;h3 id=&quot;social_libraries&quot;&gt;&lt;a href=&quot;#social_libraries&quot;&gt;Social Libraries&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#using_third_party_commands&quot;&gt;I explained before&lt;/a&gt;, Boson&amp;#8217;s libraries are easy to share with others. Simply give a url to a plain text version of your library and other users can install it. What I didn&amp;#8217;t explain was that you can customize any attribute of the library and its commands &lt;em&gt;without touching&lt;/em&gt; the installed library.&lt;/p&gt;
&lt;p&gt;For this example, we&amp;#8217;ll use &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#github_boson_library&quot;&gt;the github library&lt;/a&gt;. To install it:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/site/github.rb
  Saved to /Users/bozo/.boson/commands/github.rb

  # How one of the library&#39;s commands looks before we customize
  bash&gt; boson commands user_repo
  +------------+--------+-------+------------------------------------------------+--------------------------------+
  | full_name  | lib    | alias | usage                                          | description                    |
  +------------+--------+-------+------------------------------------------------+--------------------------------+
  | user_repos | github |       | [--user=cldwalker] [--fork_included] [--stats] | Displays a user&#39;s repositories |
  +------------+--------+-------+------------------------------------------------+--------------------------------+
  1 row in set
  
&lt;/pre&gt;&lt;p&gt;Let&amp;#8217;s add an alias and change the options and description of the above user_repos command:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Add entry under the :libraries key of config file ~/.boson/config/boson.yml
  :libraries:
    github:
      :commands:
        user_repos:
          :alias: guser
          :description: Github user page
          :options:
            :user: rails
    
  # Reindex library to pick up the config change
  bash&gt; boson -i=github commands user_repo  # or --index=github commands user_repo
  Indexing the following libraries: github
  Loaded library github
  +------------+--------+-------+--------------------------------------------+------------------+
  | full_name  | lib    | alias | usage                                      | description      |
  +------------+--------+-------+--------------------------------------------+------------------+
  | user_repos | github | guser | [--user=rails] [--fork_included] [--stats] | Github user page |
  +------------+--------+-------+--------------------------------------------+------------------+
  1 row in set

  # Calls user_repos defaulting to rails user
  bash&gt; boson guser
  +-------------------------+----------+-------+-----------------------------------+-------------------------------------------+
  | name                    | watchers | forks | homepage                          | description                               |
  +-------------------------+----------+-------+-----------------------------------+-------------------------------------------+
  | rails                   | 4468     | 718   | http://rubyonrails.org            | Ruby on Rails                             |
  | account_location        | 82       | 2     | http://rubyonrails.org            | Account Location Plugin                   |
  | acts_as_list            | 251      | 28    | http://rubyonrails.org            | ActsAsList plugin                         |
  | acts_as_nested_set      | 43       | 7     | http://rubyonrails.org            | ActsAsNestedSet                           |
  # ...
&lt;/pre&gt;&lt;p&gt;You&amp;#8217;ve just seen how Boson can customize command invocation via :alias and functionality via :options without modifying the command&amp;#8217;s source. Since commands are functionally equivalent to scripts, this has interesting implications for scripting. This basically allows us to use and preserve third-party scripts &lt;em&gt;without being bound&lt;/em&gt; to the author&amp;#8217;s naming/aliasing of commands and options. By preserving a script&amp;#8217;s source, we can update our third-party scripts when new versions come out. Perhaps Boson&amp;#8217;s script/command configuration will make scripting more social.&lt;/p&gt;
&lt;h3 id=&quot;invoking_commands&quot;&gt;&lt;a href=&quot;#invoking_commands&quot;&gt;Invoking Commands&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you don&amp;#8217;t already know, Boson&amp;#8217;s commands are just methods on &lt;code&gt;main&lt;/code&gt;, Ruby&amp;#8217;s top-level object. What this means is that the &lt;code&gt;self&lt;/code&gt; inside of any Boson command is &lt;code&gt;main&lt;/code&gt;. Once a command is loaded, it&amp;#8217;s available across libraries as a top-level method. For example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# Drop this in ~/.boson/commands/input.rb&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Input&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39; &amp;#39;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;gets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Now let&amp;#39;s use this in another library&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Quarantine&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# A boson callback to specify a library&amp;#39;s configuration&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dependencies&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;input&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Opens a reddit url in browser. Is it really worth it?&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reddit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Are you sure you want to do this to yourself? (y/N)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^y/i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;browser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see, there is no &lt;code&gt;Rake::Task[&#39;reddit&#39;].invoke(url)&lt;/code&gt; or &lt;code&gt;Quarantine.new.invoke(:reddit, url)&lt;/code&gt; as with Rake and Thor respectively. Invoking commands from different libraries is done in plain ruby per &lt;a href=&quot;/2009/10/19/how-boson-enhances-your-irb-experience.html#organization_and_philosophy&quot;&gt;Boson&amp;#8217;s philosophy&lt;/a&gt;. With this philosophy, you can still use these commands without Boson.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  &gt;&gt; obj = Object.new.extend(Input).extend(Quarantine)
  &gt;&gt; obj.reddit(&#39;lovely reddit url&#39;)
&lt;/pre&gt;&lt;h3 id=&quot;library_dependencies&quot;&gt;&lt;a href=&quot;#library_dependencies&quot;&gt;Library Dependencies&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the above command invocation example, you probably noticed that the quarantine library depends on the input library. Boson supports libraries depending on other libraries. This begins to show the collaborative and swappable nature of Boson libraries. Swappable in that you could swap one library for another as a dependency as long as it implements the same methods and api. Collaborative in that the functionality defined in one library can be made available to any another without modifying any code. Personally, this is is an improvement over having a directory full of scripts that can&amp;#8217;t communicate and depend on each other.&lt;/p&gt;
&lt;h3 id=&quot;plugin_libraries&quot;&gt;&lt;a href=&quot;#plugin_libraries&quot;&gt;Plugin Libraries&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While Boson has a number of features, you may want to add/modify some of them. No problem. Boson&amp;#8217;s &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Repo.html#M000079&quot;&gt;config file&lt;/a&gt; has a :defaults key to load up specified Boson libraries at startup. From the &lt;a href=&quot;#invoking_commands&quot;&gt;Invoking Commands section&lt;/a&gt;, if we wanted to make the &lt;code&gt;ask&lt;/code&gt; method available to all libraries, we would specify the input library under :defaults. For more examples, &lt;a href=&quot;http://github.com/cldwalker/irbfiles/tree/master/boson/commands/public/plugins&quot;&gt;see my plugins&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;option_parser&quot;&gt;&lt;a href=&quot;#option_parser&quot;&gt;Option Parser&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With this release, Boson&amp;#8217;s option parser is available for any Ruby scripts. For example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;boson&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Define options and parse them from ARGV into a hash&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:OptionParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:verbose&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:boolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:times&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:numeric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:boolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;$0 &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:OptionParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;usage&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Process remaining args in ARGV ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since Boson has dependencies, I&amp;#8217;d consider making Boson&amp;#8217;s OptionParser a separate gem if requested.&lt;/p&gt;
&lt;h3 id=&quot;option_to_object_mapper&quot;&gt;&lt;a href=&quot;#option_to_object_mapper&quot;&gt;Option to Object Mapper&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With this release, Boson&amp;#8217;s &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/OptionParser.html&quot;&gt;option parser&lt;/a&gt; has become an option-to-object mapper. To understand what that means, let&amp;#8217;s see Boson&amp;#8217;s five default option types and the Ruby objects they create. First, we create a library:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# Drop in ~/.boson/commands/option_test.rb&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;OptionTest&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:numeric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:boolean&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# The default for :hash has to be passed as a :default attribute since hashes&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# are already reserved for setting option attributes.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;yo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testin2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, back in the shell:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Each option type maps to a different ruby object. The classes of most of these objects
  # match directly to the option type&#39;s name.
  bash&gt; boson testin -a=1,2 -b a:b,c:d -c=hey -d 1 -e
  {:e=&gt;true, :d=&gt;1, :b=&gt;{&quot;a&quot;=&gt;&quot;b&quot;, &quot;c&quot;=&gt;&quot;d&quot;}, :c=&gt;&quot;hey&quot;, :a=&gt;[&quot;1&quot;, &quot;2&quot;]}
  {:e=&gt;TrueClass, :d=&gt;Fixnum, :b=&gt;Hash, :c=&gt;String, :a=&gt;Array}

  # Each option type has an expected format it uses for converting to an object as indicated
  # by the usage.
  bash&gt; boson testin -h
  testin [-c=C] [-d=N] [-e] [-a=A,B,C] [-b=A:B,C:D]

  # When options are defined with default values, the parser uses the default value&#39;s class to determine
  # the appropriate option type.
  # As expected, whatever option isn&#39;t set has its default value set.
  bash&gt; boson testin2 -b=z:y -d=2.1
  {:e=&gt;false, :d=&gt;2.1, :b=&gt;{&quot;z&quot;=&gt;&quot;y&quot;}, :c=&gt;&quot;yo&quot;, :a=&gt;[1, 2]}
  {:e=&gt;FalseClass, :d=&gt;Float, :b=&gt;Hash, :c=&gt;String, :a=&gt;Array}  
&lt;/pre&gt;&lt;p&gt;As you can see, an option type maps to objects of one or more Ruby classes i.e. :array &amp;#8594; Array and :numeric &amp;#8594; Float or Fixnum. But what if you want to create objects of other classes?&lt;/p&gt;
&lt;h3 id=&quot;custom_option_types&quot;&gt;&lt;a href=&quot;#custom_option_types&quot;&gt;Custom Option Types&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To define an option type that creates objects of your choice, you only need to define the method that creates the object. Here&amp;#8217;s a basic example to create a :date option type that creates Date objects:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# Drop this in ~/.boson/commands/date.rb&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Then make this library a plugin by putting it&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# under :defaults key in the main config&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Date&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;no&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;today&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:OptionParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Date&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# ====&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Now in any library we can use the :date option type ...&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Drop this in ~/.boson/commands/date_test.rb&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DateTest&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:date&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;day_of_week&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; falls on a &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:DAYNAMES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cwday&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# to define :day with a default we could modify options to be:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# options :day=&amp;gt;Date.today&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now to try &lt;code&gt;day_of_week&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson day_of_week -d 12/25   # or day_of_week --date 12/25
  2009-12-25 falls on a Friday

  # Default usage for new option type
  bash&gt; boson day_of_week -h
  day_of_week [--day=:date]
&lt;/pre&gt;&lt;p&gt;As you saw, simply creating a method with the name create_@type in the option parser made the option type available. If you want to add validation or custom usage for a new option type, &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Options.html&quot;&gt;see the docs&lt;/a&gt;. When creating your own option types, you may find it cleaner to define your options &lt;a href=&quot;#plugin_libraries&quot;&gt;in a plugin library&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;miscellaneous&quot;&gt;&lt;a href=&quot;#miscellaneous&quot;&gt;Miscellaneous&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now for some miscellaneous features.&lt;/p&gt;
&lt;h3 id=&quot;custom_consoles&quot;&gt;&lt;a href=&quot;#custom_consoles&quot;&gt;Custom Consoles&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Being able to start irb around certain setups you use often can be quite handy. Good examples of this are Rails&amp;#8217; script/console and the more recent &lt;a href=&quot;#http://github.com/sickill/racksh&quot;&gt;racksh&lt;/a&gt;. Boson makes it easy to start irb with specified Boson libraries loaded:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Assuming you have a library github
  bash&gt; boson -l=g -c   # or boson --load=github --console

  # Assuming you have libraries misc and ruby_ref
  bash&gt; boson -l=m,r -c  # or boson --load=misc,ruby_ref --console
  
  # Irb can require libraries in a more verbose way but it *doesn&#39;t*
  # load Boson libraries as commands
  bash&gt; irb -I ~/.boson/commands -r misc -r ruby_ref
&lt;/pre&gt;&lt;h3 id=&quot;powerful_one_liners&quot;&gt;&lt;a href=&quot;#powerful_one_liners&quot;&gt;Powerful One-Liners&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Much like &lt;code&gt;ruby -e&lt;/code&gt;, you can do a &lt;code&gt;boson -e&lt;/code&gt; with any ruby code. The big difference is that &lt;em&gt;any&lt;/em&gt; Boson command is available and loaded lazily automatically:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Drop in ~/.boson/commands/objects.rb
  module Objects
    def objects(klass)
      object = []
      ObjectSpace.each_object(klass) {|e| object.push(e) }
      object
    end
  end

  # Prints number of String objects
  bash&gt; boson -e &#39;p objects(String).size&#39;  # or boson --execute &#39;p objects(String).size&#39;
  56573

  # Prints default classes not including its defaults
  bash&gt; boson -e &#39;p objects(Class).select {|e| e.to_s !~ /^(Boson|Alias|Hirb)/ }&#39;
  [Gem::LoadError, Struct::Group, Struct::Passwd, SizedQueue, Queue, ConditionVariable, Mutex, Gem::Builder, Gem::SourceIndex, Binding,
   UnboundMethod, Method, Proc, SystemStackError, LocalJumpError, Struct::Tms, Process::Status, Time, Dir, File::Stat, File, IO, EOFError,
   IOError, Range, MatchData, Regexp, RegexpError, Struct, Hash, Array, Errno::EDQUOT, Errno::ESTALE, Errno::EINPROGRESS, Errno::EALREADY
  # ...
&lt;/pre&gt;&lt;h3 id=&quot;method_commandification&quot;&gt;&lt;a href=&quot;#method_commandification&quot;&gt;Method Commandification&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This feature redefines a method to act like a shell command using &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Scientist.html#M000034&quot;&gt;Boson::Scientist.commandify&lt;/a&gt;. This means that a method can take any number of arguments and options as one string. Since Boson commands already do this automatically, this feature is for those who want to give this functionality to any method:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  &gt;&gt; def checkit(*args); args; end
  =&gt; nil
  &gt;&gt; Boson::Scientist.commandify(self, :name=&gt;&#39;checkit&#39;, :options=&gt;{:verbose=&gt;:boolean, :num=&gt;:numeric})
  =&gt; [&#39;checkit&#39;]
  # regular invocation
  &gt;&gt; checkit &#39;one&#39;, &#39;two&#39;, :num=&gt;13, :verbose=&gt;true
  =&gt; [&quot;one&quot;, &quot;two&quot;, {:num=&gt;13, :verbose=&gt;true}]
  # commandline invocation
  &gt;&gt; checkit &#39;one two -v -n=13&#39;
  =&gt; [&quot;one&quot;, &quot;two&quot;, {:num=&gt;13, :verbose=&gt;true}]
&lt;/pre&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>Ruby Reference Commands With Boson</title>
   <link href="http://tagaholic.me/2009/11/07/ruby-reference-commands-with-boson.html"/>
   <updated>2009-11-07T00:00:00-08:00</updated>
   <id>http://tagaholic.me/2009/11/07/ruby-reference-commands-with-boson</id>
   <content type="html">&lt;p&gt;Continuing where &lt;a href=&quot;http://tagaholic.me/2009/10/15/boson-and-hirb-interactions.html&quot;&gt;this post&lt;/a&gt; left off, we&amp;#8217;ll look at more examples of the unique command and view framework interaction that &lt;a href=&#39;http://tagaholic.me/boson/&#39;&gt;Boson&lt;/a&gt; and &lt;a href=&#39;http://tagaholic.me/hirb/&#39;&gt;Hirb&lt;/a&gt; have. In particular, we&amp;#8217;ll look at commands that are useful references to your current Ruby environment. Since Boson&amp;#8217;s commands are just methods in a module, any of these commands work fine in irb without &lt;a href=&#39;http://github.com/cldwalker/boson&#39;&gt;Boson&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Game Plan&lt;/h2&gt;
&lt;p&gt;We&amp;#8217;ll be looking at my &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/ruby_ref.rb&quot;&gt;ruby_ref library&lt;/a&gt; and commands that reference:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#global_variables&quot;&gt;Global variables&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#loaded_paths&quot;&gt;Loaded paths and their respective full paths&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#gem_versions&quot;&gt;Gems and their versions&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#object_instance_variables&quot;&gt;Any object&amp;#8217;s instance variables&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#rbconfig&quot;&gt;RbConfig&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For all these commands, I will only show the original ruby method. To see the Boson configuration for each, see the &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/ruby_ref.rb&quot;&gt;library source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To follow along with the examples using boson:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  $ gem install boson boson-more
  $ echo &quot;require &#39;boson/more&#39;&quot; &gt;&gt; ~/.bosonrc
  $ boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/ruby_ref.rb
&lt;/pre&gt;&lt;h2 id=&quot;global_variables&quot;&gt;&lt;a href=&quot;#global_variables&quot;&gt;Global Variables&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As we all know, Ruby comes with &lt;a href=&quot;http://www.zenspider.com/Languages/Ruby/QuickRef.html#16&quot;&gt;predefined global variables&lt;/a&gt;. Using the &lt;code&gt;Kernel&lt;/code&gt; method &lt;code&gt;global_variables&lt;/code&gt; to retrieve them, here&amp;#8217;s a simple method to list global variables and their values:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;global_var&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;global_variables&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When Boson commandifies this method here&amp;#8217;s what happens:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson global_var
  +---------------------------+----------------------------------------------------------------------------------------------------+
  | variable                  | value                                                                                              |
  +---------------------------+----------------------------------------------------------------------------------------------------+
  | $!                        | nil                                                                                                |
  | $&quot;                        | [&quot;rubygems/defaults.rb&quot;, &quot;thread.bundle&quot;, &quot;thread.rb&quot;, &quot;etc.bundle&quot;, &quot;rbconfig.rb&quot;, &quot;rubygems/e... |
  | $$                        | 33292                                                                                              |
  | $&amp;                        | nil                                                                                                |
  | $&#39;                        | nil                                                                                                |
  | $*                        | []                                                                                                 |
  # ...
  48 rows in set

  # Alphabetical sort on the value column
  bash&gt; boson global_var &#39;-s=val&#39;   # global_var &#39;--sort=value&#39;
  +---------------------------+----------------------------------------------------------------------------------------------------+
  | variable                  | value                                                                                              |
  +---------------------------+----------------------------------------------------------------------------------------------------+
  | $FILENAME                 | &quot;-&quot;                                                                                                |
  | $0                        | &quot;/usr/bin/boson&quot;                                                                                   |
  | $PROGRAM_NAME             | &quot;/usr/bin/boson&quot;                                                                                   |
  | $-K                       | &quot;UTF8&quot;                                                                                             |
  | $KCODE                    | &quot;UTF8&quot;                                                                                             |
  | $/                        | &quot;\n&quot;                                                                                               |
  | $-0                       | &quot;\n&quot;                                                                                               |  
  # ...
  48 rows in set

  # Boson has a new global command option --query which allows us to search inside of a table&#39;s fields
  bash&gt; boson global_var &#39;-q=var:load&#39;   # global_var &#39;--query=variable:load&#39;
  +------------------+-------------------------------------------------------------------------------------------------------------+
  | variable         | value                                                                                                       |
  +------------------+-------------------------------------------------------------------------------------------------------------+
  | $LOADED_FEATURES | [&quot;rubygems/defaults.rb&quot;, &quot;thread.bundle&quot;, &quot;thread.rb&quot;, &quot;etc.bundle&quot;, &quot;rbconfig.rb&quot;, &quot;rubygems/exceptions... |
  | $LOAD_PATH       | [&quot;/Users/bozo/code/gems/bond/lib&quot;, &quot;/Users/bozo/code/gems/boson/lib&quot;, &quot;/Users/bozo/code/gems/alias/lib&quot;,... |
  +------------------+-------------------------------------------------------------------------------------------------------------+
  2 rows in set

  # If you&#39;re new to Boson, we can do any of the above from irb as well
  bash&gt; irb
  &gt;&gt; global_var &#39;-q=var:load&#39;   # global_var &#39;--query=variable:load&#39;
  +------------------+-------------------------------------------------------------------------------------------------------------+
  | variable         | value                                                                                                       |
  +------------------+-------------------------------------------------------------------------------------------------------------+
  | $LOADED_FEATURES | [&quot;rubygems/defaults.rb&quot;, &quot;thread.bundle&quot;, &quot;thread.rb&quot;, &quot;etc.bundle&quot;, &quot;rbconfig.rb&quot;, &quot;rubygems/exceptions... |
  | $LOAD_PATH       | [&quot;/Users/bozo/code/gems/bond/lib&quot;, &quot;/Users/bozo/code/gems/boson/lib&quot;, &quot;/Users/bozo/code/gems/alias/lib&quot;,... |
  +------------------+-------------------------------------------------------------------------------------------------------------+
  2 rows in set
  =&gt; true
&lt;/pre&gt;&lt;p&gt;As you can see, Boson took a simple one-line method and made it a useful command that searches, sorts and displays global variables and their values.&lt;/p&gt;
&lt;h2 id=&quot;loaded_paths&quot;&gt;&lt;a href=&quot;#loaded_paths&quot;&gt;Loaded Paths&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;$LOADED_FEATURES&lt;/code&gt; (&lt;code&gt;$&quot;&lt;/code&gt;) and &lt;code&gt;$LOAD_PATH&lt;/code&gt; (&lt;code&gt;$:&lt;/code&gt;) are handy global variables that give us required paths and the directories we can require from. Although we don&amp;#8217;t know the full paths to the required files, it&amp;#8217;s easy to calculate them with these global variables:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loaded_paths&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;vg&quot;&gt;$&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;vg&quot;&gt;$:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;?e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
          &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This method gives us a hash mapping the required paths to their full paths. Let&amp;#8217;s see what Boson does with this:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  &gt;&gt; loaded_paths &#39;-s=req&#39;  # loaded_paths &#39;--sort=require_path&#39;
  +----------------------------------------------------+---------------------------------------------------------------------------+
  | require_path                                       | full_path                                                                 |
  +----------------------------------------------------+---------------------------------------------------------------------------+
  | alias.rb                                           | /Users/bozo/code/gems/alias/lib/alias.rb                                  |
  | alias/console.rb                                   | /Users/bozo/code/gems/alias/lib/alias/console.rb                          |
  | alias/creator.rb                                   | /Users/bozo/code/gems/alias/lib/alias/creator.rb                          |
  | alias/creators/any_to_instance_method_creator.rb   | /Users/bozo/code/gems/alias/lib/alias/creators/any_to_instance_method_... |
  | alias/creators/class_method_creator.rb             | /Users/bozo/code/gems/alias/lib/alias/creators/class_method_creator.rb    |
  | alias/creators/class_to_instance_method_creator.rb | /Users/bozo/code/gems/alias/lib/alias/creators/class_to_instance_metho... |
  | alias/creators/constant_creator.rb                 | /Users/bozo/code/gems/alias/lib/alias/creators/constant_creator.rb        |
  | alias/creators/instance_method_creator.rb          | /Users/bozo/code/gems/alias/lib/alias/creators/instance_method_creator.rb |
  | alias/manager.rb                                   | /Users/bozo/code/gems/alias/lib/alias/manager.rb                          |
  # ...
  128 rows in set
  =&gt; true

  &gt;&gt; loaded_paths &#39;-q=req:bundle   # loaded_paths &#39;--query=require_path:bundle&#39;
  +-----------------------------+---------------------------------------------------------------------------------------------------------------+
  | require_path                | full_path                                                                                                     |
  +-----------------------------+---------------------------------------------------------------------------------------------------------------+
  | digest.bundle               | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/digest.bundle     |
  | digest/md5.bundle           | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/digest/md5.bundle |
  | etc.bundle                  | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/etc.bundle        |
  | readline.bundle             | /Library/Ruby/Site/1.8/universal-darwin9.0/readline.bundle                                                    |
  | readline_line_buffer.bundle | /Users/bozo/code/gems/bond/lib/readline_line_buffer.bundle                                                    |
  | stringio.bundle             | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/stringio.bundle   |
  | syck.bundle                 | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/syck.bundle       |
  | thread.bundle               | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/thread.bundle     |
  +-----------------------------+---------------------------------------------------------------------------------------------------------------+
  8 rows in set
  =&gt; true

  # We can always toggle rendering on a command to get the method&#39;s return value with --render
  &gt;&gt; load_path(&#39;--render&#39;).values.slice(0,5)
  =&gt; [&quot;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0/syck.bundle&quot;,
   &quot;/Users/bozo/code/gems/bond/lib/bond/missions/default_mission.rb&quot;, &quot;/Users/bozo/code/gems/boson/lib/boson/libraries/file_library.rb&quot;,
   &quot;/Users/bozo/code/gems/hirb/lib/hirb/menu.rb&quot;, &quot;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/ostruct.rb&quot;]
&lt;/pre&gt;&lt;h2 id=&quot;gem_versions&quot;&gt;&lt;a href=&quot;#gem_versions&quot;&gt;Gem Versions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For any number of reasons, it can be handy to know the versions of the gems you&amp;#8217;re using. Since most gems don&amp;#8217;t come with a &lt;code&gt;VERSION&lt;/code&gt; constant, the easiest way to get their version is from their loaded gemspec. But since not everything we use nowadays comes as a gem i.e. rip packages, we could also extract the versions from $LOAD_PATH. Here&amp;#8217;s a command that can do either one of these depending on the presence of a :loaded_path option:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gem_versions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:loaded_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;vg&quot;&gt;$:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/\/([\w-]+)-(\d\.\d(\.\d)?)\/lib/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;vg&quot;&gt;$2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compact&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniq&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Gem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loaded_specs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;#8217;s see it in action:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Using gemspecs to get the versions
  &gt;&gt; gem_versions
  +-----------------------+---------+
  | name                  | version |
  +-----------------------+---------+
  | matthew-method_lister | 0.2.3   |
  | mynyml-every          | 0.6     |
  | local_gem             | 0.1.1   |
  | duration              | 0.1.0   |
  +-----------------------+---------+
  4 rows in set
  =&gt; true

  # Using $: to get the versions
  &gt;&gt; gem_versions &#39;-l&#39;  # gem_versions &#39;--loaded_path&#39;  or gem_versions :loaded_path=&gt;true
  +-----------------------+---------+
  | name                  | version |
  +-----------------------+---------+
  | local_gem             | 0.1.1   |
  | matthew-method_lister | 0.2.3   |
  | duration              | 0.1.0   |
  | mynyml-every          | 0.6     |
  +-----------------------+---------+
  4 rows in set
  =&gt; true

  # How does this command look inside a Rails&#39; irb session?
  &gt;&gt; gem_versions &#39;-s=n&#39;   # gem_versions &#39;--sort=name&#39;
  +----------------------------+---------+
  | name                       | version |
  +----------------------------+---------+
  | RedCloth                   | 4.2.1   |
  | actionmailer               | 2.2.2   |
  | actionpack                 | 2.2.2   |
  | activerecord               | 2.2.2   |
  | activeresource             | 2.2.2   |
  | activesupport              | 2.2.2   |
  | alias                      | 0.2.1   |
  | cldwalker-has_machine_tags | 0.1.3   |
  | duration                   | 0.1.0   |
  | hirb                       | 0.2.7   |
  | local_gem                  | 0.1.1   |
  | matthew-method_lister      | 0.2.3   |
  | mynyml-every               | 0.6     |
  | rails                      | 2.2.2   |
  | rake                       | 0.8.7   |
  +----------------------------+---------+
  15 rows in set
  =&gt; true
&lt;/pre&gt;&lt;h2 id=&quot;object_instance_variables&quot;&gt;&lt;a href=&quot;#object_instance_variables&quot;&gt;Object Instance Variables&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Whether you&amp;#8217;re getting acquainted with a new class of objects or just trying to figure an object&amp;#8217;s current state, looking at an object&amp;#8217;s instance variables can be useful. Here&amp;#8217;s a command that gives us any object&amp;#8217;s instance variables and their values:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;instance_var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance_variables&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance_variable_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Using this with Boson:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s start with a Boson::Command object
  &gt;&gt; instance_var Boson.commands[0]
  +-------------------+-------------------------------+
  | instance          | value                         |
  +-------------------+-------------------------------+
  | @lib              | &quot;core&quot;                        |
  | @name             | &quot;usage&quot;                       |
  | @options          | {[:verbose, :V]=&gt;:boolean}    |
  | @args             | [[&quot;name&quot;], [&quot;options&quot;, &quot;{}&quot;]] |
  | @file_parsed_args | true                          |
  | @description      | &quot;Print a command&#39;s usage&quot;     |
  +-------------------+-------------------------------+
  6 rows in set
  =&gt; true

  # How about the bigger Gem::Specification object?
  &gt;&gt; instance_var Gem.loaded_specs.values[0], &#39;-s=i&#39;  #  or &#39;--sort=instance&#39;
  +----------------------------+-----------------------------------------------------------------------------------------------------------------------+
  | instance                   | value                                                                                                                 |
  +----------------------------+-----------------------------------------------------------------------------------------------------------------------+
  | @authors                   | [&quot;Matthew O&#39;Connor&quot;]                                                                                                  |
  | @autorequire               | nil                                                                                                                   |
  | @bindir                    | &quot;bin&quot;                                                                                                                 |
  | @cert_chain                | []                                                                                                                    |
  | @date                      | Mon Oct 27 00:00:00 -0400 2008                                                                                        |
  | @default_executable        | nil                                                                                                                   |
  | @dependencies              | []                                                                                                                    |
  | @description               | nil                                                                                                                   |
  | @email                     | &quot;matthew @nospam@ canonical.org&quot;                                                                                      |
  | @executables               | []                                                                                                                    |
  | @extensions                | []                                                                                                                    |
  | @extra_rdoc_files          | [&quot;README.markdown&quot;]                                                                                                   |
  | @files                     | [&quot;lib/method_lister/color_display.rb&quot;, &quot;lib/method_lister/find_result.rb&quot;, &quot;lib/method_lister/finder.rb&quot;, &quot;lib/met... |
  | @has_rdoc                  | true                                                                                                                  |
  | @homepage                  | &quot;http://github.com/matthew/method_lister/tree/master&quot;                                                                 |
  | @licenses                  | []                                                                                                                    |
 # ...
 35 rows in set
 =&gt; true

 #  Search instances containing files
 &gt;&gt; instance_var Gem.loaded_specs.values[0], &#39;-q=i:files&#39;   #  or &#39;--query=instance:files&#39;
 +-------------------+--------------------------------------------------------------------------------------------------------------------------------+
 | instance          | value                                                                                                                          |
 +-------------------+--------------------------------------------------------------------------------------------------------------------------------+
 | @files            | [&quot;lib/method_lister/color_display.rb&quot;, &quot;lib/method_lister/find_result.rb&quot;, &quot;lib/method_lister/finder.rb&quot;, &quot;lib/method_liste... |
 | @test_files       | [&quot;spec/color_display_spec.rb&quot;, &quot;spec/find_result_spec.rb&quot;, &quot;spec/finder_spec.rb&quot;, &quot;spec/ruby_ext_spec.rb&quot;, &quot;spec/simple_dis... |
 | @extra_rdoc_files | [&quot;README.markdown&quot;]                                                                                                            |
 +-------------------+--------------------------------------------------------------------------------------------------------------------------------+
 3 rows in set
 =&gt; true

 # So what if want to see everything inside the value field?
 &gt;&gt; instance_var Gem.loaded_specs.values[0], &#39;-q=i:files -V&#39;   # or &#39;--query=instance:files --vertical&#39;
 ************ 1. row ************
 instance: @files
    value: [&quot;lib/method_lister/color_display.rb&quot;, &quot;lib/method_lister/find_result.rb&quot;, &quot;lib/method_lister/finder.rb&quot;,
  &quot;lib/method_lister/ruby_ext.rb&quot;, &quot;lib/method_lister/simple_display.rb&quot;, &quot;lib/method_lister.rb&quot;, &quot;spec/color_display_spec.rb&quot;,
  &quot;spec/find_result_spec.rb&quot;, &quot;spec/finder_spec.rb&quot;, &quot;spec/helpers/matchers/list_methods.rb&quot;,
  &quot;spec/helpers/object_mother/find_result.rb&quot;, &quot;spec/helpers/object_mother/find_scenario.rb&quot;, &quot;spec/rcov.opts&quot;, &quot;spec/ruby_ext_spec.rb&quot;,
  &quot;spec/scenarios/class_with_inheritance.rb&quot;, &quot;spec/scenarios/class_with_inheritance_and_modules.rb&quot;, &quot;spec/scenarios/eigenclass.rb&quot;,
  &quot;spec/scenarios/eigenclass_with_modules.rb&quot;, &quot;spec/scenarios/filters_results_without_methods.rb&quot;,
  &quot;spec/scenarios/mixed_visibility_methods.rb&quot;, &quot;spec/scenarios/object_without_eigenclass.rb&quot;, &quot;spec/scenarios/overloaded_methods.rb&quot;
  &quot;spec/scenarios/overloaded_methods_with_modules_mixed_in.rb&quot;, &quot;spec/scenarios/private_methods.rb&quot;, &quot;spec/scenarios/single_class.rb&quot;,
  &quot;spec/scenarios/single_class_with_module_mixed_in.rb&quot;, &quot;spec/simple_display_spec.rb&quot;, &quot;spec/spec.opts&quot;, &quot;spec/spec_helper.rb&quot;,
   &quot;README.markdown&quot;]
 ************ 2. row ************
 instance: @test_files
    value: [&quot;spec/color_display_spec.rb&quot;, &quot;spec/find_result_spec.rb&quot;, &quot;spec/finder_spec.rb&quot;, &quot;spec/ruby_ext_spec.rb&quot;,
  &quot;spec/simple_display_spec.rb&quot;]
 ************ 3. row ************
 instance: @extra_rdoc_files
    value: [&quot;README.markdown&quot;]
 3 rows in set
 =&gt; true 
&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;pp&lt;/code&gt; method from the standard library is another good alternative for displaying an object&amp;#8217;s instance variables. Personally, I find the fact that any class can customize their &lt;code&gt;pp&lt;/code&gt; output to be a strength but also a weakness. The weakness lies in that formatting of objects become inconsistent across classes and there&amp;#8217;s no guarantee that &lt;code&gt;pp&lt;/code&gt;  will give you all instance variables. Also, to get a good overview of an object I think it helps to stick to one instance variable per line.&lt;/p&gt;
&lt;h2 id=&quot;rbconfig&quot;&gt;&lt;a href=&quot;#rbconfig&quot;&gt;RbConfig&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you have ever had to ensure a gem works across multiple platforms, you&amp;#8217;ve probably encountered &lt;code&gt;RbConfig&lt;/code&gt;. This module, which is generated by mkconfig.rb when your ruby is built, contains a hash constant, &lt;code&gt;CONFIG&lt;/code&gt;, containing platform-specific configuration. So let&amp;#8217;s make a command that simply points to this config hash:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rbconfig&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rbconfig&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;RbConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:CONFIG&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From the above, we already know we can display, search and sort data structures pretty easily. So let&amp;#8217;s just focus on searching features that have been dormant til now:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # We know we can search in a field
  bash&gt; boson rbconfig -q=n:arch    # or --query=name:arch
  +-------------+---------------------------------------------------------------------------------------------+
  | name        | value                                                                                       |
  +-------------+---------------------------------------------------------------------------------------------+
  | archdir     | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 |
  | sitearch    | universal-darwin9.0                                                                         |
  | arch        | universal-darwin9.0                                                                         |
  | sitearchdir | /Library/Ruby/Site/1.8/universal-darwin9.0                                                  |
  | ARCHFILE    |                                                                                             |
  | ARCH_FLAG   |                                                                                             |
  +-------------+---------------------------------------------------------------------------------------------+
  6 rows in set

  # But you can also search in all fields with &#39;*&#39;
  bash&gt; boson rbconfig -q=*:arch    # or --query=name,value:arch
  +------------------+---------------------------------------------------------------------------------------------+
  | name             | value                                                                                       |
  +------------------+---------------------------------------------------------------------------------------------+
  | archdir          | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 |
  | sitearch         | universal-darwin9.0                                                                         |
  | arch             | universal-darwin9.0                                                                         |
  | sitearchdir      | /Library/Ruby/Site/1.8/universal-darwin9.0                                                  |
  | ARCHFILE         |                                                                                             |
  | ARCH_FLAG        |                                                                                             |
  | LDSHARED         | cc -arch ppc -arch i386 -pipe -bundle -undefined dynamic_lookup                             |
  | LDFLAGS          | -L. -arch ppc -arch i386                                                                    |
  | LIBRUBY_LDSHARED | cc -arch ppc -arch i386 -pipe -dynamiclib                                                   |
  | CFLAGS           | -arch ppc -arch i386 -Os -pipe -fno-common                                                  |
  +------------------+---------------------------------------------------------------------------------------------+
  10 rows in set

  # Searches are regular expressions
  bash&gt; boson rbconfig -q=n:ruby$   # or --query=name:ruby$
  +----------+--------------------------------------------------+
  | name     | value                                            |
  +----------+--------------------------------------------------+
  | LIBRUBY  | libruby.1.dylib                                  |
  | MINIRUBY | ./miniruby                                       |
  | RUNRUBY  | ./miniruby $(srcdir)/runruby.rb --extout=.ext -- |
  +----------+--------------------------------------------------+
  3 rows in set

  # Multiple searches can be joined together by a comma
  bash&gt; boson rbconfig -q=n:ruby$,v:package  # or --query=name:ruby$,value:package
  +----------+---------------------------------------------------------------------------------+
  | name     | value                                                                           |
  +----------+---------------------------------------------------------------------------------+
  | LIBRUBY  | libruby.1.dylib                                                                 |
  | MINIRUBY | ./miniruby                                                                      |
  | RUNRUBY  | ./miniruby $(srcdir)/runruby.rb --extout=.ext --                                |
  | docdir   | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/share/doc/$(PACKAGE) |
  | dvidir   | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/share/doc/$(PACKAGE) |
  | psdir    | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/share/doc/$(PACKAGE) |
  | htmldir  | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/share/doc/$(PACKAGE) |
  | pdfdir   | /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/share/doc/$(PACKAGE) |
  +----------+---------------------------------------------------------------------------------+
  8 rows in set
&lt;/pre&gt;&lt;h2&gt;Game Over&lt;/h2&gt;
&lt;p&gt;As you can see, Boson does a decent job of turning simple methods into useful commands. In these examples, we saw the return values of these commands converted into well-formatted, sortable and searchable tables without adding &lt;em&gt;any&lt;/em&gt; code. If you look at &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/ruby_ref.rb&quot;&gt;the library source&lt;/a&gt; you will see commented &lt;code&gt;render_options&lt;/code&gt; calls for each command. These are what hooked into Boson to give us all this functionality. To understand how this all works and create your own similar commands, &lt;a href=&quot;http://tagaholic.me/boson/doc/&quot;&gt;check out the Boson docs&lt;/a&gt; and the &lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/Helpers/Table.html&quot;&gt;Hirb table docs&lt;/a&gt;. If you want to check out more libraries like this, &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/&quot;&gt;there are plenty&lt;/a&gt;. If you have ruby reference commands/methods, feel free to share them below.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
 <entry>
   <title>How Boson Enhances Your Irb Experience</title>
   <link href="http://tagaholic.me/2009/10/19/how-boson-enhances-your-irb-experience.html"/>
   <updated>2009-10-19T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2009/10/19/how-boson-enhances-your-irb-experience</id>
   <content type="html">&lt;p&gt;In &lt;a href=&#39;/2009/10/14/boson-command-your-ruby-universe.html&#39;&gt;previous&lt;/a&gt; &lt;a href=&#39;/2009/10/15/boson-and-hirb-interactions.html&#39;&gt;posts&lt;/a&gt;, &lt;a href=&#39;http://tagaholic.me/boson/&#39;&gt;Boson&lt;/a&gt; was introduced as a command framework, usable from the commandline and irb. In this post, we&amp;#8217;ll focus on how &lt;a href=&#39;http://github.com/cldwalker/boson&#39;&gt;Boson&lt;/a&gt; enhances irb by treating methods like shell commands.&lt;/p&gt;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;re an avid irb user &lt;a href=&quot;http://github.com/cldwalker/irbfiles&quot;&gt;like me&lt;/a&gt;, your ~/.irbrc is littered with methods. These methods are sometimes favorite tweaks to Ruby&amp;#8217;s core libraries and sometimes interfaces to gems. But regardless of what they represent, when you use them they&amp;#8217;re just like shell commands. With this user in mind, Boson aims to give methods command-like functionality. This means giving a method the ability to have &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#commands_with_options&quot;&gt;simple yet powerful options&lt;/a&gt;. This means &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#just_alias_it&quot;&gt;aliasing&lt;/a&gt; and annotating methods are commonplace. This means &lt;a href=&quot;#core_commands&quot;&gt;searching&lt;/a&gt; and &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#using_third_party_commands&quot;&gt;sharing your commands&lt;/a&gt; with others are easy to do. And if you want, you can even give a method &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html&quot;&gt;instant views&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the order we&amp;#8217;ll be covering using Boson with irb:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#setup&quot;&gt;Setup&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#organization_and_philosophy&quot;&gt;Organization and Philosophy&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#core_commands&quot;&gt;Core Commands&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#commands&quot; title=&quot;&quot;&gt;commands&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#libraries&quot; title=&quot;&quot;&gt;libraries&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#load_library&quot; title=&quot;&quot;&gt;load_library&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#boson_libraries&quot;&gt;Boson Libraries&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#gem_library&quot;&gt;Gem Library&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#require_library&quot;&gt;Require Library&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#module_library&quot;&gt;Module Library&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#migrating_your_irb_commands&quot;&gt;Migrating Your Irb Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;setup&quot;&gt;&lt;a href=&quot;#setup&quot;&gt;Setup&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To use Boson in irb, drop this in your ~/.irbrc. For any other ruby console application the setup is the same:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;boson&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Boson.start&lt;/code&gt; comes with &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/ConsoleRunner.html#M000064&quot;&gt;some options&lt;/a&gt;. If you don&amp;#8217;t like that Boson tells you every library it loads, set &lt;code&gt;:verbose=&amp;gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;organization_and_philosophy&quot;&gt;&lt;a href=&quot;#organization_and_philosophy&quot;&gt;Organization and Philosophy&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When Boson starts, it loads libraries of commands. &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Library.html&quot;&gt;Boson libraries&lt;/a&gt; are just Ruby modules and &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Command.html&quot;&gt;Boson commands&lt;/a&gt; are just methods in those modules. Most libraries are in their own file under ~/.boson/commands. Each library can have an optional namespace defined in a config file. With this organization commands are &lt;em&gt;independent&lt;/em&gt; of Boson. There are no &lt;code&gt;namespace&lt;/code&gt;  dsl methods as with Rake and no required Thor subclassing as with &lt;a href=&quot;http://github.com/wycats/thor&quot;&gt;Thor&lt;/a&gt;. This is on purpose. Boson strives to allow &lt;em&gt;all&lt;/em&gt; of its functionality to be written in plain ruby. This way you are free to easily test your commands and use them with other applications &lt;em&gt;independent&lt;/em&gt; of Boson. Also, if you decided to stop using Boson, all libraries you&amp;#8217;ve built for it can still be used in irb without modifying them. To do this you would simply extend your library&amp;#8217;s modules into Ruby&amp;#8217;s top-level object &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;core_commands&quot;&gt;&lt;a href=&quot;#core_commands&quot;&gt;Core Commands&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Boson comes with a handful of core commands but let&amp;#8217;s focus on three you&amp;#8217;ll probably use the most: &lt;code&gt;commands&lt;/code&gt;, &lt;code&gt;libraries&lt;/code&gt; and &lt;code&gt;load_library&lt;/code&gt;. Since these commands have options, you should &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#boson_commands_global_options&quot;&gt;familiarize yourself&lt;/a&gt; with the default global options they have. Also, you should be aware that &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#aliasing_option_values&quot;&gt;option values can be aliased&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;commands&quot;&gt;&lt;a href=&quot;#commands&quot; title=&quot;&quot;&gt;commands&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This command searches your commands in a myriad of ways.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # With no arguments commands() lists all loaded commands
  &gt;&gt; commands
  +------------------------+----------------------+-------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
  | full_name              | lib                  | alias | usage                                                                     | description                                                               |
  +------------------------+----------------------+-------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
  | usage                  | core                 |       | [name][--verbose]                                                         | Print a command&#39;s usage                                                   |
  | libraries              | core                 | lib   | [query=&#39;&#39;][--index] [--query_fields=name]                                 | List or search libraries                                                  |
  | render                 | core                 | v     | [object] [options={}]                                                     | Render any object using Hirb                                              |
  | load_library           | core                 | ll    | [library][--verbose] [--reload]                                           | Load/reload a library                                                     |
  | commands               | core                 | com   | [query=&#39;&#39;][--index] [--query_fields=full_name]                            | List or search commands                                                   |
  | menu                   | core                 |       | [output] [options={}] [&amp;block]                                            | Provide a menu to multi-select elements from a given array                |
  # ...

  # By default searches in a command&#39;s full_name
  &gt;&gt; commands &#39;usa&#39;
  +-----------+------+-------+-------------------+-------------------------+
  | full_name | lib  | alias | usage             | description             |
  +-----------+------+-------+-------------------+-------------------------+
  | usage     | core |       | [name][--verbose] | Print a command&#39;s usage |
  +-----------+------+-------+-------------------+-------------------------+
  1 row in set

  # Since searches are regular expressions, we can search multiple terms
  &gt;&gt; commands &#39;usa|lib&#39;
  +--------------------+-------+-------+-------------------------------------------+---------------------------------------------+
  | full_name          | lib   | alias | usage                                     | description                                 |
  +--------------------+-------+-------+-------------------------------------------+---------------------------------------------+
  | usage              | core  |       | [name][--verbose]                         | Print a command&#39;s usage                     |
  | libraries          | core  | lib   | [query=&#39;&#39;][--index] [--query_fields=name] | List or search libraries                    |
  | load_library       | core  | ll    | [library][--verbose] [--reload]           | Load/reload a library                       |
  +--------------------+-------+-------+-------------------------------------------+---------------------------------------------+
  3 rows in set
  =&gt; true

  # Before we can use a command&#39;s options we have to know what options it has
  &gt;&gt; commands &#39;-h&#39;  # or commands &#39;--help&#39;
  commands [query=&#39;&#39;][--index]
  =&gt; nil
  # another way of getting a command&#39;s usage
  &gt;&gt; usage &#39;commands&#39;

  # To search full_name and description fields for &#39;lib&#39;
  &gt;&gt; commands &#39;full_name,description:lib&#39;
  +--------------------+----------+-------+-------------------------------------------------------------------------------+-----------------------------------------------------------------------------+
  | full_name          | lib      | alias | usage                                                                         | description                                                                 |
  +--------------------+----------+-------+-------------------------------------------------------------------------------+-----------------------------------------------------------------------------+
  | libraries          | core     | lib   | [query=&#39;&#39;][--index] [--query_fields=name]                                     | List or search libraries                                                    |
  | load_library       | core     | ll    | [library][--verbose] [--reload]                                               | Load/reload a library                                                       |
  | install            | web_core |       | [url][--force] [--module_wrap] [--name=NAME] [--method_wrap]                  | Installs a library by url. Library should then be loaded with load_library. |  
 +--------------------+----------+-------+-------------------------------------------------------------------------------+-----------------------------------------------------------------------------+
  3 rows in set
  =&gt; true

  # With option name and value aliasing, the above can also be
  &gt;&gt; commands &#39;lib -q=f,d&#39;
&lt;/pre&gt;&lt;p&gt;Since &lt;code&gt;commands()&lt;/code&gt; comes with &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html#boson_commands_global_options&quot;&gt;Boson&amp;#8217;s global rendering options&lt;/a&gt;, commands can be sorted by command attribute and have only certain attributes displayed.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Before sorting and selecting command attributes, we need to know what attributes we can choose from in our options.
  # Let&#39;s call up verbose help:
  &gt;&gt; commands &#39;-hv&#39;    # or commands &#39;--help --verbose&#39;
  commands [query=&#39;&#39;][--index]

  COMMAND OPTIONS
  +----------------+-------+---------+-------------------+------------------------------------------------------------------------+
  | Option         | Alias | type    | Description       | Values                                                                 |
  +----------------+-------+---------+-------------------+------------------------------------------------------------------------+
  | --index        | -i    | boolean | Searches index    |                                                                        |
  +----------------+-------+---------+-------------------+------------------------------------------------------------------------+

  GLOBAL/RENDER OPTIONS
  +----------------+-------+---------+-----------------------------------------------------------+------------------------------------------------------------------------+
  | Option         | Alias | type    | Description                                               | Values                                                                 |
  +----------------+-------+---------+-----------------------------------------------------------+------------------------------------------------------------------------+
  | --class        | -c    | string  | Hirb helper class which renders                           |                                                                        |
  | --fields       | -f    | array   | Displays fields in the order given                        | name,lib,alias,description,options,args,usage,full_name,render_options |
  | --help         | -h    | boolean | Display a command&#39;s help                                  |                                                                        |
  | --max_width    | -m    | numeric | Max width of a table                                      |                                                                        |
  | --pretend      | -p    | boolean | Display what a command would execute without executing it |                                                                        |
  | --render       | -r    | boolean | Toggle a command&#39;s default rendering behavior             |                                                                        |
  | --reverse_sort | -R    | boolean | Reverse a given sort                                      |                                                                        |
  | --sort         | -s    | string  | Sort by given field                                       | name,lib,alias,description,options,args,usage,full_name,render_options |
  | --verbose      | -v    | boolean | Increase verbosity for help, errors, etc.                 |                                                                        |
  | --vertical     | -V    | boolean | Display a vertical table                                  |                                                                        |
  +----------------+-------+---------+-----------------------------------------------------------+------------------------------------------------------------------------+
  =&gt; nil

  # Looking under values column, we can see the available values for --sort and --fields i.e.
  # name,lib,alias,description,options,args,usage,full_name,render_options
  # To sort by library
  &gt;&gt; commands &#39;--sort=lib&#39;     # or commands &#39;-s=l&#39;
  +--------------+----------+-------+--------------------------------------------------------------+-----------------------------------------------------------------------------+
  | full_name    | lib      | alias | usage                                                        | description                                                                 |
  +--------------+----------+-------+--------------------------------------------------------------+-----------------------------------------------------------------------------+
  | usage        | core     |       | [name][--verbose]                                            | Print a command&#39;s usage                                                     |
  | libraries    | core     | lib   | [query=&#39;&#39;][--index] [--query_fields=name]                    | List or search libraries                                                    |
  | render       | core     | v     | [object] [options={}]                                        | Render any object using Hirb                                                |
  | load_library | core     | ll    | [library][--verbose] [--reload]                              | Load/reload a library                                                       |
  | commands     | core     | com   | [query=&#39;&#39;][--index] [--query_fields=full_name]               | List or search commands                                                     |
  | menu         | core     |       | [output] [options={}] [&amp;block]                               | Provide a menu to multi-select elements from a given array                  |
  | get          | web_core |       | [url] [options={}]                                           | Gets the body of a url                                                      |
  # ...

  # To reverse sort
  &gt;&gt; commands &#39;--sort=lib --reverse_sort&#39;     # or commands &#39;-s=l -R&#39;
  +--------------+----------+-------+--------------------------------------------------------------+-----------------------------------------------------------------------------+
  | full_name    | lib      | alias | usage                                                        | description                                                                 |
  +--------------+----------+-------+--------------------------------------------------------------+-----------------------------------------------------------------------------+
  | browser      | web_core |       | [*urls]                                                      | Opens urls in a browser on a Mac                                            |
  | install      | web_core |       | [url][--force] [--module_wrap] [--name=NAME] [--method_wrap] | Installs a library by url. Library should then be loaded with load_library. |
  | post         | web_core |       | [url] [options={}]                                           | Posts to url                                                                |
  | get          | web_core |       | [url] [options={}]                                           | Gets the body of a url                                                      |
  | menu         | core     |       | [output] [options={}] [&amp;block]                               | Provide a menu to multi-select elements from a given array                  |
  # ...

  # To only display command attributes full_name and description
  &gt;&gt; commands &#39;--fields=full_name,description    # or commands &#39;-f=f,d&#39;
  +--------------+-----------------------------------------------------------------------------+
  | full_name    | description                                                                 |
  +--------------+-----------------------------------------------------------------------------+
  | usage        | Print a command&#39;s usage                                                     |
  | libraries    | List or search libraries                                                    |
  | render       | Render any object using Hirb                                                |
  | load_library | Load/reload a library                                                       |
  | commands     | List or search commands                                                     |
  | menu         | Provide a menu to multi-select elements from a given array                  |
  | get          | Gets the body of a url                                                      |
  | post         | Posts to url                                                                |
  | install      | Installs a library by url. Library should then be loaded with load_library. |
  | browser      | Opens urls in a browser on a Mac                                            |
  +--------------+-----------------------------------------------------------------------------+
  10 rows in set
  =&gt; true

  # Don&#39;t forget that rendering can be switched off to give us the actual command objects. Any of the above
  # examples could yield command objects if prefixed with --render.
  &gt;&gt; commands(&#39;--render usa|lib&#39;).size   # or commands &#39;-r usa|lib&#39;
  =&gt; 3
&lt;/pre&gt;&lt;h3 id=&quot;libraries&quot;&gt;&lt;a href=&quot;#libraries&quot; title=&quot;&quot;&gt;libraries&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Like &lt;a href=&quot;#commands&quot;&gt;commands&lt;/a&gt;, libraries can be searched, sorted and displayed with a number of library attributes:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # These examples are specific to my libraries.
  
  # To find out valid library attributes and option values
  &gt;&gt; libraries &#39;-hv&#39;
  # ...

  # Sort by name
  &gt;&gt; libraries &#39;--sort=name&#39;     # or libraries &#39;-s=n&#39;
  +----------------------+----------+-----------------------+--------------+
  | name                 | commands | gems                  | library_type |
  +----------------------+----------+-----------------------+--------------+
  | alias                | 6        |                       | file         |
  | boson                | 10       |                       | file         |
  | boson_method_missing | 3        |                       | file         |
  | completion           | 3        |                       | file         |
  # ...

  # See the module for each library
  &gt;&gt; libraries &#39;--fields=name,module&#39;  # or libraries &#39;-f=n,m&#39;
  +----------------------+-------------------------------------+
  | name                 | module                              |
  +----------------------+-------------------------------------+
  | core                 | Boson::Commands::Core               |
  | web_core             | Boson::Commands::WebCore            |
  | boson_method_missing | Boson::Commands::BosonMethodMissing |
  | completion           | Boson::Commands::Completion         |
  | alias                | Boson::Commands::AliasLib           |
  # ...
  
  # Search inside all libraries (that Boson has indexed)
  # for libraries of type gem
  &gt;&gt; libraries &#39;library_type:gem --index&#39;  # or libraries &#39;l:gem -i&#39;
  +---------------+----------+--------------------------------------------+--------------+
  | name          | commands | gems                                       | library_type |
  +---------------+----------+--------------------------------------------+--------------+
  | httparty      | 2        | httparty,crack                             | gem          |
  | method_lister | 3        | matthew-method_lister                      | gem          |
  | sketches      | 5        | sketches                                   | gem          |
  | andand        | 4        | andand                                     | gem          |
  | local_gem     | 2        | local_gem                                  | gem          |
  | what_methods  | 2        | what_methods                               | gem          |
  | unroller      | 1        | colored,unroller,quality_extensions,facets | gem          |
  | restclient    | 1        | adamwiggins-rest-client                    | gem          |
  +---------------+----------+--------------------------------------------+--------------+
  8 rows in set
  =&gt; true
&lt;/pre&gt;&lt;h3 id=&quot;load_library&quot;&gt;&lt;a href=&quot;#load_library&quot; title=&quot;&quot;&gt;load_library&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This command loads a library and its commands. This allows you to load the bare minimum functionality you need in irb and then load commands as needed.&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Verify the desired ri command doesn&#39;t exist yet
  &gt;&gt; ri &#39;method_mis&#39;
  NameError: undefined local variable or method `ri&#39; for main:Object
          from (irb):1

  # Load my ri library and its commands
  &gt;&gt; load_library &#39;ri&#39;
  Loaded library ri
  =&gt; true

  &gt;&gt; ri &#39;method_mis&#39;
  +--------+------------------------------------+
  | number | full_name                          |
  +--------+------------------------------------+
  | 1      | DRb::DRbObject#method_missing      |
  | 2      | Delegator#method_missing           |
  | 3      | Kernel#method_missing              |
  | 4      | REXML::Functions::method_missing   |
  | 5      | REXML::QuickPath::method_missing   |
  | 6      | SOAP::SOAPReference#method_missing |
  +--------+------------------------------------+
  6 rows in set
  Choose:
  # ...
&lt;/pre&gt;&lt;p&gt;To make your life even easier, you can put Boson in a mode where unloaded commands are automatically loaded once they&amp;#8217;re executed. How does this work? Since commands are just methods on &lt;code&gt;main&lt;/code&gt;, Boson redefines &lt;code&gt;main&lt;/code&gt; &amp;#8217;s method_missing &amp;#8230;&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # To enable this you need to modify your ~/.irbrc:
  # Boson.start :autoload_libraries=&gt;true

  # Assuming irb doesn&#39;t have the ri command again
  &gt;&gt; ri &#39;method_mes&#39;
  Loaded library &#39;ri&#39;
  +--------+------------------------------------+
  | number | full_name                          |
  +--------+------------------------------------+
  | 1      | DRb::DRbObject#method_missing      |
  | 2      | Delegator#method_missing           |
  | 3      | Kernel#method_missing              |
  | 4      | REXML::Functions::method_missing   |
  | 5      | REXML::QuickPath::method_missing   |
  | 6      | SOAP::SOAPReference#method_missing |
  +--------+------------------------------------+
  6 rows in set
  Choose:
  # ...
&lt;/pre&gt;&lt;h2 id=&quot;boson_libraries&quot;&gt;&lt;a href=&quot;#boson_libraries&quot;&gt;Boson Libraries&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Up to now, &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Library.html&quot;&gt;Boson libraries&lt;/a&gt; have been described as a module sitting in a file. While this type of library, a &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/FileLibrary.html&quot;&gt;Boson::FileLibrary&lt;/a&gt; is the most common and functionally-rich, there are other library types.&lt;/p&gt;
&lt;h3 id=&quot;gem_library&quot;&gt;&lt;a href=&quot;#gem_library&quot;&gt;Gem Library&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/GemLibrary.html&quot;&gt;Boson::GemLibrary&lt;/a&gt; makes commands from a gem. Let&amp;#8217;s see this library in action by loading the &lt;a href=&quot;http://sketches.rubyforge.org/&quot;&gt;sketches gem&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Without any configuration, let&#39;s load sketches as a library
  &gt;&gt; load_library &#39;sketches&#39;
  Loaded library sketches
  =&gt; true

  # Let&#39;s see what commands Boson picked up
  &gt;&gt; commands &#39;l:sket&#39;   # or commands &#39;lib:sket&#39;
  +-------------+----------+-------+-------+-------------+
  | full_name   | lib      | alias | usage | description |
  +-------------+----------+-------+-------+-------------+
  | sketch_from | sketches |       |       |             |
  | name_sketch | sketches |       |       |             |
  | save_sketch | sketches |       |       |             |
  | sketches    | sketches |       |       |             |
  | sketch      | sketches |       |       |             |
  +-------------+----------+-------+-------+-------------+
  5 rows in set

  # Begin sketching
  &gt;&gt; sketch
  # ...
&lt;/pre&gt;&lt;p&gt;Is sketches already built to work with Boson? Not quite. Rather, this demonstrates how Boson safeguards &lt;code&gt;main&lt;/code&gt; by tracking what gems dump in &lt;code&gt;Object&lt;/code&gt; and &lt;code&gt;Kernel&lt;/code&gt;. Unfortunately this is all too common with irb-related gems. Now let&amp;#8217;s use &lt;a href=&quot;http://github.com/jnunemaker/httparty&quot;&gt;a gem&lt;/a&gt; that doesn&amp;#8217;t dump methods on us:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Create commands put and delete from HTTParty&#39;s API.
  # Values of :class_commands hash can point to any ruby code ending with a method call.
  &gt;&gt; load_library &#39;httparty&#39;, :class_commands=&gt;{&#39;put&#39;=&gt;&#39;HTTParty.put&#39;, &#39;delete&#39;=&gt;&#39;HTTParty.delete&#39; }
  =&gt; true

  &gt;&gt; commands &#39;l:http&#39;  # or commands &#39;lib:http&#39;
  +-----------+----------+-------+-------+-------------+
  | full_name | lib      | alias | usage | description |
  +-----------+----------+-------+-------+-------------+
  | blank?    | httparty |       |       |             |
  | dclone    | httparty |       |       |             |
  | delete    | httparty |       |       |             |
  | put       | httparty |       |       |             |
  +-----------+----------+-------+-------+-------------+
  4 rows in set
  =&gt; true

  # Well, we spoke to soon. blank? and dclone are again monkeypatched methods.
  # If you&#39;d rather have Boson not detect these methods for you:
  # load_library &#39;httparty&#39;, :object_methods=&gt;false, :class_commands ...

  # To avoid typing out configurations for each gem you use, save them in the config file
  # ~/.boson/config/boson.yml under the :libraries key :
  #
  # :libraries:
  #   httparty:
  #     :class_commands:
  #       put: HTTParty.put
  #       delete: HTTParty.delete

  # Next irb session we can just load httparty and use our preconfigured commands
  bash&gt; irb
  &gt;&gt; load_library &#39;httparty&#39;
  =&gt; true

  &gt;&gt; put &#39;http://blah/blah&#39;
  # ...
&lt;/pre&gt;&lt;h3 id=&quot;require_library&quot;&gt;&lt;a href=&quot;#require_library&quot;&gt;Require Library&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/RequireLibrary.html&quot;&gt;Boson::RequireLibrary&lt;/a&gt; makes its commands centered around any require-able library (i.e. standard libraries and &lt;a href=&quot;http://github.com/defunkt/rip&quot;&gt;rip&lt;/a&gt; packages):&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s make a command from the standard library abbrev
  &gt;&gt; load_library &#39;abbrev&#39;, :class_commands=&gt;{&#39;abbrev&#39;=&gt;&#39;Abbrev.abbrev&#39;}, :command_aliases=&gt;{&#39;abbrev&#39;=&gt;&#39;ab&#39;}
  =&gt; true

  # abbrev() shows a hash of all unique strings that abbreviate an array
  &gt;&gt; abbrev %w{awesome audacious asinine}
  =&gt; {&quot;audacious&quot;=&gt;&quot;audacious&quot;, &quot;asini&quot;=&gt;&quot;asinine&quot;, &quot;aw&quot;=&gt;&quot;awesome&quot;, &quot;asi&quot;=&gt;&quot;asinine&quot;, &quot;awesome&quot;=&gt;&quot;awesome&quot;, &quot;awe&quot;=&gt;&quot;awesome&quot;,
    &quot;aweso&quot;=&gt;&quot;awesome&quot;, &quot;asin&quot;=&gt;&quot;asinine&quot;, &quot;aud&quot;=&gt;&quot;audacious&quot;, &quot;audaci&quot;=&gt;&quot;audacious&quot;, &quot;asinin&quot;=&gt;&quot;asinine&quot;, &quot;audacio&quot;=&gt;&quot;audacious&quot;,
    &quot;awesom&quot;=&gt;&quot;awesome&quot;, &quot;as&quot;=&gt;&quot;asinine&quot;, &quot;audac&quot;=&gt;&quot;audacious&quot;, &quot;audaciou&quot;=&gt;&quot;audacious&quot;, &quot;awes&quot;=&gt;&quot;awesome&quot;, &quot;asinine&quot;=&gt;&quot;asinine&quot;,
    &quot;au&quot;=&gt;&quot;audacious&quot;, &quot;auda&quot;=&gt;&quot;audacious&quot;}

  # Even though we haven&#39;t hooked up abbrev() to Boson/Hirb rendering
  # we can still use it with the default command render
  &gt;&gt; render ab(%w{awesome audacious asinine}).sort
  +-----------+-----------+
  | 0         | 1         |
  +-----------+-----------+
  | as        | asinine   |
  | asi       | asinine   |
  | asin      | asinine   |
  | asini     | asinine   |
  | asinin    | asinine   |
  | asinine   | asinine   |
  # ...

  # Let&#39;s make irb feel more like a shell with fileutils
  &gt;&gt; load_library &#39;fileutils&#39;, :class_commands=&gt;%w{cd cp ln mv chmod}.inject({}) {|h,e| h[e] = &quot;FileUtils.#{e}&quot;; h}
  =&gt; true

  # Let&#39;s see what commands we have now
  &gt;&gt; commands &#39;l:fileu&#39;   # or commands &#39;lib:fileu&#39;
  +-----------+-----------+-------+-------+-------------+
  | full_name | lib       | alias | usage | description |
  +-----------+-----------+-------+-------+-------------+
  | chmod     | fileutils |       |       |             |
  | ln        | fileutils |       |       |             |
  | cd        | fileutils |       |       |             |
  | cp        | fileutils |       |       |             |
  | mv        | fileutils |       |       |             |
  +-----------+-----------+-------+-------+-------------+
  5 rows in set
  =&gt; true
&lt;/pre&gt;&lt;h3 id=&quot;module_library&quot;&gt;&lt;a href=&quot;#module_library&quot;&gt;Module Library&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/ModuleLibrary.html&quot;&gt;Boson::ModuleLibrary&lt;/a&gt; simply makes commands from a module&amp;#8217;s class methods:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  &gt;&gt; load_library Math, :commands=&gt;%w{sin cos tan}
  =&gt; true

  &gt;&gt; commands &#39;l:math&#39;    # or commands &#39;lib:math&#39;
  +-----------+------+-------+-------+-------------+
  | full_name | lib  | alias | usage | description |
  +-----------+------+-------+-------+-------------+
  | cos       | math |       |       |             |
  | sin       | math |       |       |             |
  | tan       | math |       |       |             |
  +-----------+------+-------+-------+-------------+
  3 rows in set

  # Let&#39;s brush up on ol trig
  &gt;&gt; sin (Math::PI/2)
  =&gt; 1.0
  &gt;&gt; tan (Math::PI/4)
  =&gt; 1.0
  # Close enough :)
  &gt;&gt; cos (Math::PI/2)
  =&gt; 6.12323399573677e-17
&lt;/pre&gt;&lt;h2 id=&quot;migrating_your_irb_commands&quot;&gt;&lt;a href=&quot;#migrating_your_irb_commands&quot;&gt;Migrating Your Irb Commands&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before migrating your methods or irb commands, remember Boson&amp;#8217;s &lt;a href=&quot;#organization_and_philosophy&quot;&gt;philosophy&lt;/a&gt;. Whatever time you spend organizing your irbrc isn&amp;#8217;t in vain. You can always take what you&amp;#8217;ve made and use it without Boson.&lt;/p&gt;
&lt;p&gt;The easiest way to migrate is to simply wrap all your irbrc methods in a module and explicitly pass that module to &lt;code&gt;Boson.start&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# in ~/.irbrc&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Easy&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;command1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;boson&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Boson&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:libraries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Easy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The downside to this is that your commands don&amp;#8217;t have &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#commands_with_options&quot;&gt;options&lt;/a&gt; or &lt;a href=&quot;/2009/10/15/boson-and-hirb-interactions.html&quot;&gt;views&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want those features and still want the simplest thing possible, put all your methods in a module and drop that module into a file under ~/.boson/commands/.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re serious about organizing your irbrc, you should break your methods up into libraries. If any of your methods are simply wrappers around a gem or a require-able library, consider making a &lt;a href=&quot;#gem_library&quot;&gt;gem library&lt;/a&gt; or a &lt;a href=&quot;#require_library&quot;&gt;require library&lt;/a&gt;. Otherwise make each library by wrapping it in a module and placing it in under ~/.boson/commands/.&lt;/p&gt;
&lt;p&gt;Next you should consider adding aliases and descriptions to your commands. &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#aliasing_commands&quot;&gt;Command aliasing is explained here&lt;/a&gt;. To add a command description, simply add a comment &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#creating_commands&quot;&gt;directly above it&lt;/a&gt;. If your description spans multiple lines than use the desc method attribute:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;#@desc My description spans multiple lines&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#  because I have a lot to say and&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#  not enough space to say it&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;talk&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lastly, you should decide which libraries to load at startup. The default is to load all libraries. You&amp;#8217;ll probably want to change that once your libraries load multiple gems. To specify these libraries, open up Boson&amp;#8217;s main config file at ~/.boson/config/boson.yml. Add a &lt;code&gt;:console_defaults&lt;/code&gt; key and give it an array of libraries. &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/config/boson.yml&quot;&gt;See my config file&lt;/a&gt; as an example.&lt;/p&gt;
&lt;h2&gt;Postface&lt;/h2&gt;
&lt;p&gt;In this post, we&amp;#8217;ve seen how Boson treats methods like shell commands. In doing so, it makes irb (or any ruby console) a simple yet powerful method-based shell. For more traditional ruby shell implementations, see &lt;a href=&quot;http://github.com/hayeah/rubish/&quot;&gt;rubish&lt;/a&gt;, &lt;a href=&quot;http://github.com/adamwiggins/rush&quot;&gt;rush&lt;/a&gt; and &lt;a href=&quot;http://www.creo.hu/~csaba/ruby/pope/&quot;&gt;pope&lt;/a&gt;. If you&amp;#8217;re interested in giving autocompletion to your commands, check out &lt;a href=&quot;/2009/07/16/bond-from-irb-with-completion-love.html&quot;&gt;Bond&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
    
    
    
    
 <entry>
   <title>Boson And Hirb Interactions</title>
   <link href="http://tagaholic.me/2009/10/15/boson-and-hirb-interactions.html"/>
   <updated>2009-10-15T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2009/10/15/boson-and-hirb-interactions</id>
   <content type="html">&lt;p&gt;In &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html&quot;&gt;the last post&lt;/a&gt;, I introduced &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;Boson&lt;/a&gt; and its &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#commands_with_options&quot;&gt;options for commands&lt;/a&gt;. What I didn&amp;#8217;t mention was that Boson also gives those commands default options. Among them are ones to control rendering a command&amp;#8217;s output with &lt;a href=&quot;http://tagaholic.me/hirb/&quot;&gt;Hirb&lt;/a&gt; and even toggle rendering. At the flick of a switch, Boson commands (Ruby methods) can have Hirb&amp;#8217;s views.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/post-quark_anti_quark_collision.jpg&quot; alt=&quot;particle interaction&quot; width=&quot;350&quot; height=&quot;250&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;hirbs_handy_tables&quot;&gt;&lt;a href=&quot;#hirbs_handy_tables&quot;&gt;Hirb&amp;#8217;s Handy Tables&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Back in &lt;a href=&quot;/2009/06/19/page-irb-output-and-improve-ri-with-hirb.html&quot;&gt;an old post&lt;/a&gt;, I concluded with a mention that Hirb&amp;#8217;s &lt;code&gt;table()&lt;/code&gt; can handle arrays of about any object (responding to &lt;code&gt;to_s&lt;/code&gt;). Unless you read &lt;a href=&quot;http://tagaholic.me/hirb/doc/classes/Hirb/Helpers/Table.html&quot;&gt;the docs&lt;/a&gt; or tests, that probably didn&amp;#8217;t register much. So let&amp;#8217;s see it in action:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; irb
  &gt;&gt; require &#39;hirb&#39;; extend Hirb::Console
  =&gt; main

  # Basic array or anything that responds to :to_a
  &gt;&gt; table 1..3
  +-------+
  | value |
  +-------+
  | 1     |
  | 2     |
  | 3     |
  +-------+
  3 rows in set
  =&gt; true

  # Array of arrays
  &gt;&gt; table (1..5).map {|e| [e, Math.sqrt(e)] }
  +----+------------------+
  | 0  | 1                |
  +----+------------------+
  | 1  | 1.0              |
  | 2  | 1.4142135623731  |
  | 3  | 1.73205080756888 |
  | 4  | 2.0              |
  | 5  | 2.23606797749979 |
  +----+------------------+
  5 rows in set
  =&gt; true

  # Array of hashes
  &gt;&gt; table [{:name=&gt;&#39;Brain&#39;, :occupation=&gt;&#39;Take over the world&#39;}, {:name=&gt;&#39;Batman&#39;, :occupation=&gt;&#39;Save the world&#39;},
    {:name=&gt;&#39;Joker&#39;, :occupation=&gt;&#39;Destroy the world&#39;}, {:name=&gt;&#39;Pinky&#39;, :occupation=&gt;&#39;Annoy Brain&#39;}]
  +--------+---------------------+
  | name   | occupation          |
  +--------+---------------------+
  | Brain  | Take over the world |
  | Batman | Save the world      |
  | Joker  | Destroy the world   |
  | Pinky  | Annoy Brain         |
  +--------+---------------------+
  4 rows in set
  =&gt; true

  # Choose only certain keys of hashes with :fields
  &gt;&gt; table [{:name=&gt;&#39;Brain&#39;, :occupation=&gt;&#39;Take over the world&#39;}, {:name=&gt;&#39;Batman&#39;, :occupation=&gt;&#39;Save the world&#39;},
    {:name=&gt;&#39;Joker&#39;, :occupation=&gt;&#39;Destroy the world&#39;}, {:name=&gt;&#39;Pinky&#39;, :occupation=&gt;&#39;Annoy Brain&#39;}],
    :fields=&gt;[:name]
  +--------+
  | name   |
  +--------+
  | Brain  |
  | Batman |
  | Joker  |
  | Pinky  |
  +--------+
  4 rows in set
  =&gt; true

  # Array of Date objects, stringified by to_s()
  &gt;&gt; table (1..5).map {|e| Date.today + e }
  +------------+
  | 0          |
  +------------+
  | 2009-10-15 |
  | 2009-10-16 |
  | 2009-10-17 |
  | 2009-10-18 |
  | 2009-10-19 |
  +------------+
  5 rows in set
  =&gt; true

  # Passing :fields on any object simply calls its methods
  # Comparing Date formats:
  &gt;&gt; table (1..5).map {|e| Date.today + e }, :fields=&gt;[:to_s, :ajd, :civil, :jd, :mjd]
  +------------+-----------+----------+---------+-------+
  | to_s       | ajd       | civil    | jd      | mjd   |
  +------------+-----------+----------+---------+-------+
  | 2009-10-15 | 4910239/2 | 20091015 | 2455120 | 55119 |
  | 2009-10-16 | 4910241/2 | 20091016 | 2455121 | 55120 |
  | 2009-10-17 | 4910243/2 | 20091017 | 2455122 | 55121 |
  | 2009-10-18 | 4910245/2 | 20091018 | 2455123 | 55122 |
  | 2009-10-19 | 4910247/2 | 20091019 | 2455124 | 55123 |
  +------------+-----------+----------+---------+-------+
  5 rows in set
  =&gt; true
&lt;/pre&gt;&lt;p&gt;Keep Hirb&amp;#8217;s handy tables in mind as you see Boson make use of them.&lt;/p&gt;
&lt;h2 id=&quot;to_render_or_not_to_render&quot;&gt;&lt;a href=&quot;#to_render_or_not_to_render&quot;&gt;To Render or Not To Render&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the previous post, I demonstrated &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#commands_with_options&quot;&gt;adding options to commands&lt;/a&gt;. Let&amp;#8217;s create another such command but this time to explore Boson&amp;#8217;s default options:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# Drop this in ~/.boson/commands/pinky.rb&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pinky&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#@options :count=&amp;gt;:numeric&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Give Pinky a voice&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;speak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_a?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hey Brain! &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Brain, I can count to &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;!&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let Pinky do his thing:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; irb
  &gt;&gt; speak &quot;What does this do?&quot;
  Hey Brain! What does this do?
  =&gt; nil

  # Give Pinky a number to count to
  &gt;&gt; speak &#39;La-di-da -c5&#39;
  Hey Brain! La-di-da
  Brain, I can count to 5!
  =&gt; 1..5

  # Turn on Hirb rendering for return value
  &gt;&gt; speak &#39;La-di-da --render -c5&#39;
  Hey Brain! La-di-da
  Brain, I can count to 5!
  +-------+
  | value |
  +-------+
  | 1     |
  | 2     |
  | 3     |
  | 4     |
  | 5     |
  +-------+
  5 rows in set
  =&gt; true

  # Pass Hirb&#39;s rendering a :fields option
  &gt;&gt; speak &#39;Brain!!! -r -f to_s,to_f -c3&#39;
  Hey Brain! Brain!!!
  Brain, I can count to 3!
  +------+------+
  | to_s | to_f |
  +------+------+
  | 1    | 1.0  |
  | 2    | 2.0  |
  | 3    | 3.0  |
  +------+------+
  3 rows in set
  =&gt; true

&lt;/pre&gt;&lt;p&gt;Nice! Simply by passing an option, Boson converted our command&amp;#8217;s return value into a well-formatted Hirb table. Although Boson uses Hirb&amp;#8217;s &lt;code&gt;table&lt;/code&gt; rendering by default, you can use &lt;em&gt;any&lt;/em&gt; &lt;a href=&quot;http://github.com/cldwalker/hirb/tree/master/lib/hirb/helpers&quot;&gt;Hirb helper class&lt;/a&gt;, especially ones you&amp;#8217;ve made. So what are the implications of this? &lt;i&gt;Any Boson command can have any view generated from its return value without adding view code to the method&lt;/i&gt;. If you&amp;#8217;re wondering how this is possible, see &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Scientist.html&quot;&gt;Boson::Scientist&lt;/a&gt; which redefines a command&amp;#8217;s method to have a Hirb rendering engine appended to it. For a more compelling example see the &lt;a href=&quot;#github_boson_library&quot;&gt;github library&lt;/a&gt; below.&lt;/p&gt;
&lt;h2 id=&quot;boson_commands_global_options&quot;&gt;&lt;a href=&quot;#boson_commands_global_options&quot;&gt;A Boson Command&amp;#8217;s Global Options&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each Boson command with options, or an option command, comes with global command options for rendering, sorting, etc. For now, these global options must come before a command&amp;#8217;s options. So let&amp;#8217;s see what they are:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Call up an option command&#39;s verbose help
  &gt;&gt; speak &#39;-hv&#39;
  speak [text][--count=N]

  COMMAND OPTIONS
  +---------+-------+---------+
  | Option  | Alias | type    |
  +---------+-------+---------+
  | --count | -c    | numeric |
  +---------+-------+---------+

  GLOBAL/RENDER OPTIONS
  +----------------+-------+---------+-----------------------------------------------------------+
  | Option         | Alias | type    | Description                                               |
  +----------------+-------+---------+-----------------------------------------------------------+
  | --class        | -c    | string  | Hirb helper class which renders                           |
  | --fields       | -f    | array   | Displays fields in the order given                        |
  | --help         | -h    | boolean | Display a command&#39;s help                                  |
  | --max_width    | -m    | numeric | Max width of a table                                      |
  | --pretend      | -p    | boolean | Display what a command would execute without executing it |
  | --render       | -r    | boolean | Toggle a command&#39;s default rendering behavior             |
  | --reverse_sort | -R    | boolean | Reverse a given sort                                      |
  | --sort         | -s    | string  | Sort by given field                                       |
  | --verbose      | -v    | boolean | Increase verbosity for help, errors, etc.                 |
  | --vertical     | -V    | boolean | Display a vertical table                                  |
  +----------------+-------+---------+-----------------------------------------------------------+
  =&gt; true

  # Use --pretend to see what arguments are being passed to your command without running it.
  # Useful when debugging options and aliased option values
  &gt;&gt; speak &#39;--pretend -r -c3 Testing&#39;
  Arguments: [&quot;Testing&quot;, {:count=&gt;3}]
  Global options: {:pretend=&gt;true, :render=&gt;true}
  =&gt; true

  # Use --vertical to convert a table to a vertical one.
  # Useful for database record tables
  &gt;&gt; speak &#39;-rV -c3 Que pasa!&#39;
  Hey Brain! Que pasa!
  Brain, I can count to 3!
  ******* 1. row *******
  value: 1
  ******* 2. row *******
  value: 2
  ******* 3. row *******
  value: 3
  3 rows in set
  =&gt; true

  # Resize a table&#39;s maximum width to 7 characters
  &gt;&gt; speak &#39;-r -m7 -c3 Blah blah!&#39;
  Hey Brain! Blah blah!
  Brain, I can count to 3!
  +-----+
  | val |
  +-----+
  | 1   |
  | 2   |
  | 3   |
  +-----+
  3 rows in set
  =&gt; true

  # When a global option conflicts with a command&#39;s options, pass them at the
  # end separated by a &#39;-&#39;
  &gt;&gt; speak &#39;What year is it? -r -c3 - -c=auto_table&#39;
  Hey Brain! What year is it?
  Brain, I can count to 3!
  +-------+
  | value |
  +-------+
  | 1     |
  | 2     |
  | 3     |
  +-------+
  3 rows in set
  =&gt; true
  # the above could also have been:
  &gt;&gt; speak &#39;--class=auto_table -r -c3 What year is it?&#39;
  
  # We&#39;ll demonstrate --sort and --reverse_sort soon enough ...
&lt;/pre&gt;&lt;h2 id=&quot;github_boson_library&quot;&gt;&lt;a href=&quot;#github_boson_library&quot;&gt;A Github Boson Library&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using Pinky was fun to annoy Brain but let&amp;#8217;s dig into a more useful example. Consider this command to view a &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt; user&amp;#8217;s repositories using &lt;a href=&quot;http://develop.github.com/p/repo.html&quot;&gt;the repository &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# Drop in ~/.boson/commands/github_example.rb&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;GithubExample&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# @render_options :fields=&amp;gt;{:default=&amp;gt;[:name, :watchers, :forks, :homepage, :description],&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#  :values=&amp;gt;[:homepage, :name, :forks, :private, :watchers, :fork, :url, :description, :owner, :open_issues]}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# @options :user=&amp;gt;&amp;#39;cldwalker&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Displays a github user&amp;#39;s repositories&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;repos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;YAML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://github.com/api/v2/yaml/repos/show/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;repositories&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some points:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The output of &lt;code&gt;repos()&lt;/code&gt; is an array of hashes, perfect for Hirb&amp;#8217;s tables.&lt;/li&gt;
	&lt;li&gt;The &lt;code&gt;get()&lt;/code&gt; method is a default Boson command which does a get request on a url and returns the response body.&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;render_options&lt;/code&gt;
	&lt;ul&gt;
		&lt;li&gt;Unlike Pinky&amp;#8217;s &lt;code&gt;speak()&lt;/code&gt;, this command defaults to rendering with Hirb because &lt;code&gt;render_options&lt;/code&gt; is present.&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;render_options&lt;/code&gt;, like &lt;code&gt;options&lt;/code&gt;, takes &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/OptionParser.html#M000069&quot;&gt;a hash of options&lt;/a&gt; which are passed to a Hirb helper.&lt;/li&gt;
		&lt;li&gt;Can take existing global options or new options specific to your Hirb helper.&lt;/li&gt;
		&lt;li&gt;The above commented render_options could also have been a method call, as was &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#commands_with_options&quot;&gt;shown with options&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;The :values option attribute of the :fields option let&amp;#8217;s us do sweet &lt;a href=&quot;/2009/10/14/boson-command-your-ruby-universe.html#aliasing_option_values&quot;&gt;aliasing of option values&lt;/a&gt; for :fields and :sort options.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;#8217;s try it out:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; irb
  &gt;&gt; repos &#39;-u defunkt&#39;
  +---------------------------+----------+-------+-------------------------------------------------------------------+-----------------------------------------------------------------------------------+
  | name                      | watchers | forks | homepage                                                          | description                                                                       |
  +---------------------------+----------+-------+-------------------------------------------------------------------+-----------------------------------------------------------------------------------+
  | grit                      | 10       | 1     |                                                                   |                                                                                   |
  | exception_logger          | 214      | 31    |                                                                   |                                                                                   |
  | ambition                  | 158      | 3     | http://defunkt.github.com/ambition                                | include Enumerable                                                                |
  | starling                  | 54       | 0     | http://rubyforge.org/projects/starling                            |                                                                                   |
  | subtlety                  | 6        | 1     | http://subtlety.errtheblog.com/                                   | Subtlety: SVN =&gt; RSS, hAtom =&gt; Atom                                               |
  | zippy                     | 8        | 1     |                                                                   | Zippy lil’ zipcode lib.                                                           |
  | cache_fu                  | 265      | 34    | http://errtheblog.com                                             | Everyone&#39;s favorite memcached plugin for ActiveRecord.                            |
  | mofo                      | 65       | 9     | http://mofo.rubyforge.org/                                        | Mofo is a fast and simple microformat parser, based on a concise DSL and Hpricot. |
  # ...

  # We can toggle rendering off by passing --render and get back the original return value
  &gt;&gt; repos(&#39;-r -u defunkt&#39;).size
  =&gt; 89

  # Oh the good ol days of inspect
  &gt;&gt; repos(&#39;-r -u defunkt&#39;).slice(0,2)
  =&gt; [{:forks=&gt;1, :url=&gt;&quot;http://github.com/defunkt/grit&quot;, :name=&gt;&quot;grit&quot;, :watchers=&gt;10, :private=&gt;false, :owner=&gt;&quot;defunkt&quot;, :fork=&gt;true,
    :open_issues=&gt;0}, {:forks=&gt;31, :url=&gt;&quot;http://github.com/defunkt/exception_logger&quot;, :name=&gt;&quot;exception_logger&quot;, :watchers=&gt;214,
    :private=&gt;false, :description=&gt;&quot;&quot;, :owner=&gt;&quot;defunkt&quot;, :fork=&gt;false, :open_issues=&gt;0, :homepage=&gt;&quot;&quot;}]
  
  # Remembering we can pass rendering options, let&#39;s only view a couple of fields
  &gt;&gt; repos &#39;-f n,w,op -u defunkt&#39;  # or &#39;--fields name,watchers,open_issues --user defunkt&#39;
  +---------------------------+----------+-------------+
  | name                      | watchers | open_issues |
  +---------------------------+----------+-------------+
  | grit                      | 10       | 0           |
  | exception_logger          | 214      | 0           |
  | ambition                  | 158      | 0           |
  | starling                  | 54       | 0           |
  | subtlety                  | 6        | 0           |
  | zippy                     | 8        | 0           |
  | cache_fu                  | 265      | 2           |
  | mofo                      | 65       | 1           |
  # ...

  # What about global sorting options?
  # Let&#39;s see wycats least popular repositories
  &gt;&gt; repos &#39;-s=w -u wycats&#39; # or &#39;--sort=watchers --user=wycats&#39;
  +---------------------------+----------+-------+------------------------------------------+---------------------------------------------------------------------------------------------+
  | name                      | watchers | forks | homepage                                 | description                                                                                 |
  +---------------------------+----------+-------+------------------------------------------+---------------------------------------------------------------------------------------------+
  | rails-shared-benches      | 0        | 0     |                                          | Some Rails benches that work across Rails versions and can be used to compare perf progress |
  | rails                     | 0        | 7     | http://rubyonrails.org                   | Ruby on Rails                                                                               |
  | serialize_location_header | 1        | 0     |                                          | Serialize the location header if it exists                                                  |
  | ufo_book                  | 2        | 0     |                                          | Uses the flying_saucer jruby gem to compile books                                           |
  | ruby-mozjs                | 2        | 0     |                                          | Mozilla JavaScript Engine (SpiderMonkey) bindings for Ruby                                  |
  | rack                      | 3        | 0     | http://rack.rubyforge.org/               | a modular Ruby webserver interface                                                          |
  | lonestar                  | 3        | 0     |                                          |                                                                                             |
 # ...

 # And most popular repositories
 &gt;&gt; repos &#39;-s=w -R -u wycats&#39; # or &#39;--sort=watchers --reverse_sort --user=wycats&#39;
 +---------------------------+----------+-------+------------------------------------------+---------------------------------------------------------------------------------------------+
 | name                      | watchers | forks | homepage                                 | description                                                                                 |
 +---------------------------+----------+-------+------------------------------------------+---------------------------------------------------------------------------------------------+
 | merb-core                 | 611      | 59    | http://www.merbivore.com                 | Merb Core: All you need. None you don&#39;t.                                                    |
 | merb                      | 508      | 102   | http://www.merbivore.com                 | master merb branch                                                                          |
 | thor                      | 330      | 26    | http://www.yehudakatz.com                | A scripting framework that replaces rake and sake                                           |
 | merb-more                 | 316      | 32    | http://www.merbivore.com                 | Merb More: The Full Stack. Take what you need; leave what you don&#39;t.                        |
 | merb-plugins              | 313      | 42    | http://www.merbivore.com                 | Merb Plugins: Even more modules to hook up your Merb installation                           |
 | moneta                    | 264      | 28    | http://www.yehudakatz.com                | a unified interface to key/value stores                                                     |
 | bundler                   | 228      | 20    |                                          |                                                                                             |
 # ...

 # Of course you can do all of the above from the commandline with the boson command.
 # Even manipulating the command&#39;s return value with ruby:
 #
 # bash&gt; boson -e &quot;p repos(&#39;-r -u defunkt&#39;).size&quot;
 # Loaded library github
 # 89
 #
 # bash&gt; boson -e &quot;p repos(&#39;-r -u defunkt&#39;).slice(0,2)&quot;
 # Loaded library github
 # [{:forks=&gt;1, :url=&gt;&quot;http://github.com/defunkt/grit&quot;, :name=&gt;&quot;grit&quot;, :watchers=&gt;10, :private=&gt;false, :owner=&gt;&quot;defunkt&quot;, :fork=&gt;true,
 #  :open_issues=&gt;0}, {:forks=&gt;31, :url=&gt;&quot;http://github.com/defunkt/exception_logger&quot;, :name=&gt;&quot;exception_logger&quot;, :watchers=&gt;214,
 #  :private=&gt;false, :description=&gt;&quot;&quot;, :owner=&gt;&quot;defunkt&quot;, :fork=&gt;false, :open_issues=&gt;0, :homepage=&gt;&quot;&quot;}]
&lt;/pre&gt;&lt;p&gt;As you can see, writing a Boson command to interact with the Github &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; is pretty easy. If you liked this sample command, install and try my &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site/github.rb&quot;&gt;Github Boson library&lt;/a&gt; :&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/site/github.rb
  Saved to /Users/bozo/.boson/commands/github.rb.

  # List the commands that come with the github library
  bash&gt; boson commands -q=l github
 +---------------+--------+-------+------------------------------------------------+-----------------------------------------------------------------------+
  | full_name     | lib    | alias | usage                                          | description                                                           |
  +---------------+--------+-------+------------------------------------------------+-----------------------------------------------------------------------+
  | checkout      | github |       | [url]                                          | Clones a github repo and opens in textmate                            |
  | user_search   | github |       | [query]                                        | Search users                                                          |
  | repo          | github |       | [_search(query]                                | Opens a repo with an optional path in a browser                       |
  | repo_search   | github |       | [query]                                        | Search repositories                                                   |
  | commit_list   | github |       | [user_repo][--branch=master]                   | List commits of a given user-repo                                     |
  | user_repos    | github |       | [--user=cldwalker] [--fork_included] [--stats] | Displays a user&#39;s repositories                                        |
  | raw_file      | github |       | [file_url]                                     | Downloads the raw form of a github repo file url                      |
  | repo_network  | github |       | [user_repo][--user=cldwalker]                  | Displays network of a given user-repo i.e. wycats-thor or defunkt/rip |
  | repos_watched | github |       | [user]                                         | Lists repos watched by user                                           |
  | user_follows  | github |       | [user]                                         | List users a user follows                                             |
  +---------------+--------+-------+------------------------------------------------+-----------------------------------------------------------------------+

  # Let&#39;s do a repository search
  bash&gt; boson repo_search tagging -s=f  #or tagging --sort=followers
  +------------------------------+---------------+-----------+------------+----------------------+------------+-----------------------------------------------------------------+
  | name                         | username      | followers | language   | pushed               | score      | description                                                     |
  +------------------------------+---------------+-----------+------------+----------------------+------------+-----------------------------------------------------------------+
  | acts-as-taggable-on          | mbleigh       | 633       | Ruby       | 2009-10-14T15:16:26Z | 0.46670222 | A tagging plugin for Rails applications that allows for cust... |
  | is_taggable                  | giraffesoft   | 201       | Ruby       | 2009-08-19T16:03:36Z | 0.3879375  | Tagging that doesn&#39;t want to be on steroids. It&#39;s skinny and... |
  | acts_as_taggable_on_steroids | jviney        | 118       | Ruby       | 2009-06-12T06:15:45Z | 0.57809234 | Tagging for Ruby on Rails                                       |
  | acts_as_taggable_redux       | geemus        | 100       | Ruby       | 2009-10-05T20:30:11Z | 0.46670222 | Allows for user owned tags to be added to multiple classes, ... |
  | prettyPrint.js               | jamespadolsey | 99        | JavaScript | 2009-06-07T10:17:55Z | 0.3879375  | An in-browser JavaScript variable dumper, similar in functio... |
  | django-uni-form              | pydanny       | 79        | Python     | 2009-09-12T23:47:49Z | 0.31662944 | Django forms are easily rendered as tables, paragraphs, and ... |
  | odf-report                   | sandrods      | 74        | Ruby       | 2009-09-24T03:49:09Z | 0.4354762  | Generates ODF files, given a template (.odt) and data, repla... |
  | prawn-format                 | jamis         | 64        | Ruby       | 2009-03-24T15:30:25Z | 0.3403988  | An extension to the Prawn PDF generation library that allows... |
  # ...

  # Latest commits for a given project in format :user/:repo
  bash&gt; boson commit_list wycats/bundler
  | id                                       | authored_date             | message                                                                              |
  +------------------------------------------+---------------------------+--------------------------------------------------------------------------------------+
  | 8795746808647860b7b44bbb23bf3c64423eb1c8 | 2009-10-06T17:30:31-07:00 | Always generate bin files no matter what.                                            |
  | 87201c825ff487077c4e1b55d449202007be1a42 | 2009-10-06T15:15:41-07:00 | Bump up the version number to 0.7.0.pre                                              |
  | 53c589e1d440c2874ce57ee80047b54af2e8a646 | 2009-10-06T15:15:26-07:00 | Fix branches and #git with block calls                                               |
  | 5bbb5740f3d576f57bd1c7b5c5557b781c22189b | 2009-10-06T12:15:24-07:00 | Add a glob option to directories                                                     |
  | 6f263a435645a2fb76874d0c7f2c83d59eef8e92 | 2009-10-06T00:06:34-07:00 | Add a test that tests overwriting existing bin files                                 |
  | a3694bf09ac8d3093c2ce1a744992e590ab50b5e | 2009-10-05T23:34:39-07:00 | It handles the simple git method as a block                                          |
  # ...

  # List network of a given :user/:repo sorted by most watched
  bash&gt; boson repo_network rails/rails -s=w -R  # or rails/rails --sort=watchers --reverse_sort
  +-----------------------+----------+-------+-----------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
  | owner                 | watchers | forks | homepage                    | description                                                                                                                          |
  +-----------------------+----------+-------+-----------------------------+--------------------------------------------------------------------------------------------------------------------------------------+
  | rails                 | 4308     | 702   | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
  | josh                  | 35       | 4     | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
  | relevance             | 13       | 0     | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
  | miloops               | 11       | 0     | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
  | revolutionhealth      | 10       | 0     | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
  | xing                  | 10       | 0     | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
  | 37signals             | 9        | 0     | http://rubyonrails.org      | Ruby on Rails                                                                                                                        |
 # ...
&lt;/pre&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As you&amp;#8217;ve seen, Boson-Hirb interactions can lead to some novel and useful Ruby commands. Hirb&amp;#8217;s instant views, controlled by Boson commands, can make one think of Boson as a commandline &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; framework with an optional V. To learn more about Boson, &lt;a href=&quot;http://tagaholic.me/boson/doc/&quot;&gt;read it&amp;#8217;s docs&lt;/a&gt;. I&amp;#8217;m eager to see what useful Boson libraries others will come up with. To try out Boson &lt;span class=&#39;github&#39;&gt;gem install boson boson-more&lt;/span&gt;.&lt;/p&gt;</content>
 </entry>
    
    
    
    
 
    
    
    
    
    
    
    
    
 <entry>
   <title>Boson - Command Your Ruby Universe</title>
   <link href="http://tagaholic.me/2009/10/14/boson-command-your-ruby-universe.html"/>
   <updated>2009-10-14T00:00:00-07:00</updated>
   <id>http://tagaholic.me/2009/10/14/boson-command-your-ruby-universe</id>
   <content type="html">&lt;p&gt;Introducing &lt;a href=&quot;http://tagaholic.me/boson/&quot;&gt;Boson&lt;/a&gt;, a command/task framework that could change how you collect and execute your ruby code. Sure, there&amp;#8217;s &lt;a href=&#39;http://rake.rubyforge.org/&#39;&gt;rake&lt;/a&gt;, &lt;a href=&#39;http://github.com/wycats/thor&#39;&gt;thor&lt;/a&gt; and &lt;a href=&quot;http://delicious.com/tag/gem:type=task&quot;&gt;a dozen other gems.&lt;/a&gt; But how many will let you create a universe of ruby commands you can run from the commandline &lt;em&gt;and&lt;/em&gt; irb?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/post-higgs_boson_decay.jpg&quot; alt=&quot;higgs boson decay&quot; width=&quot;300&quot; height=&quot;300&quot;/&gt;&lt;/p&gt;
&lt;h2&gt;Spinning On&lt;/h2&gt;
&lt;p&gt;Feel free to &lt;a href=&quot;http://github.com/cldwalker/boson&quot;&gt;follow Boson on the Hub&lt;/a&gt; and to install it:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  $ gem install boson boson-more
  $ echo &quot;require &#39;boson/more&#39;&quot; &gt;&gt; ~/.bosonrc
&lt;/pre&gt;&lt;p&gt;To get an idea of Boson&amp;#8217;s features, here&amp;#8217;s an outline:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;#shell_and_irb_duality&quot;&gt;Shell and Irb Duality&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#creating_commands&quot;&gt;Creating Commands&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#commands_with_options&quot;&gt;Commands With Options&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#just_alias_it&quot;&gt;Just Alias It&lt;/a&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;#aliasing_commands&quot;&gt;Aliasing Commands&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#aliasing_options&quot;&gt;Aliasing Options&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;#aliasing_option_values&quot;&gt;Aliasing Option Values&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#using_third_party_commands&quot;&gt;Using Third Party Commands&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;#namespaces&quot;&gt;Namespaces&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;shell_and_irb_duality&quot;&gt;&lt;a href=&quot;#shell_and_irb_duality&quot;&gt;Shell and Irb Duality&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Like traditional command frameworks, Boson executes commands(tasks) from the commandline:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Let&#39;s list boson&#39;s default libraries
  bash&gt; boson libraries
  +----------+----------+------+--------------+
  | name     | commands | gems | library_type |
  +----------+----------+------+--------------+
  | core     | 6        |      | module       |
  | web_core | 3        |      | module       |
  +----------+----------+------+--------------+
  2 rows in set

  # And default commands
  bash&gt; boson commands
  +--------------+----------+-------+--------------------------------------------+-----------------------------------------------------------------------------+
  | full_name    | lib      | alias | usage                                      | description                                                                 |
  +--------------+----------+-------+--------------------------------------------+-----------------------------------------------------------------------------+
  | usage        | core     |       | [name][--verbose]                          | Print a command&#39;s usage                                                     |
  | libraries    | core     |       | [query=&#39;&#39;][--index] [--query_fields=A,B,C] | List or search libraries                                                    |
  | render       | core     |       | [object] [options={}]                      | Render any object using Hirb                                                |
  | load_library | core     |       | [library][--verbose] [--reload]            | Load/reload a library                                                       |
  | commands     | core     |       | [query=&#39;&#39;][--index] [--query_fields=A,B,C] | List or search commands                                                     |
  | menu         | core     |       | [output] [options={}] [&amp;block]             | Provide a menu to multi-select elements from a given array                  |
  | get          | web_core |       | [url]                                      | Gets the body of a url                                                      |
  | install      | web_core |       | [url][--force] [--name=NAME]               | Installs a library by url. Library should then be loaded with load_library. |
  | browser      | web_core |       | [*urls]                                    | Opens urls in a browser                                                     |
  +--------------+----------+-------+--------------------------------------------+-----------------------------------------------------------------------------+
  9 rows in set
  =&gt; true
&lt;/pre&gt;&lt;p&gt;But unlike others, you can do the same in the ruby console:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  bash&gt; irb
  # You could drop this line in your irbrc
  &gt;&gt; require &#39;boson&#39;; Boson.start
  Loaded library core
  Loaded library web_core
  =&gt; nil

  &gt;&gt; libraries
  +----------+----------+------+--------------+
  | name     | commands | gems | library_type |
  +----------+----------+------+--------------+
  | core     | 6        |      | module       |
  | web_core | 3        |      | module       |
  +----------+----------+------+--------------+
  2 rows in set
  =&gt; true

  &gt;&gt; commands
  # same as above ...
&lt;/pre&gt;&lt;p&gt;How is this done? Commands are simply methods on Ruby&amp;#8217;s top level object, main. You provide the methods and Boson manages and empowers them. Even with more complex command usage, the shell/irb duality holds:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Print basic command usage in irb
  irb&gt;&gt; commands &#39;-h&#39;
  commands [query=&#39;&#39;][--index]
  =&gt; nil
  # Or in your shell
  bash&gt; boson commands -h
  # same as above ...
  
  # Search command fields full_name and description for &#39;lib&#39; and sort by full_name
  irb&gt;&gt; commands &#39;full_name,description:lib --sort full_name&#39;
  +--------------+----------+-------+-------------------------------------------+-----------------------------------------------------------------------------+
  | full_name    | lib      | alias | usage                                     | description                                                                 |
  +--------------+----------+-------+-------------------------------------------+-----------------------------------------------------------------------------+
  | install      | web_core |       | [url][--force] [--name=NAME]              | Installs a library by url. Library should then be loaded with load_library. |
  | libraries    | core     | lib   | [query=&#39;&#39;][--index] [--query_fields=name] | List or search libraries                                                    |
  | load_library | core     | ll    | [library][--verbose] [--reload]           | Load/reload a library                                                       |
  +--------------+----------+-------+-------------------------------------------+-----------------------------------------------------------------------------+
  3 rows in set
  =&gt; true

  # In your shell
  bash&gt; boson commands full_name,description:lib --sort full_name
  # same as above ...

  # Using option aliases
  bash&gt; boson commands lib -s f -q=f,d
  # same as above ...

  # Execute a command repo_search under namespace github in irb
  irb&gt;&gt; github.repo_search &#39;crazy&#39;
  # or in a shell
  bash&gt; boson github.repo_search crazy
&lt;/pre&gt;&lt;h2 id=&quot;creating_commands&quot;&gt;&lt;a href=&quot;#creating_commands&quot;&gt;Creating Commands&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Creating a Boson command is as easy as opening a module and defining a method:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;c1&quot;&gt;# Drop this in ~/.boson/commands/brain.rb&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# The module name can be anything but it makes sense to name it the same as the file.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# The module is evaluated under Boson::Commands&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Brain&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Help Brain live his dream&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;take_over&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Pinky, it&amp;#39;s time to take over the &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;!&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;#8217;s give the new command a spin:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  # Unfortunately Brain can&#39;t do much right now
  bash&gt; boson take_over farm
  Pinky, it&#39;s time to take over the farm!

  # Of course we now have a brain library
  bash&gt; boson libraries
  +----------+----------+------+--------------+
  | name     | commands | gems | library_type |
  +----------+----------+------+--------------+
  | core     | 6        |      | module       |
  | web_core | 3        |      | module       |
  | brain    | 1        |      | file         |
  +----------+----------+------+--------------+
  3 rows in set

  # And a take_over command
  bash&gt; boson commands take
  +-----------+-------+-------+---------------+---------------------------+
  | full_name | lib   | alias | usage         | description               |
  +-----------+-------+-------+---------------+---------------------------+
  | take_over | brain |       | [destination] | Help Brain live his dream |
  +-----------+-------+-------+---------------+---------------------------+
  1 row in set

  # And of course you can execute this all from irb ...
&lt;/pre&gt;&lt;p&gt;As you can see, Boson lets you write your libraries and commands in &lt;em&gt;plain&lt;/em&gt; ruby. Module-method DSLs be damned. If you want more commands for the brain library, add more methods to &lt;code&gt;Brain&lt;/code&gt; in the file. Also notice that Boson automatically generates a command&amp;#8217;s usage and description from the method&amp;#8217;s arguments and the comment above it.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s cool. Boson&amp;#8217;s libraries are just modules and its commands just methods. But if this is all the functionality Boson offers, why bother with it at all?&lt;/p&gt;
&lt;h2 id=&quot;commands_with_options&quot;&gt;&lt;a href=&quot;#commands_with_options&quot;&gt;Commands With Options&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Borrowing from &lt;a href=&quot;http://github.com/wycats/thor&quot;&gt;Thor&lt;/a&gt;, Boson commands can have simple yet powerful options. Let&amp;#8217;s add some to &lt;code&gt;take_over()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Brain&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:boolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:countdown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:numeric&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Help Brain live his dream&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;take_over&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Pinky, it&amp;#39;s time to take over the &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;!&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:countdown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:countdown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/home/brain/take_over/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Brain always has the best of intentions:&lt;/p&gt;
&lt;pre class=&quot;console&quot;&gt;
  bash&gt; boson take_over world --execute --countdown=3
  Pinky, it&#39;s time to take over the world!
  # program sleeps 3 seconds
  # executes `/home/brain/take_over/world`

  # Thanks to auto-generated option aliases
  bash&gt; boson take_over world -e -c3
  # same as above ...

  # Boson still holds true to its irb duality
  bash&gt; irb
  &gt;&gt; take_over &#39;world -e -c3&#39;
  # same as above ...

  # And if you want, call your command in plain ruby
  &gt;&gt; take_over &#39;world&#39;, :execute=&gt;true, :countdown=&gt;3
&lt;/pre&gt;&lt;p&gt;A few points:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;options()&lt;/code&gt; takes a hash of options with names mapping to option types&lt;/li&gt;
	&lt;li&gt;Short flags or option aliases are automatically generated based on the first letter of the option name.&lt;/li&gt;
	&lt;li&gt;Options have &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/OptionParser.html&quot;&gt;plenty of functionality&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;Commands with options must expect their last argument to be an options hash.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So it&amp;#8217;s great that options can be defined concisely, but whatever happened to just writing commands in plain ruby? Well, Boson actually lets you but it&amp;#8217;s gonna cost you &lt;strong&gt;2&lt;/strong&gt; more characters:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Brain&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#@options :execute=&amp;gt;:boolean, :countdown=&amp;gt;:numeric&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Help Brain live his dream&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;take_over&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ....&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
As you can see, I commented out the &lt;span class=&quot;caps&quot;&gt;DSL&lt;/span&gt; method and prepended &amp;#8216;options&amp;#8217; with &amp;#8216;@&amp;#8217;. This command still has the same functionality while still keeping it all in &lt;em&gt;plain&lt;/em&gt; ruby.
&lt;p/&gt;
&lt;h2 id=&quot;just_alias_it&quot;&gt;&lt;a href=&quot;#just_alias_it&quot;&gt;Just Alias It&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Built with the power user in mind, Boson encourages aliasing of commands, options and even option values. Let&amp;#8217;s take a look at each.&lt;/p&gt;
&lt;h3 id=&quot;aliasing_commands&quot;&gt;&lt;a href=&quot;#aliasing_commands&quot;&gt;Aliasing Commands&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Aliasing commands is done through Boson&amp;#8217;s main config file at ~/.boson/config/boson.yml. For an example config file, &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/config/boson.yml&quot;&gt;see mine&lt;/a&gt;. Let&amp;#8217;s add command aliases for the default command &lt;code&gt;commands&lt;/code&gt; and our example command &lt;code&gt;take_over&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Drop this in ~/.boson/config/boson.yml
  :command_aliases:
    commands: com
    take_over: take

  # Back in the shell
  # List commands with &#39;com&#39; or &#39;take in its name:
  bash&gt; boson -l=brain com com\|take
  +-----------+-------+-------+------------------------------------------------+---------------------------+
  | full_name | lib   | alias | usage                                          | description               |
  +-----------+-------+-------+------------------------------------------------+---------------------------+
  | commands  | core  | com   | [query=&#39;&#39;][--index] [--query_fields=full_name] | List or search commands   |
  | take_over | brain | take  | [destination]                                  | Help Brain live the dream |
  +-----------+-------+-------+------------------------------------------------+---------------------------+
  2 rows in set

  # And if we wanted to execute take_over with the new alias
  bash&gt; boson take world -e -c3
&lt;/pre&gt;&lt;h3 id=&quot;aliasing_options&quot;&gt;&lt;a href=&quot;#aliasing_options&quot;&gt;Aliasing Options&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As &lt;a href=&quot;#commands_with_options&quot;&gt;explained above&lt;/a&gt;, options automatically have aliases generated for them. But if you want, specify your own aliases in &lt;code&gt;options()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s add some aliases to the execute option
  
  module Brain
    #@options [:execute, :conquer, :x]=&gt;:boolean, :countdown=&gt;:numeric
    # ...
  end

  # The execute option can now be called with -x and --conquer
&lt;/pre&gt;&lt;h3 id=&quot;aliasing_option_values&quot;&gt;&lt;a href=&quot;#aliasing_option_values&quot;&gt;Aliasing Option Values&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Aliasing option values is possible for option types :string and :array. But unlike the other aliases, you specify a unique string that a value starts with rather than define explicit aliases. Let&amp;#8217;s redo &lt;code&gt;take_over()&lt;/code&gt; to take a :string option with some expected values:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;  &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Brain&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#@options :destination=&amp;gt;{:type=&amp;gt;:string, :values=&amp;gt;%w{world farm fjord}},&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# :execute=&amp;gt;:boolean, :countdown=&amp;gt;:numeric&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Help Brain live his dream&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;take_over&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Pinky, it&amp;#39;s time to take over the &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:destination&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;!&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:countdown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:countdown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/home/brain/take_over/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:destination&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see we added a :destination option with a :values attribute. With this attribute, the :destination option is able to instantly alias those values. For more about the :values attribute &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/OptionParser.html#M000069&quot;&gt;see here&lt;/a&gt;. Let&amp;#8217;s see this aliasing in action:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # &#39;f&#39; will match &#39;farm&#39; over &#39;fjord&#39; since values are searched alphabetically
  bash&gt; boson take -d=f
  Pinky, it&#39;s time to take over the farm!

  # It&#39;s still easy to get fjord
  bash&gt; boson take -d=fj
  Pinky, it&#39;s time to take over the fjord!

  # This is what Brain really wants to do
  bash&gt; boson take -d=w -e
  Pinky, it&#39;s time to take over the world!

  # If at any time you need to remember your option&#39;s values
  bash&gt; boson -hv take
  Loaded library core
  Loaded library web_core
  Loaded library brain
  take [--execute] [--destination=DESTINATION] [--countdown=N]

  COMMAND OPTIONS
  +---------------+-------+---------+------------------+
  | Option        | Alias | type    | Values           |
  +---------------+-------+---------+------------------+
  | --countdown   | -c    | numeric |                  |
  | --destination | -d    | string  | world,farm,fjord |
  | --execute     | -e    | boolean |                  |
  +---------------+-------+---------+------------------+
  # ...
&lt;/pre&gt;&lt;p&gt;You may be pleased to know that the default commands &lt;code&gt;libraries&lt;/code&gt; and &lt;code&gt;commands&lt;/code&gt; come with all this goodness:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; irb
  &gt;&gt; commands &#39;-hv&#39;
  commands [query=&#39;&#39;][--index]

  COMMAND OPTIONS
  +----------------+-------+---------+----------------+------------------------------------------------------------------------+
  | Option         | Alias | type    | Description    | Values                                                                 |
  +----------------+-------+---------+----------------+------------------------------------------------------------------------+
  | --index        | -i    | boolean | Searches index |                                                                        |
  +----------------+-------+---------+----------------+------------------------------------------------------------------------+

  GLOBAL/RENDER OPTIONS
  +----------------+-------+---------+-----------------------------------------------------------+------------------------------------------------------------------------+
  | Option         | Alias | type    | Description                                               | Values                                                                 |
  +----------------+-------+---------+-----------------------------------------------------------+------------------------------------------------------------------------+
  | --class        | -c    | string  | Hirb helper class which renders                           |                                                                        |
  | --fields       | -f    | array   | Displays fields in the order given                        | name,lib,alias,description,options,args,usage,full_name,render_options |
  | --help         | -h    | boolean | Display a command&#39;s help                                  |                                                                        |
  | --max_width    | -m    | numeric | Max width of a table                                      |                                                                        |
  | --pretend      | -p    | boolean | Display what a command would execute without executing it |                                                                        |
  | --render       | -r    | boolean | Toggle a command&#39;s default rendering behavior             |                                                                        |
  | --reverse_sort | -R    | boolean | Reverse a given sort                                      |                                                                        |
  | --sort         | -s    | string  | Sort by given field                                       | name,lib,alias,description,options,args,usage,full_name,render_options |
  | --verbose      | -v    | boolean | Increase verbosity for help, errors, etc.                 |                                                                        |
  | --vertical     | -V    | boolean | Display a vertical table                                  |                                                                        |
  +----------------+-------+---------+-----------------------------------------------------------+------------------------------------------------------------------------+
 =&gt; true

  # Don&#39;t worry about the other options. To be covered in another blog post :p
&lt;/pre&gt;&lt;p&gt;So yes, you can search commands and libraries while choosing which fields to search, sort and display with aliased options and option values!&lt;/p&gt;
&lt;h2 id=&quot;using_third_party_commands&quot;&gt;&lt;a href=&quot;#using_third_party_commands&quot;&gt;Using Third Party Commands&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Boson makes it dead easy to install someone else&amp;#8217;s commands:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # Let&#39;s download a library which explains irb&#39;s default commands
  bash&gt; boson install https://github.com/cldwalker/irbfiles/raw/master/boson/commands/public/irb_core.rb
  Saved to /Users/bozo/.boson/commands/irb_core.rb

  # Let&#39;s see the commands in irb
  bash&gt; irb
  &gt;&gt; commands &#39;-q=l irb_core&#39;
  +-------------------------------+----------+------------+-------+-----------------------------------------------------------------------------+
  | full_name                     | lib      | alias      | usage | description                                                                 |
  +-------------------------------+----------+------------+-------+-----------------------------------------------------------------------------+
  | irb_pop_workspace             | irb_core | popws      |       | Pops current workspace and changes to next workspace in context             |
  | irb_require                   | irb_core |            |       | Evals file like require line by line                                        |
  | public                        | irb_core |            |       | Works same as module#public                                                 |
  | private                       | irb_core |            |       | Works same as module#private                                                |
  | irb                           | irb_core |            |       | Starts a new workspace/subsession                                           |
  | irb_push_workspace            | irb_core | pushws     |       | Creates a workspace for given object and pushes it into the current context |
  | irb_load                      | irb_core |            |       | Evals file like load line by line                                           |
  | irb_change_workspace          | irb_core | cws        |       | Changes current workspace to given object                                   |
  | irb_source                    | irb_core | source     |       | Evals full path file line by line                                           |
  | irb_jobs                      | irb_core | jobs       |       | List workspaces/subsessions                                                 |
  | irb_fg                        | irb_core | fg         |       | Switch to a workspace/subsession                                            |
  | irb_help                      | irb_core | help       |       | Ri based help                                                               |
  | irb_kill                      | irb_core | kill       |       | Kills a given workspace/subsession                                          |
  | include                       | irb_core |            |       | Works same as module#include                                                |
  | irb_exit                      | irb_core | exit       |       | Kills the current workspace/subsession                                      |
  | irb_workspaces                | irb_core | workspaces |       | Array of workspaces for current context                                     |
  | irb_context                   | irb_core | conf       |       | Displays configuration for current workspace/subsession                     |
  | install_alias_method          | irb_core |            |       | Aliases given method, allows lazy loading of dependent file                 |
  | irb_current_working_workspace | irb_core | cwws       |       | Prints current workspace                                                    |
  +-------------------------------+----------+------------+-------+-----------------------------------------------------------------------------+
  19 rows in set
  =&gt; true

  # Sweet! Now we have a list and description of commands that come with irb.  
&lt;/pre&gt;&lt;p&gt;If you remember, Boson&amp;#8217;s libraries are just modules. So &lt;em&gt;any&lt;/em&gt; url that points to a ruby module now offers you a library of Boson commands. You can even have the installer automatically wrap ruby code in a method and a module to make it a valid Boson library.&lt;br /&gt;
For example, take &lt;a href=&quot;http://gist.github.com/203861&quot;&gt;this gist&lt;/a&gt; for displaying authors on a git repository:&lt;/p&gt;
&lt;script src=&quot;http://gist.github.com/203861.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Let&amp;#8217;s commandify it:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  bash&gt; boson install https://gist.github.com/raw/203861/c063260bef7f004c9db4c2a7719ff649b59d3ade/git-authors -m
  Saved to /Users/bozo/.boson/commands/git_authors.rb.
  
  # Verify we have the command
  bash&gt; boson commands auth
  +-------------+-------------+-------+-------+-------------+
  | full_name   | lib         | alias | usage | description |
  +-------------+-------------+-------+-------+-------------+
  | git_authors | git_authors |       |       |             |
  +-------------+-------------+-------+-------+-------------+
  1 row in set

  # Running this in my local repo of http://github.com/wycats/thor
  bash&gt; boson git_authors
  * José Valim
  * Nathan Weizenbaum
  * Yehuda Katz
  * Brian Donovan
  * Fabien Franzen
  * Mislav Marohnić
  * James Herdman
  * Charles Jolley
  * Markus Prinz
  * Luis Lavena
  * Damian Janowski
  * Jack Dempsey
  * valodzka
  * Gabriel Horner
  * Edwin Moss
&lt;/pre&gt;&lt;p&gt;To try some third-party Boson libraries, &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/site/github.rb&quot;&gt;here&lt;/a&gt; &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/ruby_ref.rb&quot;&gt;are&lt;/a&gt; &lt;a href=&quot;http://github.com/cldwalker/irbfiles/blob/master/boson/commands/public/ri.rb&quot;&gt;some&lt;/a&gt; of mine I recommend.&lt;/p&gt;
&lt;h2 id=&quot;namespaces&quot;&gt;&lt;a href=&quot;#namespaces&quot;&gt;Namespaces&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;re familiar with rake and thor, you may be surprised that there has been no mention of namespaces. That&amp;#8217;s because by default they&amp;#8217;re optional. Boson, like Ruby, assumes you&amp;#8217;re grown up enough to balance power and peril. To aid with keeping the default namespace clean, Boson doesn&amp;#8217;t load a library if it introduces a command which will conflict with existing commands. This conflict detector will even catch third-party gems who pollute the default namespace by monkeypatching &lt;code&gt;Kernel&lt;/code&gt; or &lt;code&gt;Object&lt;/code&gt;. You can turn off the conflict detector per library as needed. If Boson&amp;#8217;s conflict detector isn&amp;#8217;t comforting enough, no worries. You can &lt;a href=&quot;http://tagaholic.me/boson/doc/classes/Boson/Library.html#M000074&quot;&gt;configure any library&lt;/a&gt; to have a namespace. And if you yearn for namespacing by default, simply drop &lt;code&gt;:auto_namespace: true&lt;/code&gt; into your ~/.boson/config/boson.yml.&lt;/p&gt;
&lt;h2&gt;Spinning Off&lt;/h2&gt;
&lt;p&gt;Although we&amp;#8217;ve covered most of Boson&amp;#8217;s basics, we still haven&amp;#8217;t touched on how Boson integrates with &lt;a href=&quot;http://tagaholic.me/hirb/&quot;&gt;Hirb&lt;/a&gt;. That&amp;#8217;s for the next post.&lt;/p&gt;
&lt;p&gt;And for all you physics geeks out there:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  &gt;&gt; Boson.higgs.instance_eval(&quot;class &lt;&lt; self; self end&quot;).ancestors[1]
  =&gt; Boson::Universe
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; The format for querying commands and libraries has changed since this was posted. The above examples have been updated to reflect this. Examples:&lt;/p&gt;
&lt;pre class=&#39;console&#39;&gt;
  # With the old format fields to query were passed to --query_fields
  bash&gt; boson commands lib --query_fields=full_name --sort=full_name   # or commands lib -q=f -s=f

  # With the new format, fields are placed before a query with a &#39;:&#39;
  # --query_fields doesn&#39;t exist
  bash&gt; boson commands full_name:lib --sort=full_name     # or commands f:lib -s=f

  # The new format still maintains the old format of querying with an implicit query field.
  # The implicit field is &#39;name&#39; for libraries.
  bash&gt; boson libraries core     # same as libraries name:core

  # With the new format all fields can be queried using a &#39;*&#39;
  # Searches library fields: gems,dependencies,commands,loaded,module,name,namespace,indexed_namespace,library_type
  bash&gt; boson libraries *:core

  # The new format allows for multiple searches to be joined together by &#39;,&#39;
  # This query searches for libraries that have the name matching core or a library_type matching gem
  bash&gt; boson libraries name:core,library_type:gem
&lt;/pre&gt;</content>
 </entry>
    
    
    
    
 
 
</feed>