What am I missing about splat operator?

Discussion in 'Ruby' started by RichardOnRails, Dec 29, 2010.

  1. 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
    RichardOnRails, Dec 29, 2010
    #1
    1. Advertising

  2. RichardOnRails

    Ryan Davis Guest

    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/
    >=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)))))
    Ryan Davis, Dec 29, 2010
    #2
    1. Advertising

  3. On Dec 28, 10:12 pm, Ryan Davis <> wrote:
    > 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
    RichardOnRails, Dec 29, 2010
    #3
  4. On Dec 28, 10:54 pm, RichardOnRails
    <> wrote:
    > On Dec 28, 10:12 pm, Ryan Davis <> wrote:
    >
    >
    >
    > > 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
    RichardOnRails, Dec 29, 2010
    #4
  5. RichardOnRails

    Ryan Davis Guest

    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.
    Ryan Davis, Dec 29, 2010
    #5
  6. RichardOnRails

    Ryan Davis Guest

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

    > 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.
    Ryan Davis, Dec 29, 2010
    #6
  7. RichardOnRails

    botp Guest

    On Wed, Dec 29, 2010 at 10:50 AM, 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:
    > =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
    botp, Dec 29, 2010
    #7
  8. RichardOnRails

    Josh Cheek Guest

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

    On Tue, Dec 28, 2010 at 9:12 PM, Ryan Davis <>wrote:

    >
    > # 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?
    Josh Cheek, Dec 29, 2010
    #8
  9. RichardOnRails

    Ryan Davis Guest

    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.=
    Ryan Davis, Dec 30, 2010
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Daniel Berger

    Doing a splat within a C extension

    Daniel Berger, Nov 3, 2005, in forum: Ruby
    Replies:
    3
    Views:
    121
  2. Eero Saynatkari

    Splat, #to_ary and #to_a

    Eero Saynatkari, Sep 18, 2006, in forum: Ruby
    Replies:
    18
    Views:
    230
    Rick DeNatale
    Sep 20, 2006
  3. Adam Shelly

    redefining splat?

    Adam Shelly, Oct 2, 2006, in forum: Ruby
    Replies:
    10
    Views:
    343
    Martin Coxall
    Oct 3, 2006
  4. Pedro Del Gallego

    splat operator Question.

    Pedro Del Gallego, May 20, 2007, in forum: Ruby
    Replies:
    1
    Views:
    108
    Pedro Del Gallego
    May 20, 2007
  5. Gunther Diemant

    Splat operator gives an SystemStackError

    Gunther Diemant, Mar 4, 2011, in forum: Ruby
    Replies:
    2
    Views:
    104
    Gunther Diemant
    Mar 4, 2011
Loading...

Share This Page