$0 in Ruby is worth more than you’d think!
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.
Markus Gärtner said,
May 21, 2009 at 4:47 am
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,
December 18, 2009 at 3:54 pm
$0 originates from unix shell
trptcolin said,
May 21, 2009 at 8:09 am
Cool, and as I look into this further, it’s actually also in Perl and Unix shell scripting!
Ryan Davis said,
May 28, 2009 at 12:52 pm
throw me some examples for vlad.
Ryan Davis said,
June 24, 2009 at 3:51 am
no… really.
trptcolin said,
June 24, 2009 at 6:53 am
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.
mcandre said,
March 3, 2011 at 12:12 pm
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.
me said,
March 3, 2011 at 3:24 pm
> The worst thing about $0 is its lack of a Googlable name
Actually, I found this page by searching for “ruby $0″