f



Splat array with 1 value in Ruby 1.9 vs Ruby 1.8

In porting some automation code from 1.8.7 to 1.9.1, I find that in ruby
1.8 the following generated code (real code is unpacking binary strings
and assigning variables, but I simplify for clarity, although the result
may look a bit silly) worked:

  var1                     = *[ val1 ]                       # var1 =
val1
  var1, var2, varn = *[ val1, val2, valn ]   #       ,,

(the splat is not necessary in the second case, but this allowed the
code to be generated in the same way, regardless of array size).

With Ruby 1.9.1-p243, instead, this happens:

   var1                      = *[ val1 ]                     # var1 = [
val1 ]  (!)
   var1, var2, varn = *[ val1, val2, valn ]   # var1 = val1

So in the first case, var1 became an array (instead than the expected
integer).
Of course, this can be fixed by generating code that checks the array
size (and doing a shift if 1, etc). But I am curious on this behavior of
splat when the array contains one element (I read about the
differences/new features of splat in 1.9, but they seem to have nothing
to do with this). Does anyone know if it is a bug?

Thanks

Raul Parolari
-- 
Posted via http://www.ruby-forum.com/.

0
12/1/2009 5:49:21 AM
comp.lang.ruby 48886 articles. 0 followers. Post Follow

15 Replies
876 Views

Similar Articles

[PageSpeed] 56

[ Sorry for the horrible indentation. I repeat the text renouncing to 
align the expressions ]

In porting some automation code from 1.8.7 to 1.9.1, I find that in ruby 
1.8 the following worked (real code is unpacking binary strings and 
assigning variables, but I simplify for clarity):

  var1  = *[ val1 ]   # => var1 = val1

  var1, var2, varn = *[ val1, val2, valn ]

(I know that the splat is not necessary in the second case, but this 
allowed the code to be generated in the same way, regardless of array 
size).

With Ruby 1.9.1, instead, this happens:

   var1  = *[ val1 ]   # => var1 = [ val1 ]  (!)

   var1, var2, varn = *[ val1, val2, valn ]

Of course, this can be handled by generating code that checks the array 
size. But I am curious on this behavior of splat when the array contains 
one element (I read about the features of splat in 1.9, but they seem to 
have nothing to do with this). Does anyone know if it is a bug or 
intentional?

Thanks
-- 
Posted via http://www.ruby-forum.com/.

0
Raul
12/1/2009 5:53:56 AM
On Tue, Dec 1, 2009 at 12:53 AM, Raul Parolari <raulparolari@gmail.com> wro=
te:
> [ Sorry for the horrible indentation. I repeat the text renouncing to
> align the expressions ]
>
> In porting some automation code from 1.8.7 to 1.9.1, I find that in ruby
> 1.8 the following worked (real code is unpacking binary strings and
> assigning variables, but I simplify for clarity):
>
> =A0var1 =A0=3D *[ val1 ] =A0 # =3D> var1 =3D val1
>
> =A0var1, var2, varn =3D *[ val1, val2, valn ]
>
> (I know that the splat is not necessary in the second case, but this
> allowed the code to be generated in the same way, regardless of array
> size).
>
> With Ruby 1.9.1, instead, this happens:
>
> =A0 var1 =A0=3D *[ val1 ] =A0 # =3D> var1 =3D [ val1 ] =A0(!)
>
> =A0 var1, var2, varn =3D *[ val1, val2, valn ]
>
> Of course, this can be handled by generating code that checks the array
> size. But I am curious on this behavior of splat when the array contains
> one element (I read about the features of splat in 1.9, but they seem to
> have nothing to do with this). Does anyone know if it is a bug or
> intentional?


Not sure exactly what you mean by generating the code, but could you use

var1 =3D val1
and
var1, var2, varn =3D val1, val2, valn



--=20
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

0
Rick
12/1/2009 3:26:34 PM
Rick Denatale wrote:
> On Tue, Dec 1, 2009 at 12:53 AM, Raul Parolari <raulparolari@gmail.com> 
> wrote:
>>
>> Of course, this can be handled by generating code that checks the array
>> size. But I am curious on this behavior of splat when the array contains
>> one element (I read about the features of splat in 1.9, but they seem to
>> have nothing to do with this). Does anyone know if it is a bug or
>> intentional?
> 
> 
> Not sure exactly what you mean by generating the code, but could you use
> 
> var1 = val1
> and
> var1, var2, varn = val1, val2, valn
> 
> 
> 
> --
> Rick DeNatale
> 
> Blog: http://talklikeaduck.denhaven2.com/
> Twitter: http://twitter.com/RickDeNatale

As I said at the beginning of the post, the code is unpacking binary 
strings, which generates an array (else of course I would have not added 
the array, just for the fun of having to remove it). For example:

   x, y = "\x23\x00\x61".unpack('Cn')  # => [35, 97]; so: x = 35; y = 97

Now, when there is just one variable to extract, we get (as expected):

   z="\x00\x61".unpack('n')   # z = [97]

To get the scalar values in both cases, in 1.8.7 a splat operator in 
front of the right value expression (placed by the code generator) does 
the job; in 1.9.1, it does not. The solution is simple, but I was not 
asking for "a solution".

In other words, I was just pointing out this difference of behavior:

  a = *[ 3 ]   # =>  a =3        with Ruby 1.8.7

  a = *[ 3 ]   # => a = [ 3 ]    with Ruby 1.9.1

I think that this is a bug in Ruby 1.9.

Raul Parolari





   x =


-- 
Posted via http://www.ruby-forum.com/.

0
Raul
12/1/2009 3:59:04 PM
2009/12/1 Raul Parolari <raulparolari@gmail.com>:
> Rick Denatale wrote:
>> On Tue, Dec 1, 2009 at 12:53 AM, Raul Parolari <raulparolari@gmail.com>
>> wrote:
>>>
>>> Of course, this can be handled by generating code that checks the array
>>> size. But I am curious on this behavior of splat when the array contain=
s
>>> one element (I read about the features of splat in 1.9, but they seem t=
o
>>> have nothing to do with this). Does anyone know if it is a bug or
>>> intentional?
>>
>>
>> Not sure exactly what you mean by generating the code, but could you use
>>
>> var1 =3D val1
>> and
>> var1, var2, varn =3D val1, val2, valn
>>
>>
>>
>> --
>> Rick DeNatale
>>
>> Blog: http://talklikeaduck.denhaven2.com/
>> Twitter: http://twitter.com/RickDeNatale
>
> As I said at the beginning of the post, the code is unpacking binary
> strings, which generates an array (else of course I would have not added
> the array, just for the fun of having to remove it). For example:
>
> =A0 x, y =3D "\x23\x00\x61".unpack('Cn') =A0# =3D> [35, 97]; so: x =3D 35=
; y =3D 97
>
> Now, when there is just one variable to extract, we get (as expected):
>
> =A0 z=3D"\x00\x61".unpack('n') =A0 # z =3D [97]
>
> To get the scalar values in both cases, in 1.8.7 a splat operator in
> front of the right value expression (placed by the code generator) does
> the job; in 1.9.1, it does not. The solution is simple, but I was not
> asking for "a solution".
>
> In other words, I was just pointing out this difference of behavior:
>
> =A0a =3D *[ 3 ] =A0 # =3D> =A0a =3D3 =A0 =A0 =A0 =A0with Ruby 1.8.7
>
> =A0a =3D *[ 3 ] =A0 # =3D> a =3D [ 3 ] =A0 =A0with Ruby 1.9.1
>
> I think that this is a bug in Ruby 1.9.

Regardless whether it is or is not a bug (I would not be so sure of
that), there is a way to fix it and handle it uniformly across Ruby
versions:

17:31:18 test$ allruby -e 'a =3D [123];b =3D *[456];c, =3D [789]; p a,b,c'
CYGWIN_NT-5.1 padrklemme1 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
[123]
456
789
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-cygwin]
[123]
[456]
789
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java
HotSpot(TM) Client VM 1.6.0_17) [x86-java]
[123]
456
789

Look at variable "c".

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

0
Robert
12/1/2009 4:32:23 PM
Robert Klemme wrote:
> 2009/12/1 Raul Parolari <raulparolari@gmail.com>:
>>>
>>>
>>
>>
>> �a = *[ 3 ] � # => a = [ 3 ] � �with Ruby 1.9.1
>>
>> I think that this is a bug in Ruby 1.9.
> 
> Regardless whether it is or is not a bug (I would not be so sure of
> that), there is a way to fix it and handle it uniformly across Ruby
> versions:
> 
> 17:31:18 test$ allruby -e 'a = [123];b = *[456];c, = [789]; p a,b,c'
> CYGWIN_NT-5.1 padrklemme1 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
> ========================================
> ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
> [123]
> 456
> 789
> ========================================
> ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-cygwin]
> [123]
> [456]
> 789
> ========================================
> jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java
> HotSpot(TM) Client VM 1.6.0_17) [x86-java]
> [123]
> 456
> 789
> 
> Look at variable "c".
> 
> Kind regards
> 
> robert

Indeed, this solves with grace the problem in the automation  (without 
the easy but disturbing question on "how many elements the array has"):

a,b, = [ 3, 4 ]    # => a = 3; b = 4
a,    = [ 3 ]         # => a  = 3

On the other matter ( a = *[ 3 ] ), I still think that it is a bug in 
1.9 (else I don't understand fully what a splat operator is, and I'd 
like to know more).

But thanks a lot, Robert

Raul Parolari



-- 
Posted via http://www.ruby-forum.com/.

0
Raul
12/1/2009 4:56:39 PM
On 12/01/2009 05:56 PM, Raul Parolari wrote:
> Robert Klemme wrote:
>> 2009/12/1 Raul Parolari <raulparolari@gmail.com>:
>>>>
>>>
>>> ?a =3D *[ 3 ] ? # =3D> a =3D [ 3 ] ? ?with Ruby 1.9.1
>>>
>>> I think that this is a bug in Ruby 1.9.
>> Regardless whether it is or is not a bug (I would not be so sure of
>> that), there is a way to fix it and handle it uniformly across Ruby
>> versions:
>>
>> 17:31:18 test$ allruby -e 'a =3D [123];b =3D *[456];c, =3D [789]; p a,=
b,c'
>> CYGWIN_NT-5.1 padrklemme1 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygw=
in
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
>> [123]
>> 456
>> 789
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-cygwin]
>> [123]
>> [456]
>> 789
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>> jruby 1.4.0 (ruby 1.8.7 patchlevel 174) (2009-11-02 69fbfa3) (Java
>> HotSpot(TM) Client VM 1.6.0_17) [x86-java]
>> [123]
>> 456
>> 789
>>
>> Look at variable "c".
>>
>> Kind regards
>>
>> robert
>=20
> Indeed, this solves with grace the problem in the automation  (without =

> the easy but disturbing question on "how many elements the array has"):=

>=20
> a,b, =3D [ 3, 4 ]    # =3D> a =3D 3; b =3D 4
> a,    =3D [ 3 ]         # =3D> a  =3D 3
>=20
> On the other matter ( a =3D *[ 3 ] ), I still think that it is a bug in=
=20
> 1.9 (else I don't understand fully what a splat operator is, and I'd=20
> like to know more).

I know there have been some things changed with regard to how the splat=20
operator works, including more complex patterns:

robert@fussel:~$ ruby1.9 -e 'def f(a,*b,c)p a,b,c end;f(1, 2, 3, 4)'
1
[2, 3]
4

This did not work in 1.8:

robert@fussel:~$ ruby1.8 -e 'def f(a,*b,c)p a,b,c end;f(1, 2, 3, 4)'
-e:1: syntax error, unexpected tIDENTIFIER, expecting tAMPER or '&'
def f(a,*b,c)p a,b,c end;f(1, 2, 3, 4)
             ^
robert@fussel:~$

The changes may make it necessary that 1.9 behaves the way you observed. =

  That's why I said I am not sure whether it is actually a bug.

> But thanks a lot, Robert

You're welcome!

Kind regards

	robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
0
Robert
12/1/2009 5:24:19 PM
Robert Klemme wrote:
> On 12/01/2009 05:56 PM, Raul Parolari wrote:
>>>
>>> [456]
>>> Kind regards
>> 1.9 (else I don't understand fully what a splat operator is, and I'd 
>> like to know more).
> 
> I know there have been some things changed with regard to how the splat
> operator works, including more complex patterns:
> 
> robert@fussel:~$ ruby1.9 -e 'def f(a,*b,c)p a,b,c end;f(1, 2, 3, 4)'
> 1
> [2, 3]
> 4
> 
> This did not work in 1.8:
> ...
> 
> The changes may make it necessary that 1.9 behaves the way you observed.
>   That's why I said I am not sure whether it is actually a bug.
> 

Hmm.. the difference is:
a) in 1.8 the splat operator could only be applied to the last 
left-value
b) in 1.9 the splat operator can appear at any position in the list of 
left-values

But the concept of the operation has remained identical: all extra 
rvalues are placed into an array

Similarly, 1.9 adds more flexibility when the splat is done on an rvalue 
(multiple splats). But the concept is still the same (in this case, as 
Matz/Flanagan's book says "the array elements replace the array in the 
original rvalue"). That's the reason that I think the behavior of
      a = *[ 3 ]    # => a = [ 3 ]
is a bug; else, it would go against the definition just given (just 
because the array has 1 element). Just my opinion, of course.

---

In any case, thanks again for the elegant solution to my code generation

Raul Parolari


-- 
Posted via http://www.ruby-forum.com/.

0
Raul
12/1/2009 6:11:24 PM
2009/12/1 Raul Parolari <raulparolari@gmail.com>:
> Hmm.. the difference is:
> a) in 1.8 the splat operator could only be applied to the last
> left-value
> b) in 1.9 the splat operator can appear at any position in the list of
> left-values
>
> But the concept of the operation has remained identical: all extra
> rvalues are placed into an array
>
> Similarly, 1.9 adds more flexibility when the splat is done on an rvalue
> (multiple splats). But the concept is still the same (in this case, as
> Matz/Flanagan's book says "the array elements replace the array in the
> original rvalue"). That's the reason that I think the behavior of
> =A0 =A0 =A0a =3D *[ 3 ] =A0 =A0# =3D> a =3D [ 3 ]
> is a bug; else, it would go against the definition just given (just
> because the array has 1 element). Just my opinion, of course.

If you believe you have found a bug, please file it so it can be taken care=
 of.
http://redmine.ruby-lang.org/

> In any case, thanks again for the elegant solution to my code generation

You're welcome!

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

0
Robert
12/2/2009 10:52:33 AM
Robert Klemme wrote:
> 2009/12/1 Raul Parolari <raulparolari@gmail.com>:
>> (multiple splats). But the concept is still the same (in this case, as
>> Matz/Flanagan's book says "the array elements replace the array in the
>> original rvalue"). That's the reason that I think the behavior of
>> � � �a = *[ 3 ] � �# => a = [ 3 ]
>> is a bug; else, it would go against the definition just given (just
>> because the array has 1 element). Just my opinion, of course.
> 
> If you believe you have found a bug, please file it so it can be taken 
> care of.
> http://redmine.ruby-lang.org/
> 
>> In any case, thanks again for the elegant solution to my code generation
> 
> You're welcome!
> 
> Kind regards
> 
> robert

Thanks for the suggestion; I just reported (what I believe to be) the 
bug, with the quote from Matz's book

Raul Parolari
-- 
Posted via http://www.ruby-forum.com/.

0
Raul
12/2/2009 5:53:35 PM
Well, so what's the solution to get the single element in the array or the
whole array when multiple elements ?

for exemple:

def my_method_handling_single_or_multiple
  ...
  "str".scan(/.../)
end

how to make this in a beautiful way?
I would like to have only the element if there is only one

of course, there is:
arr =3D "str".scan(/.../)
arr.length =3D=3D 1 ? arr[0] : arr

but that create a useless new variable and doesn't look good at all.

B.D.

2009/12/2 Raul Parolari <raulparolari@gmail.com>

> Robert Klemme wrote:
> > 2009/12/1 Raul Parolari <raulparolari@gmail.com>:
> >> (multiple splats). But the concept is still the same (in this case, as
> >> Matz/Flanagan's book says "the array elements replace the array in the
> >> original rvalue"). That's the reason that I think the behavior of
> >> =EF=BF=BD =EF=BF=BD =EF=BF=BDa =3D *[ 3 ] =EF=BF=BD =EF=BF=BD# =3D> a =
=3D [ 3 ]
> >> is a bug; else, it would go against the definition just given (just
> >> because the array has 1 element). Just my opinion, of course.
> >
> > If you believe you have found a bug, please file it so it can be taken
> > care of.
> > http://redmine.ruby-lang.org/
> >
> >> In any case, thanks again for the elegant solution to my code generati=
on
> >
> > You're welcome!
> >
> > Kind regards
> >
> > robert
>
> Thanks for the suggestion; I just reported (what I believe to be) the
> bug, with the quote from Matz's book
>
> Raul Parolari
> --
> Posted via http://www.ruby-forum.com/.
>
>

0
Benoit
12/19/2009 8:47:58 PM
Benoit Daloze wrote:
> Well, so what's the solution to get the single element in the array or 
> the
> whole array when multiple elements ?
..
> how to make this in a beautiful way?
> I would like to have only the element if there is only one
> 
> of course, there is:
> arr = "str".scan(/.../)
> arr.length == 1 ? arr[0] : arr
> 
> but that create a useless new variable and doesn't look good at all.
> 

Benoit, str.scan(pattern) always returns an array of matches; you then 
need to process the resulting array (for example, iterating on it, 
extracting the elements of the array). You seem to want a different 
result depending if the array size is 1 or not (that is by the way the 
opposite of what this post was about, on a different problem).

I find that suspect; think about it: from that moment on, the rest of 
the program will have to deal with a result that is of different type 
depending on the fact that there was only 1 value or not in the array? 
this is odd, and it is usually the contrary of what you want.
Anyhow, if you want to do such a thing, yes, test for array size and 
extract the value (with shift or [0], etc).  And at that point, you will 
happily have a scalar value or an array depending on the number of 
elements in the original array.

---
For clarity:
the original problem discussed in the thread was this: the splat 
operator does not do what it used to when there is only 1 element in the 
array. Robert Klemme has indicated above a solution to this (using the 
'comma' notation at the end of left values).  I posted a bug against 
Ruby 1.9.
This  problem posted by Benoit above has nothing to do with this.


-- 
Posted via http://www.ruby-forum.com/.

0
Raul
12/19/2009 9:41:41 PM
[Note:  parts of this message were removed to make it a legal post.]

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.

Ok, I'll just keep the ".length" code ... but I asked if there was a feature
on Array acting like a splat operator.

class Array
  def splat
    length == 1 ? shift : self
  end
end

(then in 1.8, I imagined to do: "*result" at the last line of the method.
irb(main):001:0> def m
irb(main):002:1> arr = [2]
irb(main):003:1> *arr
irb(main):004:1> end
SyntaxError: compile error
(irb):3: syntax error, unexpected '\n', expecting '='
    from (irb):4
irb(main):005:0> def m
irb(main):006:1> arr = [2]
irb(main):007:1> return *arr
irb(main):008:1> end
=> nil
irb(main):009:0> m
=> 2
For once, return is needed it seems ...)

2009/12/19 Raul Parolari <raulparolari@gmail.com>

> Benoit Daloze wrote:
> > Well, so what's the solution to get the single element in the array or
> > the
> > whole array when multiple elements ?
> ..
> > how to make this in a beautiful way?
> > I would like to have only the element if there is only one
> >
> > of course, there is:
> > arr = "str".scan(/.../)
> > arr.length == 1 ? arr[0] : arr
> >
> > but that create a useless new variable and doesn't look good at all.
> >
>
> Benoit, str.scan(pattern) always returns an array of matches; you then
> need to process the resulting array (for example, iterating on it,
> extracting the elements of the array). You seem to want a different
> result depending if the array size is 1 or not (that is by the way the
> opposite of what this post was about, on a different problem).
>
> I find that suspect; think about it: from that moment on, the rest of
> the program will have to deal with a result that is of different type
> depending on the fact that there was only 1 value or not in the array?
> this is odd, and it is usually the contrary of what you want.
> Anyhow, if you want to do such a thing, yes, test for array size and
> extract the value (with shift or [0], etc).  And at that point, you will
> happily have a scalar value or an array depending on the number of
> elements in the original array.
>
> ---
> For clarity:
> the original problem discussed in the thread was this: the splat
> operator does not do what it used to when there is only 1 element in the
> array. Robert Klemme has indicated above a solution to this (using the
> 'comma' notation at the end of left values).  I posted a bug against
> Ruby 1.9.
> This  problem posted by Benoit above has nothing to do with this.
>
>
> --
> Posted via http://www.ruby-forum.com/.
>
>

0
Benoit
12/19/2009 11:28:43 PM
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/
0
Robert
12/20/2009 12:21:04 PM
[Note:  parts of this message were removed to make it a legal post.]

2009/12/20 Robert Klemme <shortcutter@googlemail.com>

>
> 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/
>
> Thanks for your answer, I think in fact creating 2 methods is the best way.
And to keep it very simple I can do:

def vars
  ... # => Array
end
def var
  vars.shift
end

Regards,
  Benoit

0
eregontp (60)
12/20/2009 3:22:54 PM
2009/12/20 Benoit Daloze <eregontp@gmail.com>:

>> Thanks for your answer, I think in fact creating 2 methods is the best w=
ay.
> And to keep it very simple I can do:
>
> def vars
> =A0... # =3D> Array
> end
> def var
> =A0vars.shift
> end

That's a good approach.  By that you can still change the
implementation of #var if it proves to be too slow (e.g. if you are
often scanning large strings and the single match is at the
beginning).

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

0
Robert
12/21/2009 8:18:43 AM
Reply: