[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Unpacking an array with the star operator

Brian Schröder

11/30/2004 4:40:00 PM

Hello Group,

I just noticed the following behaviour:

$ irb --prompt-mode xmp
*[:x]
SyntaxError: compile error
(irb):1: syntax error
from (irb):1
a=*[:x]
==>:x

and wondered why it is the case. I always understood the * operator as pack/unpack array operator. So I would have expected the following behaviour.

*[:x] => :x

What is the reason for * being implemented as it is?

After reading this again I see, that it may be the problem with

*[:x, :y] => ???

So in fact maybe I should not wonder. So let me rephrase it into "what exactly does the * return", because I thought "every ruby expressions retruns something" and a = *[:x] are two expressions.

And is the * a private kernel method or where is it defined?

Regards,

Brian

PS: Sorry if this is a dumb question.

--
Brian Schröder
http://www.brian-sch...



5 Answers

Robert Klemme

11/30/2004 4:52:00 PM

0


"Brian Schröder" <ruby@brian-schroeder.de> schrieb im Newsbeitrag
news:20041130174018.40e55108@black.wg...
> Hello Group,
>
> I just noticed the following behaviour:
>
> $ irb --prompt-mode xmp
> *[:x]
> SyntaxError: compile error
> (irb):1: syntax error
> from (irb):1
> a=*[:x]
> ==>:x
>
> and wondered why it is the case. I always understood the * operator as
pack/unpack array operator. So I would have expected the following
behaviour.
>
> *[:x] => :x

No, it does not pack / unpack an array. You can only use it in a
situation where there is an assignment. The star indicates, that a given
value should be enumerated and assigned to lvalues in order (this applies
also to method argument lists).

> What is the reason for * being implemented as it is?
>
> After reading this again I see, that it may be the problem with
>
> *[:x, :y] => ???

No, it doesn't matter how many elements you put into the array.

> So in fact maybe I should not wonder. So let me rephrase it into "what
exactly does the * return", because I thought "every ruby expressions
retruns something" and a = *[:x] are two expressions.

It's not exactly an expression that returns something. It's more like a
compiler directive - if you look for an analogy.

> And is the * a private kernel method or where is it defined?

I'd guess that it's implemented somewhere in the Ruby interpreter - not in
any particular class or module - as it is *not* an operator in the usual
meaning of the word.

> PS: Sorry if this is a dumb question.

I don't think it's a dumb question.

Kind regards

robert


PS: Some examples:

17:46:05 [robert.klemme]: irbs
>> class Foo
>> include Enumerable
>> def each() yield "foo" end
>> end
=> nil
>> Foo.new.to_a
=> ["foo"]
>> a,b=*Foo.new
=> ["foo"]
>> a
=> "foo"
>> b
=> nil
>> a,b=Foo.new
=> [#<Foo:0x1017a958>]
>> a
=> #<Foo:0x1017a958>
>> b
=> nil

dblack

11/30/2004 6:32:00 PM

0

Florian Gross

11/30/2004 6:54:00 PM

0

David A. Black wrote:

> On Wed, 1 Dec 2004, Robert Klemme wrote:
>>"Brian Schröder" <ruby@brian-schroeder.de> schrieb
>>>*[:x] => :x
>>No, it does not pack / unpack an array. You can only use it in a
>>situation where there is an assignment. The star indicates, that a given
>>value should be enumerated and assigned to lvalues in order (this applies
>>also to method argument lists).
>
> It doesn't have to be an assignment; you can do:
>
> irb(main):003:0> [1,2,*[3,4]]
> => [1, 2, 3, 4]

I think this is just another case of a hidden method call. I like to
think of [1, 2, 3] as Array[1, 2, 3] which is Array.[](1, 2, 3)

So maybe that sample could be thought of as Array.[](1, 2, *Array.[](3,
4)) -- isn't Ruby an oddly lovable language? :)

> or:
>
> irb(main):004:0> arr = [1,2,3,4]
> => [1, 2, 3, 4]
> irb(main):005:0> Hash[*arr]
> => {1=>2, 3=>4}
>
> I like to think of it as the unarr?ay (unary/unarray) operator :-)

Same here, equivalent to Hash.[](1, 2, 3, 4). So I guess the theory of
the original poster (* interpolates an Array into an assignment list)
still holds true.

Brian Schröder

11/30/2004 9:46:00 PM

0

Thanks for the answers. I again learned something new. I didn't knew that each enumerable could be "unstarred".

Regards,

Brian

On Wed, 1 Dec 2004 01:52:48 +0900
"Robert Klemme" <bob.news@gmx.net> wrote:

> 17:46:05 [robert.klemme]: irbs
> >> class Foo
> >> include Enumerable
> >> def each() yield "foo" end
> >> end
> => nil
> >> Foo.new.to_a
> => ["foo"]
> >> a,b=*Foo.new
> => ["foo"]
> >> a
> => "foo"
> >> b
> => nil
> >> a,b=Foo.new
> => [#<Foo:0x1017a958>]
> >> a
> => #<Foo:0x1017a958>
> >> b
> => nil

--
Brian Schröder
http://www.brian-sch...



Robert Klemme

12/1/2004 8:24:00 AM

0


"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.44.0411301028320.4191-100000@wobblini...
> Hi --
>
> On Wed, 1 Dec 2004, Robert Klemme wrote:
>
> >
> > "Brian Schröder" <ruby@brian-schroeder.de> schrieb im Newsbeitrag
> > news:20041130174018.40e55108@black.wg...
> > > Hello Group,
> > >
> > > I just noticed the following behaviour:
> > >
> > > $ irb --prompt-mode xmp
> > > *[:x]
> > > SyntaxError: compile error
> > > (irb):1: syntax error
> > > from (irb):1
> > > a=*[:x]
> > > ==>:x
> > >
> > > and wondered why it is the case. I always understood the * operator
as
> > pack/unpack array operator. So I would have expected the following
> > behaviour.
> > >
> > > *[:x] => :x
> >
> > No, it does not pack / unpack an array. You can only use it in a
> > situation where there is an assignment. The star indicates, that a
given
> > value should be enumerated and assigned to lvalues in order (this
applies
> > also to method argument lists).
>
> It doesn't have to be an assignment; you can do:
>
> irb(main):003:0> [1,2,*[3,4]]
> => [1, 2, 3, 4]

Thanks David! I didn't think of this case. I wonder whether this can be
viewed as an anonymous assignment.

> or:
>
> irb(main):004:0> arr = [1,2,3,4]
> => [1, 2, 3, 4]
> irb(main):005:0> Hash[*arr]
> => {1=>2, 3=>4}

That's a method argument list.

> I like to think of it as the unarr?ay (unary/unarray) operator :-)

IMHO it's not an operator, as it has mainly compile time effects, i.e., it
controls which values are assigned to which variables (in an assignment).

Note also, that the star can appear on the left side of an assignment, too
(or in the argument list of a method definition, which is basically the
same):

>> a,b,c = %w{aaa bbb ccc ddd}
=> ["aaa", "bbb", "ccc", "ddd"]
>> a
=> "aaa"
>> b
=> "bbb"
>> c
=> "ccc"
>> a,b,*c = %w{aaa bbb ccc ddd}
=> ["aaa", "bbb", "ccc", "ddd"]
>> a
=> "aaa"
>> b
=> "bbb"
>> c
=> ["ccc", "ddd"]

Kind regards

robert