redefining splat?

A

Adam Shelly

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
 
M

MonkeeSage

Brian said:
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
 
B

Brian Mitchell

Brian said:
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.
 
F

Florian Frank

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

Matt Todd

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

Adam Sanderson

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
 
M

Martin Coxall

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
 

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,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top