redefining splat?

Discussion in 'Ruby' started by Adam Shelly, Oct 2, 2006.

  1. Adam Shelly

    Adam Shelly Guest

    Can you redefine the * prefix operator?
    I'm in the middle of refactoring some code. I have a function that
    looks like this

    def send_command cmd_arry
    type = cmd_arry.shift
    @comms.send(type, *cmd_arry)
    end

    I want to replace the command arrays (which have the form [:COMMAND,
    data1, data2, ...]) with a class structure like:

    class LogonCommand < Command
    def initialize name, pass
    super()
    @name,@pass = name,pass
    @command = :LOGON
    end
    def write
    [@command, @name, @pass]
    end
    end

    but there are a lot of these command types, and I wanted to do a
    gradual transition. So I thought I could make the Command class mimic
    the array:

    class Command
    def shift
    @command
    end
    def *
    *(write[1..-1])
    end
    end

    but that gives a syntax error. Is there any way to redefine the splat
    for my class? Or at least to make my class act like an array when the
    splat is applied?

    -Adam
    Adam Shelly, Oct 2, 2006
    #1
    1. Advertising

  2. Jeremy Kemper wrote:
    > You can define to_ary which splat uses. In Ruby 1.9 you can define
    > to_splat

    You mean #to_a?

    --
    Florian Frank
    Florian Frank, Oct 2, 2006
    #2
    1. Advertising

  3. Adam Shelly

    Adam Shelly Guest

    On 10/2/06, Jeremy Kemper <> wrote:
    > You can define to_ary which splat uses. In Ruby 1.9 you can define to_splat
    > directly.
    >


    perfect, thanks.
    Adam Shelly, Oct 2, 2006
    #3
  4. On 10/2/06, Florian Frank <> wrote:
    > Jeremy Kemper wrote:
    > > You can define to_ary which splat uses. In Ruby 1.9 you can define
    > > to_splat

    > You mean #to_a?


    class C
    def to_a
    [:to_a]
    end
    end

    a = *C.new

    class C
    def to_ary
    [:to_ary]
    end
    end

    b = *C.new

    puts a, b

    Brian.
    Brian Mitchell, Oct 2, 2006
    #4
  5. Adam Shelly

    MonkeeSage Guest

    Brian Mitchell wrote:
    > class C
    > def to_a
    > [:to_a]
    > end
    > end
    >
    > a = *C.new
    > ...


    Looks for #to_ary first, failing that uses #to_a:

    class C
    def to_a
    [:to_a]
    end
    def to_ary
    [:to_ary]
    end
    end

    p *C.new

    Regards,
    Jordan
    MonkeeSage, Oct 2, 2006
    #5
  6. On 10/2/06, MonkeeSage <> wrote:
    > Brian Mitchell wrote:
    > > class C
    > > def to_a
    > > [:to_a]
    > > end
    > > end
    > >
    > > a = *C.new
    > > ...

    >
    > Looks for #to_ary first, failing that uses #to_a:
    >
    > class C
    > def to_a
    > [:to_a]
    > end
    > def to_ary
    > [:to_ary]
    > end
    > end
    >
    > p *C.new
    >


    As was my point ;-). There was a reason I reopened the class.

    Brian.
    Brian Mitchell, Oct 2, 2006
    #6
  7. Brian Mitchell wrote:
    > On 10/2/06, Florian Frank <> wrote:
    >> Jeremy Kemper wrote:
    >> > You can define to_ary which splat uses. In Ruby 1.9 you can define
    >> > to_splat

    >> You mean #to_a?

    >

    Well, #to_ary expresses a bit more than just splatability (is this even
    a word?). It means that the Object is in some way actually an Array, not
    only that it can be converted into an array if needed. A good example
    for this is Pathname#to_str.

    So, you don't have to use the splat operator at all, if you want to
    print a class that implements #to_ary, e. g.:

    >> class A;def to_ary;[:foo,:bar];end;end

    # => nil
    >> puts A.new

    foo
    bar

    This is different from:

    >> class B;def to_a;[:foo,:bar];end;end

    # => nil
    >> puts *B.new

    foo
    bar
    >> puts B.new

    #<B:0xb7a8d114>

    --
    Florian Frank
    Florian Frank, Oct 2, 2006
    #7
  8. Adam Shelly

    MonkeeSage Guest

    Brian Mitchell wrote:
    > As was my point ;-). There was a reason I reopened the class.


    Just trying to emphasize your point. :)

    Regards,
    Jordan
    MonkeeSage, Oct 2, 2006
    #8
  9. Adam Shelly

    Matt Todd Guest

    > Can you redefine the * prefix operator?

    Why do you need to? I know slight modifications to do some cool
    wizardry can be adventageous, but to me, what it seems like you want
    is a completely different thing that will completely redefine the *.
    (Even if only locally.)

    > I'm in the middle of refactoring some code. I have a function that
    > looks like this
    >
    > def send_command cmd_arry
    > type = cmd_arry.shift
    > @comms.send(type, *cmd_arry)
    > end


    What's wrong with...

    def send_command cmd_ary
    cmd = Command.new(cmd_ary)
    @comms.send(cmd.type, cmd.params)
    end

    Or even...

    def send_command cmd_ary
    cmd = Command.new(cmd_ary)
    @comms.send cmd
    end

    with #send overwritten to do something special with the Command class?
    (Still retaining the original functionality otherwise.)

    Just my opinion.

    M.T.
    Matt Todd, Oct 3, 2006
    #9
  10. I would agree with Matt, if you are trying to redefine the splat
    operator (is that really what we're calling it? neat), with the .to_a
    or .to_ary to return a class instead of an array, you should make sure
    that the class looks enough like an array that it wouldn't break
    someone's expectations later.

    It might not make a big difference now, but should someone need to
    touch your code later, even if that person is yourself, you will save
    many headaches by not being overly trixy.
    .adam



    Matt Todd wrote:
    > > Can you redefine the * prefix operator?

    >
    > Why do you need to? I know slight modifications to do some cool
    > wizardry can be adventageous, but to me, what it seems like you want
    > is a completely different thing that will completely redefine the *.
    > (Even if only locally.)
    >
    > > I'm in the middle of refactoring some code. I have a function that
    > > looks like this
    > >
    > > def send_command cmd_arry
    > > type = cmd_arry.shift
    > > @comms.send(type, *cmd_arry)
    > > end

    >
    > What's wrong with...
    >
    > def send_command cmd_ary
    > cmd = Command.new(cmd_ary)
    > @comms.send(cmd.type, cmd.params)
    > end
    >
    > Or even...
    >
    > def send_command cmd_ary
    > cmd = Command.new(cmd_ary)
    > @comms.send cmd
    > end
    >
    > with #send overwritten to do something special with the Command class?
    > (Still retaining the original functionality otherwise.)
    >
    > Just my opinion.
    >
    > M.T.
    Adam Sanderson, Oct 3, 2006
    #10
  11. On 10/3/06, Adam Sanderson <> wrote:
    > I would agree with Matt, if you are trying to redefine the splat
    > operator (is that really what we're calling it? neat)


    Pshaw. Somebody who's never read the INTERCAL reference manual?

    http://www.muppetlabs.com/~breadbox/intercal-man/tonsila.html

    Character Name Use (if any)
    . spot identify 16-bit
    variable
    : two-spot identify 32-bit
    variable
    , tail identify 16-bit
    array
    ; hybrid identify 32-bit
    array
    # mesh identify constant
    =3D half-mesh

    ' spark grouper
    ` backspark

    ! wow equivalent to
    spark-spot
    ? what unary XOR
    " rabbit-ears grouper
    rabbit equivalent to ears-spot
    | spike

    % double-oh-seven percentage qualifier
    - worm used with angles
    < angle used with worms
    > right angle


    ( wax precedes line label
    ) wane follows line label
    [ U turn

    ] U turn back

    { embrace

    } bracelet

    * splat flags invalid
    statements (I72)
    & ampersand * unary AND
    V V (or book) unary OR
    bookworm unary XOR (I72)
    $ big money binary interleave
    =A2 change binary interleave
    ~ sqiggle binary select
    _ flat worm

    =AF overline indicates
    "times 1000"
    + intersection separates list items
    / slat

    \ backslat

    @ whirlpool unary BUT
    =AC hookworm

    ^ shark (or simply sharkfin) unary XOR (additive)

    Martin
    Martin Coxall, Oct 3, 2006
    #11
    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:
    120
  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. Trans

    '**' as hash splat?

    Trans, Oct 24, 2006, in forum: Ruby
    Replies:
    12
    Views:
    186
    Kalman Noel
    Oct 26, 2006
  4. Gary Wright
    Replies:
    3
    Views:
    105
    Macario Ortega
    Jun 3, 2009
  5. Pedro Del Gallego

    splat operator Question.

    Pedro Del Gallego, May 20, 2007, in forum: Ruby
    Replies:
    1
    Views:
    105
    Pedro Del Gallego
    May 20, 2007
Loading...

Share This Page