GetoptLong, but not on ARGV

Is there a way to utilize Getoptlong on an arbitrary command var, ie.
not on ARGV. I figure I can alway do something like:

  require 'getoptlong'

  my_argv = Shellwords.shellwords( "foo -x" )

  const_set(:ARGV, my_argv)

  opts = GetoptLong.new(
    [ '-x', GetoptLong::NO_ARGUMENT ]
  )

But it just doesn't seem proper to reset ARGV.

Thanks,
T.

Basically did
%s/ARGV/(@arglist||ARGV)/g
and inserted the attribute accessor, funny thing seems to work :wink:

opts = GetoptLong.new(
   [ '-x', GetoptLong::NO_ARGUMENT ]
)
opts.arglist = Shellwords.shellwords( "foo -x" )

getoptlong.patch (2.13 KB)

···

On 6/20/07, Trans <transfire@gmail.com> wrote:

Is there a way to utilize Getoptlong on an arbitrary command var, ie.
not on ARGV. I figure I can alway do something like:

  require 'getoptlong'

  my_argv = Shellwords.shellwords( "foo -x" )

  const_set(:ARGV, my_argv)

  opts = GetoptLong.new(
    [ '-x', GetoptLong::NO_ARGUMENT ]
  )

But it just doesn't seem proper to reset ARGV.

Thanks,
T.

--
Too boldly go where no one has gone before
  -- forgot who said that

Robert

Ah, so we need a patch. Okay well I guess I'll post that up on the
board too.

Thanks Robert,
T.

···

On Jun 20, 4:18 pm, "Robert Dober" <robert.do...@gmail.com> wrote:

On 6/20/07, Trans <transf...@gmail.com> wrote:

> Is there a way to utilize Getoptlong on an arbitrary command var, ie.
> not on ARGV. I figure I can alway do something like:

> require 'getoptlong'

> my_argv = Shellwords.shellwords( "foo -x" )

> const_set(:ARGV, my_argv)

> opts = GetoptLong.new(
> [ '-x', GetoptLong::NO_ARGUMENT ]
> )

> But it just doesn't seem proper to reset ARGV.

> Thanks,
> T.

Basically did
%s/ARGV/(@arglist||ARGV)/g
and inserted the attribute accessor, funny thing seems to work :wink:

opts = GetoptLong.new(
   [ '-x', GetoptLong::NO_ARGUMENT ]
)
opts.arglist = Shellwords.shellwords( "foo -x" )

Ah, so we need a patch. Okay well I guess I'll post that up on the
board too.

Yes definitely ARGV is hardcoded, I was however fooling around, trying
to make a patch in less than a minute, which worked ;).

If you really want to send up a patch, please consider this one (it is
a correct patch created with diff -u this time too):

It does *not* temper with internal state, just allows an array to be
passed to #each or #get. I tested it with this use case:

------------------ 8< -------------------------
require 'getoptlong'

opt = GetoptLong.new([ '-x', GetoptLong::NO_ARGUMENT ],[ '-b',
GetoptLong::REQUIRED_ARGUMENT])

blk = lambda do
  >*v|
  puts v.join(": ")
end
opt.dup.each %w{ -x -b 1024}, &blk

opt.dup.each %w{ -b 4096 }, &blk
------------------------------ 8<---------------------------

Please note the necessity of dup for reuse, I did not want to bother
with internal state of a class I do not understand and I have no time
to dig into :(.

Cheers
Robert

getoptlong.patch (2.93 KB)

···

On 6/21/07, Trans <transfire@gmail.com> wrote:

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Hi,

At Thu, 21 Jun 2007 17:04:15 +0900,
Robert Dober wrote in [ruby-talk:256352]:

It does *not* temper with internal state, just allows an array to be
passed to #each or #get. I tested it with this use case:

You forget about #terminate.

···

--
Nobu Nakada

I think i would be better to do:

  def argslist
    @argslist ||= ARGV # or ARGV.dup
  end

  def argslist=(array)
    @argslist = array.to_ary
  end

and then /argslist/ARGV/g

T.

···

On Jun 21, 4:04 am, "Robert Dober" <robert.do...@gmail.com> wrote:

On 6/21/07, Trans <transf...@gmail.com> wrote:

> Ah, so we need a patch. Okay well I guess I'll post that up on the
> board too.

Yes definitely ARGV is hardcoded, I was however fooling around, trying
to make a patch in less than a minute, which worked ;).

If you really want to send up a patch, please consider this one (it is
a correct patch created with diff -u this time too):

It does *not* temper with internal state, just allows an array to be
passed to #each or #get. I tested it with this use case:

------------------ 8< -------------------------
require 'getoptlong'

opt = GetoptLong.new([ '-x', GetoptLong::NO_ARGUMENT ],[ '-b',
GetoptLong::REQUIRED_ARGUMENT])

blk = lambda do
  >*v|
  puts v.join(": ")
end
opt.dup.each %w{ -x -b 1024}, &blk

opt.dup.each %w{ -b 4096 }, &blk
------------------------------ 8<---------------------------

Please note the necessity of dup for reuse, I did not want to bother
with internal state of a class I do not understand and I have no time
to dig into :(.

Cheers
Robert

Thanks nobu, does this fix it?

Robert

getoptlong.patch (3.59 KB)

···

On 6/21/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

Hi,

At Thu, 21 Jun 2007 17:04:15 +0900,
Robert Dober wrote in [ruby-talk:256352]:
> It does *not* temper with internal state, just allows an array to be
> passed to #each or #get. I tested it with this use case:

You forget about #terminate.

--
Nobu Nakada

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

I think i would be better to do:

  def argslist
    @argslist ||= ARGV # or ARGV.dup
  end

  def argslist=(array)
    @argslist = array.to_ary
  end

and then /argslist/ARGV/g

Hmm more in the spirit of the original class probably.
Anyway if Nobu really wants this little patch I can adapt the patch to
your approach if he prefers.

Robert

···

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Hi,

At Thu, 21 Jun 2007 19:45:08 +0900,
Robert Dober wrote in [ruby-talk:256371]:

Thanks nobu, does this fix it?

Almost, but #terminate can be called outside #get. I think
getoptlong isn't designed for such usage.

     @non_option_arguments.reverse_each do |argument|
- ARGV.unshift(argument)
+ args.unshift(argument)
     end

In short, this can be:

      args.unshift(*@non_option_arguments)

···

--
Nobu Nakada

Hi,

At Thu, 21 Jun 2007 19:45:08 +0900,
Robert Dober wrote in [ruby-talk:256371]:
> Thanks nobu, does this fix it?

Almost, but #terminate can be called outside #get. I think
getoptlong isn't designed for such usage.

> @non_option_arguments.reverse_each do |argument|
> - ARGV.unshift(argument)
> + args.unshift(argument)
> end

In short, this can be:

      args.unshift(*@non_option_arguments)

I did not want to lecture :wink:
Hmm I am a little bit confused now because I have provided #terminate
with a defaulted parameter for exactly the reason above.
Anyway I think Tom's idea to use an instance variable @args (defaulting to ARGV)
with an attribute accessor reflects the spirit of the original design
much better.
I will try to find half an hour to do that for fun this weekend and I
will send it, feel free to use it or to loose it ;).

Cheers
Robert

···

On 6/21/07, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:

--
Nobu Nakada

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Here goes the patch implementing Tom's idea. I also removed the clumsy
loop in #terminate, and than I started to write a test-suite, but I
got puzzled by this behavior ( same for the original getoptlong.rb and
the patched one ):

------------------- 8< -----------------------------
577/77 > cat test_getoptlong_basic.rb && ruby test_getoptlong_basic.rb
require 'test/unit'
require 'getoptlong'

class GetoptLong; include Enumerable end

class TestGetoptLongBasic < Test::Unit::TestCase
  def setup
        @opt = GetoptLong.new([ '-x', GetoptLong::NO_ARGUMENT ],[ '-b',
          GetoptLong::REQUIRED_ARGUMENT])
  end

  def test_0_basic
        ARGV.clear.push *%w{ -x -b 4096 }
        assert_equal [ ["-x", ""], ["-b", "4096"] ],
@opt.dup.inject([]){|a, o| a << o }
        assert_equal [], ARGV

        ARGV.push *%w{ alpha -x 12 -b 4096 }
        assert_equal [ ["-x", ""], ["-b", "4096"] ],
@opt.dup.inject([]){|a, o| a << o }
        assert_equal %w{ alpha 12 }, ARGV

        ARGV.clear.push *%w{ -- -b 4096 }
        assert_equal [], @opt.dup.inject([]){|a, o| a << o }
        assert_equal %w{-b 4096}, ARGV # line 23
  end

end
Loaded suite test_getoptlong_basic
Started
F
Finished in 0.014403 seconds.

  1) Failure:
test_0_basic(TestGetoptLongBasic) [test_getoptlong_basic.rb:23]:
<["-b", "4096"]> expected but was
<["alpha", "12", "-b", "4096"]>.

1 tests, 6 assertions, 1 failures, 0 errors
------------------- 8< -----------------------------

Any thoughts about it?
cheers
Robert

getoptlong.patch (4.76 KB)

···

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw