From: Robert Klemme Date: 2009-12-20T21:25:09+09:00 Subject: Re: Splat array with 1 value in Ruby 1.9 vs Ruby 1.8 Please do not top post. On 20.12.2009 00:28, Benoit Daloze wrote: > Humm, well, it has a very-not-easy-to-see link, but it is. > > I imagined at a moment using the splat operator, while it can of course not > work without any variable. > > I use code above to allow dynamic parameters based on the name of the > variable who's result of that method is assigned to that variable. > (for exemple : > x = var > allow to pass a parameter "x" to the method var() ) > > So I'm *scan*ning the code (probably not a good idea but ...) and then I > want this method to return an array if I do: > x, y = var > or a single object like above. I believe you are overlooking something: the very moment that you do "x = meth(...)" you are *expecting* a single value or you are *expecting* an Array with any number of elements. If you do "a,b,c = meth(...)" you are *expecting* multiple values, typically three. The expectation is expressed by the code that follows this line, i.e. if you do x = meth(...) x.each {|m| ... } your code expects an Array with any number of entries. If you do x = meth(...) puts Integer(x) your code expects a single value. If you have these two different use cases of your method, it makes every sense in the world to have *two* different methods. It's easier for the implementation and it is more efficient as well because when you expect a single value you can use String#[] or a regexp match with =~ instead of scanning the whole string. Now if you argue that you want to use the same regexp in both cases, that's not too difficult: both methods can share the regexp. RX = /.../ def m1(...) s[RX] end def mn(...) s.scan RX end In fact, if the implementation is just a single line both methods might actually be superfluous and you could use the regular expression directly. Your wish may be motivated by Perl experience where a method can actually find out what the caller expects but Ruby is different and I believe it does not make sense to try to force perlisms into a Ruby program. Btw, there's also a different way to deal with this: def m(...) s.scan ... end a, = m(...) a,b,c = m(...) By doing that every variable receives a single value and you do can always return an Array. irb(main):001:0> def demo(items) Array.new(items) {|i| i} end => nil irb(main):002:0> demo(5) => [0, 1, 2, 3, 4] irb(main):003:0> a, = demo(5); a => 0 irb(main):004:0> a,b,c = demo(5) => [0, 1, 2, 3, 4] irb(main):005:0> a => 0 irb(main):006:0> b => 1 irb(main):007:0> c => 2 irb(main):012:0> a,b,c = demo(2) => [0, 1] irb(main):013:0> a => 0 irb(main):014:0> b => 1 irb(main):015:0> c => nil Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/