"Milo Thurston" <milo.thurston / bioinf.ceh.ac.uk> schrieb im Newsbeitrag
news:c7qnj9$7k3$1 / news.ox.ac.uk...
> I've just started trying out ruby, having been using perl, and
> encountered a small problem with the getopt module, as follows.
> I re-wrote a script that is meant to glob huge numbers of files,
> to get around the shell's globbing limitations. It has options
> for the suffix to glob "-g" and other things to do e.g. "-d" to
> delete them. However, the options work in one order but not another,
> e.g.
>
> $ ./globber.rb -g gbk -d
> globs *.gbk and deletes the files.
>
> $ ./globber.rb -d -g gbk
> Fails to glob any files and exits.
>
> Here are the relevant parts of the code.
>
> parser = GetoptLong.new
> parser.ordering = GetoptLong::PERMUTE
> parser.set_options(
> ["-h", "--help", GetoptLong::NO_ARGUMENT],
> ["-d", "--delete", GetoptLong::NO_ARGUMENT],
> ["-g", "--glob", GetoptLong::REQUIRED_ARGUMENT],
> ["-o", "--output", GetoptLong::OPTIONAL_ARGUMENT]
> )
>
> # process options
> files = nil
> outfile = nil
> loop do
> begin
> opt, arg = parser.get
> break if not opt
> case opt
> when "-g"
> files = Dir["*.#{arg}"]
> when "-d"
> files.each {|f|
> File.unlink(f)
> puts "Deleting #{f}..."
> }
> exit
> end
> end
>
> if files == nil
> puts "No files available!"
> else
> puts files
> end
>
>
> Presumably my problem is the loop, but I can't see any other way to do
> this in the documents. Is there an equivalent of perl's use of a hash
> to process options?

Your problem is that you do the work while you are processing options.  If
you place -d before -g then you won't have globbed anything when
encountering -d - so there's nothing to delete.  Normally you first
process options and then act on them.  This is what I did when using
GetoptLong (untested):

require 'getoptlong'

files = []
outfile = nil
delete = nil

opts = GetoptLong.new(
  ["--help", "-h", GetoptLong::NO_ARGUMENT],
  ["--delete", "-d", GetoptLong::NO_ARGUMENT],
  ["--glob", "-g", GetoptLong::REQUIRED_ARGUMENT],
  ["--output", "-o", GetoptLong::OPTIONAL_ARGUMENT]
)

opts.each do |opt, arg|
  case opt
    when "--help"
      puts "Help!"
    when "--delete"
      delete = true
    when "--glob"
      files.concat Dir["*.#{arg}"]
    when "--output"
      outfile = arg
    else
      raise "Error"
  end
end

if files.empty?
  $stderr.puts "no files"
else
  files.each do |f|
    puts "Deleting #{f}"
    File.unlink(f)
  end if delete

  puts files
end

Note: now that optparse is part of the std distribution you might want to
look into that, too.

Regards

    robert