On 06.05.2007 15:30, Robert Klemme wrote:
> On 06.05.2007 15:20, anansi wrote:
>> Hi,
>> I'm struggeling with writing a little script. It has a loop just e.g. 
>> like this:
>>
>> for x in 1..10 do
>> begin
>>  puts "#{x}"
>> end
>>
>> The userinput is the loop count (so above the userinput would have 
>> been 1..10): but now this userinput can be a fixnum like 12 or 36 or 
>> it can be a range like 1..10 or 24..84 or an array like [23,41,35,63] 
>> and for every 3 different input kinds the loop shall do the same.
>>
>> Like in this example:
>>
>> If userinput is just fixnum 11 it just prints 11 on the screen, is it 
>> a range from 1..10 all numbers from 1..10 shall be printed and for an 
>> array all single numbers stored in the array...you know what I mean. 
>> The actual routine doesn't print anything it's just about I have to 
>> process numbers which can the user give in, in three different ways 
>> and I was wondering if it is possible to build this into one single 
>> loop and not three different ones?
> 
> How about
> 
> def my_loop(x,&b)
>   case x
>     when /\A\d+\z/
>       x.to_i.times(&b)
>     when /\A(\d+)\.\.(\d+)\z/
>       ($1.to_i .. $2.to_i).each(&b)
>     when /\A\[\s*\d+\s*(?:,\s*\d+\s*)*\]\z/
>       eval(x).each(&b)
>     else
>       raise ArgumentError, "Don't know what to do with: #{x}"
>   end
> end
> 
>  >> my_loop("5") {|x| p x}
> 0
> 1
> 2
> 3
> 4
> => 5
>  >> my_loop("1..5") {|x| p x}
> 1
> 2
> 3
> 4
> 5
> => 1..5
>  >> my_loop("[5,3,2]") {|x| p x}
> 5
> 3
> 2
> => [5, 3, 2]
>  >> my_loop("1,2") {|x| p x}
> ArgumentError: Don't know what to do with: 1,2
>         from (irb):10:in `my_loop'
>         from (irb):16
>         from :0
>  >>
> 
> Kind regards
> 
>     robert

more elegant:

def my_loop(x,&b)
   case x
     when /\A\d+\z/
       1 .. x.to_i
     when /\A(\d+)\.\.(\d+)\z/
       ($1.to_i .. $2.to_i)
     when /\A\[\s*\d+\s*(?:,\s*\d+\s*)*\]\z/
       eval(x)
     else
       raise ArgumentError, "Don't know what to do with: #{x}"
   end.each(&b)
end

more modular:

def my_enum(x,&b)
   case x
     when /\A\d+\z/
       1 .. x.to_i
     when /\A(\d+)\.\.(\d+)\z/
       ($1.to_i .. $2.to_i)
     when /\A\[\s*\d+\s*(?:,\s*\d+\s*)*\]\z/
       eval(x)
     else
       raise ArgumentError, "Don't know what to do with: #{x}"
   end
end

	robert