Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > What am I missing about splat operator?

Reply
Thread Tools

What am I missing about splat operator?

 
 
RichardOnRails
Guest
Posts: n/a
 
      12-29-2010
In trying to understand the splat operator, I visited:
http://theplana.wordpress.com/2007/0...plat-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
 
Reply With Quote
 
 
 
 
Ryan Davis
Guest
Posts: n/a
 
      12-29-2010

On Dec 28, 2010, at 18:50 , RichardOnRails wrote:

> In trying to understand the splat operator, I visited:
> =

http://theplana.wordpress.com/2007/0...plat-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, et1), s(:lasgn, et2), s(:lasgn, et3)),
# s(:splat, s(:array, s(:str, "duck"), s(:str, "dog"), s(:str, =
"cat")))),
# # 2
# s(:masgn,
# s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
# s(:to_ary, s(:array, s(:str, "duck"), s(:str, "dog"), s(:str, =
"cat")))),
# # 3
# s(:masgn,
# s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
# 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, , s(:arglist)))),
# # 2
# s(:masgn,
# s(:array, s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c)),
# s(:splat, s(:call, nil, , s(:arglist)))))



 
Reply With Quote
 
 
 
 
RichardOnRails
Guest
Posts: n/a
 
      12-29-2010
On Dec 28, 10:12*pm, Ryan Davis <(E-Mail Removed)> wrote:
> On Dec 28, 2010, at 18:50 , RichardOnRails wrote:
>
> > In trying to understand the splat operator, I visited:
> >http://theplana.wordpress.com/2007/0...plat-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, et1), s(:lasgn, et2), s(:lasgn, et3)),
> # * * s(:splat, s(:array, s(:str, "duck"), s(:str, "dog"), s(:str, "cat")))),
> # * # 2
> # * s(:masgn,
> # * * s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
> # * * s(:to_ary, s(:array, s(:str, "duck"), s(:str, "dog"), s(:str, "cat")))),
> # * # 3
> # * s(:masgn,
> # * * s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
> # * * 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, , s(:arglist)))),
> # * # 2
> # * s(:masgn,
> # * * s(:array, s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c)),
> # * * s(:splat, s(:call, nil, , 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
 
Reply With Quote
 
RichardOnRails
Guest
Posts: n/a
 
      12-29-2010
On Dec 28, 10:54*pm, RichardOnRails
<(E-Mail Removed)> wrote:
> On Dec 28, 10:12*pm, Ryan Davis <(E-Mail Removed)> wrote:
>
>
>
> > On Dec 28, 2010, at 18:50 , RichardOnRails wrote:

>
> > > In trying to understand the splat operator, I visited:
> > >http://theplana.wordpress.com/2007/0...plat-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, et1), s(:lasgn, et2), s(:lasgn, et3)),
> > # * * s(:splat, s(:array, s(:str, "duck"), s(:str, "dog"), s(:str, "cat")))),
> > # * # 2
> > # * s(:masgn,
> > # * * s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
> > # * * s(:to_ary, s(:array, s(:str, "duck"), s(:str, "dog"), s(:str,"cat")))),
> > # * # 3
> > # * s(:masgn,
> > # * * s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
> > # * * 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, , s(:arglist)))),
> > # * # 2
> > # * s(:masgn,
> > # * * s(:array, s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c)),
> > # * * s(:splat, s(:call, nil, , 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 = [[lanes, 21], [:cars, 36]]
h = Hash[*a] # => {[lanes, 21]=>[:cars, 36]}
Allegedly, h = Hash[*a] # => { lanes=>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
 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      12-29-2010

On Dec 28, 2010, at 19:55 , RichardOnRails wrote:

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


 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      12-29-2010

On Dec 28, 2010, at 20:35 , RichardOnRails wrote:

> A little more info ... this time, incorrect IMHO:
>
> Splat array of arrays:
> a = [[lanes, 21], [:cars, 36]]
> h = Hash[*a] # => {[lanes, 21]=>[:cars, 36]}
> Allegedly, h = Hash[*a] # => { lanes=>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/0...plat-operator/
^^^^^^^^^^

the comments correct the errors in the post.

Hash[a] works fine.


 
Reply With Quote
 
botp
Guest
Posts: n/a
 
      12-29-2010
On Wed, Dec 29, 2010 at 10:50 AM, RichardOnRails
<(E-Mail Removed)> wrote:
> In trying to understand the splat operator, I visited:
> http://theplana.wordpress.com/2007/0...plat-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

 
Reply With Quote
 
Josh Cheek
Guest
Posts: n/a
 
      12-29-2010
[Note: parts of this message were removed to make it a legal post.]

On Tue, Dec 28, 2010 at 9:12 PM, Ryan Davis <(E-Mail Removed)>wrote:

>
> # 2
> pet1, pet2, pet3 = ["duck","dog","cat"] # no splat operator
>
> # # 2
> # s(:masgn,
> # s(:array, s(:lasgn, et1), s(:lasgn, et2), s(:lasgn, et3)),
> # 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?

 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      12-30-2010

On Dec 29, 2010, at 05:21 , Josh Cheek wrote:

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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ruby 1.9 splat in return statement, bug or feature? Gary Wright Ruby 3 06-03-2009 06:30 AM
'**' as hash splat? Trans Ruby 12 10-26-2006 03:49 PM
redefining splat? Adam Shelly Ruby 10 10-03-2006 03:51 PM
Splat, #to_ary and #to_a Eero Saynatkari Ruby 18 09-20-2006 05:22 PM
Doing a splat within a C extension Daniel Berger Ruby 3 11-03-2005 01:33 PM



Advertisments