2009-07-10 25 views
12

ho questo codice:metodo con lo stesso nome e parametri diversi in Ruby

def setVelocity (x, y, yaw) 
    setVelocity (Command2d.new(x,y,yaw)) 
end 
def setVelocity (vel) 
...... 
end 

vel è una classe Command2D che ha 3 attributi, è paragonabile e definisce +, in fondo è una classe conveniente per me per gestire tali 3 attributi, quindi voglio usarlo internamente nella mia libreria (non voglio renderli privati, o dare loro nomi strani). Ma Ruby sembra mantenere solo l'ultima setVelocity anche quando il numero di parametri è diverso. quindi quando chiamo setVelocity con 3 parametri dirò che devo chiamare quel metodo con un solo parametro.

risposta

29

Ruby in realtà non supporta il sovraccarico.

This page fornisce ulteriori dettagli e una soluzione alternativa. Fondamentalmente si crea un singolo metodo con un numero variabile di parametri e si gestiscono appropriatamente.

(mi consiglia personalmente scrivendo un metodo per riconoscere i due "falsi overload" diverso e quindi un metodo per ogni sovraccarico, con nomi diversi che riflettono i diversi parametri.)

In alternativa, si limita a fornire nomi diversi a inizia con :)

+0

In verità, non c'è un argomento che non sono presenti sensei Skeet - come è non si dispone di un badge "generalista" ? Al momento della scrittura, hai pubblicato 2140 tag diversi e i primi 50 tag hanno almeno 30 post. Mi chiedo cosa ci vuole per essere un "generalista" – Matt

+0

Sì, il generalista non è ancora stato implementato - Jeff ha insinuato su Meta che non lo farà direttamente, ma qualcosa di simile. –

0

Usa attr_accessor per aggiungere attributi e otterrai automaticamente getter e setter. In alternativa utilizzare attr_reader o attr_writer per ottenere attributi di sola lettura o solo scrittura.

class Foo 
    attr_accessor :velocity 
end 

È ora possibile impostare e ottenere il valore di questo attributo come questo:

foo = Foo.new 
foo.velocity = 100 
puts foo.velocity # => 100 

Se si desidera aggiungere i metodi per impostare l'attributo sulla base di alcuni parametri, utilizzare un nome che riflette il tipo di ingresso sono attesi:

def velocity_from_yaw(x, y, yaw) 
    velocity = Command2d.new(x, y, yaw) 
end 

si può probabilmente trovare un nome molto meglio in questo caso, ma non so che cosa il vostro x, y e imbardata significa veramente nel tuo contesto.

2

Proprio per il confronto, ecco come avrei risolverlo:.

#!/usr/bin/env ruby 

class Command2D 
    def initialize(x, y, yaw) 
    @command = [x, y, yaw] 
    end 
end 

class Vehicle 
    def velocity=(command_or_array) 
    case command_or_array 
    when Command2D 
     self.velocity_from_command = command_or_array 
    when Array 
     self.velocity_from_array = command_or_array 
    else 
     raise TypeError, 'Velocity can only be a Command2D or an Array of [x, y, yaw]' 
    end 
    end 

    private 

    def velocity_from_command=(command) 
    @velocity = command 
    end 

    def velocity_from_array=(ary) 
    raise TypeError, 'Velocity must be an Array of [x, y, yaw]' unless ary.length == 3 
    @velocity = Command2D.new(*ary) 
    end 
end 

v1 = Vehicle.new 
v1.velocity = Command2D.new(1, 2, 3) 

v2 = Vehicle.new 
v2.velocity = [1, 2, 3] 

p v1 
p v2 
Problemi correlati