12

Since:

irb --help

Usage: irb.rb [options] [programfile] [arguments]


I know I can pass arguments to ARGV if I include a programfile

eg:

irb test.rb A B C

where test.irb is simply "p ARGV"

produces:

["a", "b", "c"]


Making programfile be con in DOS... I can do following

irb con A B C
con(main):001:0> ARGV

produces:

ARGV
=> ["A", "B", "C"]

but this is system dependent and has the side effect of echoing input :-(

What i really like is something like

irb -- a b c

BTW: I know I can set ARGV inside irb but I my intention is to alias special == irb -rSpecialLibrary" so I can do something like:

special A B C
<input goes here>

Any suggestions?

DMisener
  • 891
  • 1
  • 8
  • 15
  • That is a badly formatted series of sample code and examples. Please try reediting and formatting using the examples provided in [Editing Help](http://stackoverflow.com/editing-help). Normally I'd help clean it up for you, but there is too much, and I don't know your intention. – the Tin Man Jan 20 '11 at 19:46
  • Why do you want to pass arguments if you could set them in irb? Are the arguments being used by the SpecialLibrary? – cldwalker Jan 21 '11 at 02:31
  • I want to alias "special == irb -rSpecialLibrary" so I can do something like "special A B C" as illustrated above. – DMisener Jan 21 '11 at 16:02
  • I cleaned up the code example using the Editing Help... thanks for the pointer. – DMisener Jan 21 '11 at 16:06
  • Think of it as trying to parameterize an interactive shell which is built from IRB with additional functionality supplied by a *required* module (using the -r) – DMisener Jan 21 '11 at 16:09

3 Answers3

9

Looking at the source of the irb executable:

#!/usr/bin/env ruby
require "irb"

if __FILE__ == $0
  IRB.start(__FILE__)
else
  # check -e option
  if /^-e$/ =~ $0
    IRB.start(__FILE__)
  else
    IRB.setup(__FILE__)
  end
end

The at the source of the IRB module:

# File lib/irb/init.rb, line 15
  def IRB.setup(ap_path)
    IRB.init_config(ap_path)
    IRB.init_error
    IRB.parse_opts
    IRB.run_config
    IRB.load_modules

    unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
      IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE])
    end
  end

Down to parse_opts, our problem method:

# File lib/irb/init.rb, line 126
  def IRB.parse_opts
    load_path = []
    while opt = ARGV.shift
      case opt
      when "-f"
        @CONF[:RC] = false
      when "-m"
        @CONF[:MATH_MODE] = true
      when "-d"
        $DEBUG = true
      when /^-r(.+)?/
        opt = $1 || ARGV.shift
        @CONF[:LOAD_MODULES].push opt if opt
      when /^-I(.+)?/
        opt = $1 || ARGV.shift
        load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
      when '-U'
        set_encoding("UTF-8", "UTF-8")
      when /^-E(.+)?/, /^--encoding(?:=(.+))?/
        opt = $1 || ARGV.shift
        set_encoding(*opt.split(':', 2))
      when "--inspect"
        @CONF[:INSPECT_MODE] = true
      when "--noinspect"
        @CONF[:INSPECT_MODE] = false
      when "--readline"
        @CONF[:USE_READLINE] = true
      when "--noreadline"
        @CONF[:USE_READLINE] = false
      when "--echo"
        @CONF[:ECHO] = true
      when "--noecho"
        @CONF[:ECHO] = false
      when "--verbose"
        @CONF[:VERBOSE] = true
      when "--noverbose"
        @CONF[:VERBOSE] = false
      when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
        opt = $1 || ARGV.shift
        prompt_mode = opt.upcase.tr("-", "_").intern
        @CONF[:PROMPT_MODE] = prompt_mode
      when "--noprompt"
        @CONF[:PROMPT_MODE] = :NULL
      when "--inf-ruby-mode"
        @CONF[:PROMPT_MODE] = :INF_RUBY
      when "--sample-book-mode", "--simple-prompt"
        @CONF[:PROMPT_MODE] = :SIMPLE
      when "--tracer"
        @CONF[:USE_TRACER] = true
      when /^--back-trace-limit(?:=(.+))?/
        @CONF[:BACK_TRACE_LIMIT] = ($1 || ARGV.shift).to_i
      when /^--context-mode(?:=(.+))?/
        @CONF[:CONTEXT_MODE] = ($1 || ARGV.shift).to_i
      when "--single-irb"
        @CONF[:SINGLE_IRB] = true
      when /^--irb_debug=(?:=(.+))?/
        @CONF[:DEBUG_LEVEL] = ($1 || ARGV.shift).to_i
      when "-v", "--version"
        print IRB.version, "\n"
        exit 0
      when "-h", "--help"
        require "irb/help"
        IRB.print_usage
        exit 0
      when "--"
        if opt = ARGV.shfit
          @CONF[:SCRIPT] = opt
          $0 = opt
        end
        break
      when /^-/
        IRB.fail UnrecognizedSwitch, opt
      else
        @CONF[:SCRIPT] = opt
        $0 = opt
        break
      end
    end
    if RUBY_VERSION >= FEATURE_IOPT_CHANGE_VERSION
      load_path.collect! do |path|
        /\A\.\// =~ path ? path : File.expand_path(path)
      end
    end
    $LOAD_PATH.unshift(*load_path)

  end

It is hardcoded to take that option as the script name (@CONF[:SCRIPT] = opt). Luckily, this is Ruby. The first idea I had was using a different script to launch IRB that modifies the module first.

~/bin/custom-irb:

#!/usr/bin/env ruby
require 'irb'
module IRB
  class << self
    # sort of lame way to reset the parts we don't like about
    # parse_opts after it does the parts we do like
    def parse_opts_with_ignoring_script
      arg = ARGV.first
      script = $0
      parse_opts_without_ignoring_script
      @CONF[:SCRIPT] = nil
      $0 = script
      ARGV.unshift arg
    end
    alias_method :parse_opts_without_ignoring_script, :parse_opts
    alias_method :parse_opts, :parse_opts_with_ignoring_script
  end
end

if __FILE__ == $0
  IRB.start(__FILE__)
else
  # check -e option
  if /^-e$/ =~ $0
    IRB.start(__FILE__)
  else
    IRB.setup(__FILE__)
  end
end

You can launch this with custom-irb foo bar baz and ARGV will be ['foo', 'bar', 'baz'].

scragz
  • 6,670
  • 2
  • 23
  • 23
  • +1 Ugly, but gets the job done. It's the Susan Boyle of scripts. – zetetic Jan 23 '11 at 21:08
  • 1
    Nice hack @scragz. It might make some sense to allow `irb - a b c` as a way to bypass the file requirement but your answer covers the question nicely. – noodl Jan 24 '11 at 18:44
  • Yes allowing irb - a b c would address the original posters concern and eliminate the duplicate code. Anyone care to query current IRB maintainer for quick patch? – DMisener Jan 24 '11 at 18:52
-1

You can make a file that modifies ARGV and then use '-r' to include it.

$ echo 'ARGV = ["testing", "1","2","3"]' > ~/blah.rb && irb -r ./blah test.rb 
/home/me/blah.rb:1: warning: already initialized constant ARGV
test.rb(main):001:0> require 'pp'
=> true
test.rb(main):002:0* pp ARGV
["testing", "1", "2", "3"]
=> ["testing", "1", "2", "3"]
test.rb(main):003:0> 

You could even redirect it to your your ~/.irbrc and leave out the '-r ./blah'.

onionjake
  • 3,905
  • 27
  • 46
-1

quite strange solution is to create file with variables

# defaults.rb
@a = "hello world"

And

# terminal
=> irb -r defaults.rb
irb=> @a
irb=> "hello world"
fl00r
  • 82,987
  • 33
  • 217
  • 237
  • This doesn't easily allow passing parameters into an interactive IRB based shell clone. – DMisener Jan 21 '11 at 16:05
  • I think you have misunderstood the question. This is about populating the ARGV constant that is populated with parameters passed on the command line. – mydoghasworms Jan 30 '12 at 07:51