Joe Van Dyk
12/21/2005 11:16:00 PM
On 12/21/05, Joe Van Dyk <joevandyk@gmail.com> wrote:
> On 12/21/05, Matthew Feadler <matthew@feadler.com> wrote:
> > Retro thanks to all who helped me with my last post. I'm certainly more
> > comfortable with Ruby now than then, but still a newbie as the following
> > will surely demonstrate.
> >
> > Below, you can see that I'm checking command-line arguments to the
> > program for various conditions. Unfortunately, because the args are
> > stored as strings, when I convert them via to_i, empty and non-numerical
> > strings become 0. 0 is an acceptable element in this program, therefore
> > I can't use it to test for invalid input. I've worked around this (sort
> > of), by creating two sets of variables for the arguments (one set as
> > strings, one set as integers). Unfortunately, this complicates the
> > code, and more importantly, leaves me stumped concerning how to test for
> > non-numeric values.
> >
> > So, the program does what I want, except when the args are non-numeric
> > strings, and the code seems uglier than it ought to be.
> >
> > Thanks in advance,
> >
> > -ELf
> >
> > def gen_chart(max)
> > x=0
> > y=0
> > local_chart = Array.new
> > while x<=max
> > y+=x
> > local_chart[x]=y
> > x+=1
> > end
> > local_chart
> > end
> >
> > arg0 = ARGV[0]
> > arg1 = ARGV[1]
> >
> > arg0i = ARGV[0].to_i
> > arg1i = ARGV[1].to_i
> >
> > if arg0.nil? or (arg0i < 0) or (arg1i < 0)
> > #print usage
> > print <<-EOS
> >
> > No args, or bad args!
> >
> > Usage: #$0 [maxvalue]
> > #$0 [minvalue] [maxvalue]
> > EOS
> > elsif arg1.nil?
> > #do chart to arg0, print last pair
> > chart = gen_chart(arg0i)
> > puts arg0i.to_s + ": " + chart[arg0i].to_s
> > else
> > #do chart to arg1, print pairs from arg0 to last
> > chart = gen_chart(arg1i)
> > x=arg0i
> > y=arg1i
> > while x<=y
> > puts x.to_s + ": " + chart[x].to_s
> > x+=1
> > end
> > end
>
> Maybe this will give you an idea or two:
>
> require 'test/unit'
>
> def process_command_line_arguments args
> results = []
> args.each do |arg|
> raise "Hey, '#{ arg }' needs to be a number" if !arg.match(/^\d*$/)
> arg = arg.to_i
> results << arg
> end
> results
> end
>
> class TestThis < Test::Unit::TestCase
> def test_command_line_processing
> assert_equal [2], process_command_line_arguments(["2"])
> assert_equal [2, 3], process_command_line_arguments(["2", "3"])
> assert_raise(RuntimeError) { process_command_line_arguments(["-1"]) }
> assert_raise(RuntimeError) { process_command_line_arguments(["1", "oog"]) }
> assert_raise(RuntimeError) { process_command_line_arguments(["boo", "oog"])}
> end
> end
>
>
>
> $ ruby a.rb
> Loaded suite a
> Started
> .
> Finished in 0.001163 seconds.
>
> 1 tests, 5 assertions, 0 failures, 0 errors
>
Whoops, this is probably better:
def process_command_line_arguments args
args.map do |arg|
raise "Hey, '#{ arg }' needs to be a number" if !arg.match(/^\d*$/)
arg.to_i
end
end
Passes all the tests.