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