How can I pass <arguments> to IRB if I don't specify <programfile>?
Asked Answered
P

4

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?

Padegs answered 20/1, 2011 at 16:6 Comment(5)
That is a badly formatted series of sample code and examples. Please try reediting and formatting using the examples provided in Editing Help. Normally I'd help clean it up for you, but there is too much, and I don't know your intention.Krystin
Why do you want to pass arguments if you could set them in irb? Are the arguments being used by the SpecialLibrary?Molnar
I want to alias "special == irb -rSpecialLibrary" so I can do something like "special A B C" as illustrated above.Padegs
I cleaned up the code example using the Editing Help... thanks for the pointer.Padegs
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<moduleName>)Padegs
S
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'].

Successive answered 23/1, 2011 at 19:40 Comment(3)
+1 Ugly, but gets the job done. It's the Susan Boyle of scripts.Heaviside
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.Rosenbaum
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?Padegs
C
0

As of 2022, there is now a --noscript option to accomplish this goal. See the IRB documentation for an explanation and example usage, reproduced here:

$ irb --noscript Foo Bar Baz
irb(main):001> ARGV
=> ["Foo", "Bar", "Baz"]
Cuisine answered 22/12, 2023 at 20:33 Comment(0)
C
-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"
Critter answered 20/1, 2011 at 17:41 Comment(2)
This doesn't easily allow passing parameters into an interactive IRB based shell clone.Padegs
I think you have misunderstood the question. This is about populating the ARGV constant that is populated with parameters passed on the command line.Barthelemy
M
-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'.

Milliliter answered 2/10, 2013 at 1:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.