$0 in Ruby is worth more than you’d think!

May 20, 2009 at 10:51 pm (Ruby, Week 9) (, , , , )

I feel pretty good about my work today; we did a lot of refactoring and cleaning, and I was able to do a couple larger things on my own, which was good for my confidence. I got a better understanding of how the application works in edge cases, and we got some code under test (and made even more code more testable). We also cleaned up a lot of noise in the tests and process runs, moving it to log files rather than STDOUT. I was able to use a lot of code that Micah had just written, so that made my job significantly easier. Micah taught me a neat trick for differentiating between command-line file runs and simple requires in Ruby: $0, which is the name of the file run from the command line. Here’s what I’m talking about:

### file1.rb
if $0 == __FILE__
  puts "running file_1.rb from the command line"
end
### file2.rb
require "file1"

So, if I type this at the command line:
$ ruby file1.rb
I’ll see the output from the puts statement above, but not if I run
$ ruby file2.rb

Now, it might not look like much in the simple example above, but imagine if you have a script you want to run at the command line, but you also want to require it in other files in order to test the methods in the file. So you can eliminate the need to actually run the script during the test, simply by wrapping the actual run line in an if statement like the above. Pretty cool idea.

I was also able to give Jim a couple of tips on using Vlad the Deployer, the deployment love-child of Capistrano and the Rails Machine gem. Great stuff, but it could stand to have more examples in the documentation, so the second time around is much easier.

About these ads

8 Comments

  1. Markus Gärtner said,

    The $0 trick you mentioned is originated from Python I think (most probably there are elder sources of origin, which I am not aware of, like SmallTalk maybe?). It’s in widespread use in the Python community afaik.

    Kind regards
    Markus Gärtner

    • Chris Wong said,

      $0 originates from unix shell

  2. trptcolin said,

    Cool, and as I look into this further, it’s actually also in Perl and Unix shell scripting!

  3. Ryan Davis said,

    throw me some examples for vlad.

  4. Ryan Davis said,

    no… really.

    • trptcolin said,

      Ryan,
      I actually did send you an email back on Thu, May 28, 2009 at 9:34 PM — did that come through? I sent it from my personal email address (trptcolin at gmail).

      In any case, here’s the full text of that email:
      ===
      Ryan,

      Hey, I realized as I read your comment on my blog
      (http://softwareapprenticeship.wordpress.com) that I was being a bit
      negative without really trying to help improve things (regarding
      examples in the Vlad documentation), and I feel bad about that,
      because I like Vlad a lot.

      That said, below is an example of what I had been looking to do
      initially, nothing too special (I’m defininitely no expert user). I
      guess it would just be nice to have some more extended deploy.rb
      structures for the noob user (maybe even spelling out the whole. Most
      of my problem was probably my minimal Rake knowledge. Also, it’d be
      great if http://hitsquad.rubyforge.org/vlad/doco/variables_txt.html
      was cross-linked more prominently (like from
      http://hitsquad.rubyforge.org/vlad/doco/getting_started_txt.html) – it
      took us awhile to find those the first time.

      ####################
      # deploy.rb
      ####################

      set :application, “app_name_here”
      set :repository, “git@github.com:account_name/repo_name.git”
      set :user, “username_here”
      set :web_command, “sudo apache2ctl”
      set :rails_env, “production”

      set :domain, “#{user}@domain-here.com”
      set :deploy_to, “/var/www/apps/#{application}”

      namespace :vlad do

      remote_task :update do
      Rake::Task['vlad:after_update'].invoke
      end

      remote_task :after_update do
      run “chown -R www-data:www-data #{deploy_to}/current/”
      Rake::Task['gems:install'].invoke
      releases[0..-7].each do |release|
      puts “Removing #{release}…”
      run “rm -rf #{deploy_to}/releases/#{release}”
      puts “Release #{release} removed”
      end
      end

      desc “Updates to latest revision, run rake db:migrate, then restarts
      app server”
      remote_task :deploy => [:update, :migrate, :start_app]

      end

      ####################

      Thanks!

      - Colin

      p.s. Also Yoda is fantastic – it had the office cracking up for quite awhile.

  5. mcandre said,

    YES! It’s a feature desperately lacking in Common Lisp, Scheme, and Erlang. It’s fortunately present in C, C++, C#, Objective C, Perl, Python, Ruby, and Haskell.

    The worst thing about $0 is its lack of a Googlable name. I tentatively call it “scripted main”; the main that is run only if this is the main script to load.

  6. me said,

    > The worst thing about $0 is its lack of a Googlable name

    Actually, I found this page by searching for “ruby $0″

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: