From: Joe Van Dyk Date: 2005-12-22T08:16:23+09:00 Subject: Re: String > Integer Conversion Problem On 12/21/05, Joe Van Dyk wrote: > On 12/21/05, Matthew Feadler 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.