Redefining splat?

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

On 10/2/06, Adam S. [email protected] wrote:

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?

You can define to_ary which splat uses. In Ruby 1.9 you can define
to_splat
directly.

jeremy

Jeremy K. wrote:

You can define to_ary which splat uses. In Ruby 1.9 you can define
to_splat
You mean #to_a?

On 10/2/06, Jeremy K. [email protected] wrote:

You can define to_ary which splat uses. In Ruby 1.9 you can define to_splat
directly.

perfect, thanks.

On 10/2/06, Florian F. [email protected] wrote:

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

On 10/2/06, MonkeeSage [email protected] wrote:

Looks for #to_ary first, failing that uses #to_a:
p *C.new

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

Brian.

Brian M. wrote:

On 10/2/06, Florian F. [email protected] wrote:

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

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

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.

Brian M. wrote:

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

Just trying to emphasize your point. :slight_smile:

Regards,
Jordan

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

On 10/3/06, Adam S. [email protected] 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
= 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
¢ change binary interleave
~ sqiggle binary select
_ flat worm

¯                overline                          indicates

“times 1000”
+ intersection separates list
items
/ slat

\                backslat

@                whirlpool                         unary BUT
¬                hookworm

^                shark (or simply sharkfin)        unary XOR 

(additive)

Martin