2009-07-10 10 views
12

mam ten kod:metoda o takiej samej nazwie i różnych parametrów w Ruby

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

vel jest klasa Command2D że ma 3 cechy, jest porównywalny i definiuje +, w zasadzie to wygodne klasa dla mnie do zarządzania tymi 3 atrybuty, więc chcę używać go wewnętrznie w mojej bibliotece (nie chcę, aby były prywatne, albo nadaj im dziwne nazwy). Ale wydaje się, że Ruby zachowuje tylko ostatnią wartość setVelocity, nawet jeśli liczba parametrów jest inna. więc gdy zadzwonię setVelocity z 3 parametrami, powiem, że muszę wywołać tę metodę tylko z jednym parametrem.

Odpowiedz

29

Ruby tak naprawdę nie obsługuje przeciążania.

This page podaje więcej szczegółów i obejście. Zasadniczo tworzysz jedną metodę ze zmienną liczbą parametrów i odpowiednio sobie z nimi radzisz.

(ja osobiście polecam pisanie jedną metodę rozpoznawania dwóch różnych „sfałszowane przeciążenia”, a następnie jedną metodę dla każdego przeciążeniem, o różnych nazwach odzwierciedlających różne parametry.)

Alternatywnie, po prostu dostarczyć różnych nazw zacznij od :)

+0

Zaprawdę, nie jest to temat nie są obecne w sensei Skeet - jak to jest nie mieć „ogólnym” odznakę ? W chwili pisania pisałeś w 2140 różnych tagach, a 50 pierwszych tagów ma co najmniej 30 postów. Sprawia, że ​​zastanawiam się, co to naprawdę wymaga bycia "generałem" – Matt

+0

Tak, generalista nie został jeszcze zaimplementowany - Jeff sugeruje Meta, że ​​nie zamierza zrobić tego bezpośrednio, ale coś podobnego. –

0

Użyj atrybutu attr_accessor, aby uzyskać atrybuty, a otrzymasz automatycznie polecenia pobierające i ustawiające. Alternatywnie można użyć atrybutu attr_reader lub attr_writer, aby uzyskać atrybuty tylko do odczytu lub tylko do zapisu.

class Foo 
    attr_accessor :velocity 
end 

Możesz teraz ustawić i uzyskać wartość tego atrybutu jak poniżej:

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

Jeśli chcesz dodać metody do ustawiania atrybutu na podstawie pewnych parametrów, należy użyć nazwy odzwierciedlające jakiego rodzaju oczekuje się, że wkład:

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

prawdopodobnie można znaleźć znacznie lepszą nazwę w tym przypadku, ale nie wiem, co się x, y i zbaczają naprawdę znaczą w twoim kontekście.

2

Dla porównania, oto jak bym go rozwiązać.

#!/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 
Powiązane problemy