Unpacking an array with the star operator

B

Brian Schröder

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.
 
R

Robert Klemme

Brian Schröder said:
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
=> [# said:
=> # said:
=> nil
 
D

David A. Black

Hi --

Brian Schröder said:
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]

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 :)


David
 
F

Florian Gross

David said:
Brian Schröder said:
*[: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.
 
R

Robert Klemme

David A. Black said:
Hi --

Brian Schröder said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,432
Latest member
GTRNorbert

Latest Threads

Top