[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

redefining splat?

Adam Shelly

10/2/2006 6:40:00 PM

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

10 Answers

Florian Frank

10/2/2006 6:46:00 PM

0

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


Adam Shelly

10/2/2006 6:55:00 PM

0

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

perfect, thanks.

Brian Mitchell

10/2/2006 7:00:00 PM

0

On 10/2/06, Florian Frank <flori@nixe.ping.de> 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.

MonkeeSage

10/2/2006 8:18:00 PM

0

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

Brian Mitchell

10/2/2006 8:37:00 PM

0

On 10/2/06, MonkeeSage <MonkeeSage@gmail.com> 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.

Florian Frank

10/2/2006 8:43:00 PM

0

Brian Mitchell wrote:
> On 10/2/06, Florian Frank <flori@nixe.ping.de> 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


MonkeeSage

10/2/2006 8:49:00 PM

0

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

Just trying to emphasize your point. :)

Regards,
Jordan

Matt Todd

10/3/2006 3:33:00 AM

0

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

netghost

10/3/2006 3:44:00 PM

0

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.

Martin Coxall

10/3/2006 3:52:00 PM

0

On 10/3/06, Adam Sanderson <netghost@gmail.com> 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/to...

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