What am I missing about splat operator?

R

RichardOnRails

In trying to understand the splat operator, I visited:
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/

The first example that site offers is:
The split mode :
pet1, pet2, pet3 = *["duck","dog","cat"]

That resulted in pet1 == "duck", etc

But so did:
pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator
and#
pet1, pet2, pet3 = "duck","dog","cat" # no array-literal markers

So this first example makes no sense, does it? What am I missing?

Thanks in Advance,
Richard
 
R

Ryan Davis

In trying to understand the splat operator, I visited:
= http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/
=20
The first example that site offers is:
The split mode :
pet1, pet2, pet3 =3D *["duck","dog","cat"]
=20
That resulted in pet1 =3D=3D "duck", etc
=20
But so did:
pet1, pet2, pet3 =3D ["duck","dog","cat"] # no splat operator
and#
pet1, pet2, pet3 =3D "duck","dog","cat" # no array-literal markers
=20
So this first example makes no sense, does it? What am I missing?

The fact that you're splatting an array doesn't matter, just the fact =
that you're splatting.

# 1
pet1, pet2, pet3 =3D *["duck","dog","cat"]

# 2
pet1, pet2, pet3 =3D ["duck","dog","cat"] # no splat operator

# 3
pet1, pet2, pet3 =3D "duck","dog","cat" # no array-literal markers

# parses as:
#
# s:)block,
# # 1
# s:)masgn,
# s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
# s:)splat, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, =
"cat")))),
# # 2
# s:)masgn,
# s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
# s:)to_ary, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, =
"cat")))),
# # 3
# s:)masgn,
# s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
# s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, "cat"))))

# In all 3 cases, you're dealing with a multi-assign w/ an array on LHS.
#
# RHS:
# 1) splatted array
# 2) to_ary array (or any object, see below)
# 3) array (whether you use [] or not, it is still an array literal)

a, b, c =3D x
a, b, c =3D *x

# s:)block,
# # 1
# s:)masgn,
# s:)array, s:)lasgn, :a), s:)lasgn, :b), s:)lasgn, :c)),
# s:)to_ary, s:)call, nil, :x, s:)arglist)))),
# # 2
# s:)masgn,
# s:)array, s:)lasgn, :a), s:)lasgn, :b), s:)lasgn, :c)),
# s:)splat, s:)call, nil, :x, s:)arglist)))))
 
R

RichardOnRails

The first example that site offers is:
  The split mode :
  pet1, pet2, pet3 = *["duck","dog","cat"]
That resulted in pet1 == "duck", etc
But so did:
  pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator
and#
  pet1, pet2, pet3 = "duck","dog","cat" # no array-literal markers
So this first example makes no sense, does it?  What am I missing?

The fact that you're splatting an array doesn't matter, just the fact that you're splatting.

# 1
pet1, pet2, pet3 = *["duck","dog","cat"]

# 2
pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator

# 3
pet1, pet2, pet3 = "duck","dog","cat" # no array-literal markers

# parses as:
#
# s:)block,
#   # 1
#   s:)masgn,
#     s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
#     s:)splat, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, "cat")))),
#   # 2
#   s:)masgn,
#     s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
#     s:)to_ary, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, "cat")))),
#   # 3
#   s:)masgn,
#     s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
#     s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, "cat"))))

# In all 3 cases, you're dealing with a multi-assign w/ an array on LHS.
#
# RHS:
# 1) splatted array
# 2) to_ary array (or any object, see below)
# 3) array (whether you use [] or not, it is still an array literal)

a, b, c = x
a, b, c = *x

# s:)block,
#   # 1
#   s:)masgn,
#     s:)array, s:)lasgn, :a), s:)lasgn, :b), s:)lasgn, :c)),
#     s:)to_ary, s:)call, nil, :x, s:)arglist)))),
#   # 2
#   s:)masgn,
#     s:)array, s:)lasgn, :a), s:)lasgn, :b), s:)lasgn, :c)),
#     s:)splat, s:)call, nil, :x, s:)arglist)))))

Hi Ryan,

It looks to me the you gave me Lisp expressions one could use, in
part, to translate the three right-hand-sides I provided. I knew that
Ruby treats "x,y = 1,2" as equivalent to "x=1; y=2",
but I didn't know that Ruby first view them as "LHS-array assigned
values from a RHS-array" (which is how I interpret your expressions,
which look like Lisp to me).

Ultimately, then, the website's first lines show me that splat on
arrays is an Identity prefix operator, without mentioning that
explicitly. That's not very helpful, IMHO. Don't you agree?

Best wishes,
Richard
 
R

RichardOnRails

On Dec 28, 2010, at 18:50 , RichardOnRails wrote:
In trying to understand the splat operator, I visited:
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/
The first example that site offers is:
  The split mode :
  pet1, pet2, pet3 = *["duck","dog","cat"]
That resulted in pet1 == "duck", etc
But so did:
  pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator
and#
  pet1, pet2, pet3 = "duck","dog","cat" # no array-literal markers
So this first example makes no sense, does it?  What am I missing?
The fact that you're splatting an array doesn't matter, just the fact that you're splatting.
# 1
pet1, pet2, pet3 = *["duck","dog","cat"]
# 2
pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator
# 3
pet1, pet2, pet3 = "duck","dog","cat" # no array-literal markers
# parses as:
#
# s:)block,
#   # 1
#   s:)masgn,
#     s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
#     s:)splat, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, "cat")))),
#   # 2
#   s:)masgn,
#     s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
#     s:)to_ary, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str,"cat")))),
#   # 3
#   s:)masgn,
#     s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
#     s:)array, s:)str, "duck"), s:)str, "dog"), s:)str, "cat"))))
# In all 3 cases, you're dealing with a multi-assign w/ an array on LHS..
#
# RHS:
# 1) splatted array
# 2) to_ary array (or any object, see below)
# 3) array (whether you use [] or not, it is still an array literal)
a, b, c = x
a, b, c = *x
# s:)block,
#   # 1
#   s:)masgn,
#     s:)array, s:)lasgn, :a), s:)lasgn, :b), s:)lasgn, :c)),
#     s:)to_ary, s:)call, nil, :x, s:)arglist)))),
#   # 2
#   s:)masgn,
#     s:)array, s:)lasgn, :a), s:)lasgn, :b), s:)lasgn, :c)),
#     s:)splat, s:)call, nil, :x, s:)arglist)))))

Hi Ryan,

It looks to me the you gave me Lisp expressions one could use, in
part, to translate the three right-hand-sides I provided.  I knew that
Ruby treats "x,y = 1,2" as equivalent to "x=1; y=2",
but I didn't know that Ruby first view them as "LHS-array assigned
values from a RHS-array" (which is how I interpret your expressions,
which look like Lisp to me).

Ultimately, then, the website's first lines show me that splat on
arrays is an Identity prefix operator, without mentioning that
explicitly.  That's not very helpful, IMHO.  Don't you agree?

Best wishes,
Richard

A little more info ... this time, incorrect IMHO:

Splat array of arrays:
a = [[:planes, 21], [:cars, 36]]
h = Hash[*a] # => {[:planes, 21]=>[:cars, 36]}
Allegedly, h = Hash[*a] # => { :planes=>21, :cars=>36}
Do you concur in my finding that the site's in error here?

So, I hunt for a more informative (and more accurate) presentation of
the virtues of splat.

Again, Best Wishes,
Richard
 
R

Ryan Davis

It looks to me the you gave me Lisp expressions one could use, in
part, to translate the three right-hand-sides I provided.
Ultimately, then, the website's first lines show me that splat on
arrays is an Identity prefix operator, without mentioning that
explicitly. That's not very helpful, IMHO. Don't you agree?

I have no idea what you're saying here nor why you're capitalizing identity.
 
R

Ryan Davis

A little more info ... this time, incorrect IMHO:

Splat array of arrays:
a = [[:planes, 21], [:cars, 36]]
h = Hash[*a] # => {[:planes, 21]=>[:cars, 36]}
Allegedly, h = Hash[*a] # => { :planes=>21, :cars=>36}
Do you concur in my finding that the site's in error here?

So, I hunt for a more informative (and more accurate) presentation of
the virtues of splat.

http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/
^^^^^^^^^^

the comments correct the errors in the post.

Hash[a] works fine.
 
B

botp

In trying to understand the splat operator, I visited:
http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/

The first example that site offers is:
=A0 The split mode :
=A0 pet1, pet2, pet3 =3D *["duck","dog","cat"]

That resulted in pet1 =3D=3D "duck", etc

But so did:
=A0 pet1, pet2, pet3 =3D ["duck","dog","cat"] # no splat operator
and#
=A0 pet1, pet2, pet3 =3D "duck","dog","cat" # no array-literal markers

So this first example makes no sense, does it?

The splat operator is more explicit and versatile.

try the ff

x,*y,z=3D*[1,2,3,4,5], 100,200


also, some methods that do not accept array argument is just a splat away, =
eg

printf("%d %d %d",*[1,2,3])


best regards -botp
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

# 2
pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator

# # 2
# s:)masgn,
# s:)array, s:)lasgn, :pet1), s:)lasgn, :pet2), s:)lasgn, :pet3)),
# s:)to_ary, s:)array, s:)str, "duck"), s:)str, "dog"), s:)str,
"cat")))),
This implies to me that I should be able to define to_ary on an object, and
it will be able to be RHS of a mass assign.

a = Object.new

def a.to_ary
[1, 2]
end

b , c = a

b # => 1
c # => 2


Yes, it works. But I am confused where to_ary came from. I have never used
it myself, and wouldn't have even thought to use it except I saw it in the
sexp. Googling turns up http://www.ruby-forum.com/topic/81642, which isn't
helpful, and http://forums.pragprog.com/forums/54/topics/992 which left me
rather unconvinced, and only addresses the difference without really
addressing the reasoning.



Same for the Pickaxe which says on 366
to_ary: "This is used when interpreter needs a parameter to a method to be
an array, and when expanding parameters and assignments containing the *xyz
syntax"
to_a: "This is used when the interpreter needs to convert an object into an
array for parameter passing or multiple assignment."
So one's a po-tay-to, the other's a po-tah-to?



In The Ruby Programming Language, on page 80, it says they are defined for
the purposes of implicit conversions. I verified with this code

class Fixnum
alias to_str to_s
end
'1' + 1 # => "11"

But I don't understand why the implicit version should be different from the
explicit version, or why "#{obj}" doesn't invoke the implicit version. Is
there some example which shows the necessity of a separate, but but similar
method for to_a/to_ary, to_i/to_int, to_s/to_str, etc?
 
R

Ryan Davis

a =3D Object.new
=20
def a.to_ary
[1, 2]
end
=20
b , c =3D a
=20
b # =3D> 1
c # =3D> 2
=20
=20
Yes, it works. But I am confused where to_ary came from. I have never = used
it myself, and wouldn't have even thought to use it except I saw it in = the
sexp.

to_ary and to_str are implicit cast methods. to_a (deprecated for =
Array()) and to_s are (usually) explicit cast methods. to_ary/str are =
used internally when something is used in an array or string context and =
you're saying that the object is array-like or string-like. Most things =
aren't array-like tho, so you don't see the method much.=
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top