2009/10/26 Michael Randall <randallsata / gmail.com>: > I am sure I'm making a newbie mistake, as I've just started learning > Ruby, and would really appreciate someone pointing out what I've done > wrong, why it is wrong, and how it *should* be done. Thanks in advance. > > I am writing a method definition to double any number, or all numbers if > an array of numbers is passed to it. When I use array.collect outside of > the method, it works as expected. When I place it inside of the method, > instead of multiplying each integer, it treats the entire array as one > object and double it, [1, 2, 3, 4] becoming 12341234. > > I've attached my test code, "simplea.rb", and below is the output when I > run it. In case it matters to anyone, I'm running Ruby 1.8.7 under > Cygwin (because I hate windows and don't have a Mac yet). ;) > > $ simplea.rb > > Test double([1, 2, 3, 4]) > > 12341234 > > > Test double( 3 ) > > 6 > > > > Let's prove it. > 2 > 4 > 6 > 8 > > Attachments: > http://www.ruby-forum.com/attachment/4184/simplea.rb There are a few issues with the first line: my_a = [ n ].to_a unless n.class == "Array" First, the test will always fail because the class and the name of the class are of different types: irb(main):002:0> Array == "Array" => false Then, you only need either "[n]" or "n.to_a" but not both. I recommend the former (the latter is deprecated). Here is _one_ way to do it: def double(x) Enumerable === x ? x.map {|i| i * 2} : x * 2 end irb(main):006:0> double 1 => 2 irb(main):007:0> double [1,2,3] => [2, 4, 6] (Note, #map is the same as #collect.) --- spoiler warning --- An alternative is to use the splat operator and always work with Arrays: def double(*a) a.map {|i| i * 2} end irb(main):011:0> double 1 => [2] irb(main):012:0> double 1,2,3 => [2, 4, 6] irb(main):013:0> double [1,2,3] => [[1, 2, 3, 1, 2, 3]] Or, a bit more sophisticated def double(*a) a.flatten.map {|i| i * 2} end irb(main):017:0> double 1 => [2] irb(main):018:0> double 1,2,3 => [2, 4, 6] irb(main):019:0> double [1,2,3] => [2, 4, 6] And finally with special treatment of case 1 element: def double(*a) a.flatten! case a.size when 0 raise ArgumentError, "need values" when 1 a.first * 2 else a.map {|i| i * 2} end end irb(main):054:0> double 1 => 2 irb(main):055:0> double 1,2,3 => [2, 4, 6] irb(main):056:0> double [1,2,3] => [2, 4, 6] Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/