tags:

views:

23

answers:

1

Normally to use Ruby libraries from command line I can do something like:

ruby -rfastercsv -e 'code'

Unfortunately this doesn't work with rubygems, as they're not enabled by default, and whatever rubygems does to override require doesn't seem to work with -r switch, so I'm forced to do this instead:

ruby -e 'require "rubygems"; require "fastercsv"; code'

Quite annoying for a one-liner - 42 characters of overhead compared with just 13 for non-rubygems libraries. Is there any way to avoid that?

I wrote this script to work around the problem (it works as multiple -e "code" are allowed, and require is idempotent so it shouldn't interfere with -p/-n or anything else as far as I can tell), but it's all rather ugly, and I wouldn't mind a more elegant solution:

args = []
until ARGV.empty?
  arg = ARGV.shift
  if arg =~ /\A-r(.*)\Z/
    args << "-e" << "require 'rubygems'; require '#{$1.empty? ? ARGV.shift : $1}'"
  else
    args << arg
  end
end
exec "ruby", *args
A: 

My first attempt (above) only works with -e. It wouldn't work with scripts in files like ruby -rfoo bar.rb. This scripts supports both by self-requiring trick (its file name must end in .rb):

#!/usr/bin/env ruby

if $0 == __FILE__
  args = []
  libs = []
  last_lib = nil
  while arg = ARGV.shift
    if arg == "--"
      args << arg
      args += ARGV
      break
    elsif arg =~ /\A-r(.*)\Z/
      libs << ($1.empty? ? ARGV.shift : $1)
      last_lib = args.size
    else
      args << arg
    end
  end
  if last_lib
    libself = __FILE__.chomp(".rb")
    ENV["RUBYGEMS_LIBS"] = libs.join(":")
    args[last_lib, 0] = ["-r", libself]
  end
  exec "ruby", *args
else
  require "rubygems"
  libs = ENV["RUBYGEMS_LIBS"]||""
  libs.split(":").each{|lib|
    require lib
  }
end
taw