2012-02-28 14 views
9

Mam wiele funkcji, które przyjmują tablicę obiektów lub pojedynczy obiekt przeznaczony do traktowania jako tablica zawierająca jeden obiekt i szukam czystszy sposób, aby to osiągnąć. Zasadniczo, chcę wiedzieć, w jaki sposób mogę dokonać unless udział w następujących funkcji bardziej zwięzły:Akceptowanie parametru jako pojedynczego obiektu lub jako tablicy obiektów

def foo(bar_or_bars) 
    unless bar_or_bars.is_a?(Array) 
    bar_or_bars = [bar_or_bars] 
    end 
    bar_or_bars.each { |baz| ... } 
end 

Każda pomoc będzie mile widziana! Dzięki.

Odpowiedz

11

Pierwsza rzeczą, jaką można zrobić, to napisać logikę unless w jednym wierszu:

bars = bar_or_bars.is_a?(Array) ? bar_or_bars : [bar_or_bars] 

Jak widzisz, daję mu nową nazwę tutaj, jak to już nie bar lub barów, to teraz zdecydowanie kolekcja.

Problem z tym i twoim oryginalnym podejściem polega na tym, że chociaż twoja funkcja może działać na jakimkolwiek Enumerable, zmusisz swoich użytkowników do podania argumentu konkretnego typu, który łamie pisanie na maszynie.

Zgrabny trick częściowo rozwiązać ten problem jest następujący:

def foo(bar_or_bars) 
    bars = [*bar_or_bars] 
    bars.each { |baz| ... } 
end 

nie będę dokładnie nazwać czytelny, choć. To naprawdę pachnie jak zły interfejs API. Prawdopodobnie trzeba lepiej wziąć wiele argumentów tak:

def foo(*bars) 
    bars.each { |baz| ... } 
end 

I niech rozmówca zdecydować, czy chce przekazać pojedynczy obiekt lub tablicę:

foo("XYZ") 
ary = ["abc", "def"] 
foo(*ary) 
+0

Dzięki, że drugi Sztuką było to, czego szukałem. Wiem, że to nie jest idealne, ale tak naprawdę upraszczałem: ponieważ mam wiele kolejnych parametrów, które zachowują się tak, jak to opisałem, nie mogłem użyć zwykłej starej ikony na liście parametrów. – user2398029

18

Najczystsze rozwiązanie znalazłem się przy użyciu metoda jądro Array:

Array(5) #=> [5] 
Array([1, 2, 3]) #=> [1,2,3] 

tak

def foo(bar_or_bars) 
    bars = Array(bar_or_bars) 
    bars.each { |baz| ... } 

To będzie pracować nawet na zagnieżdżonych tablic, które mają tablice jako elementy (przyzwyczajenie być spłaszczona)

1

Obecnie używam to:

bars = [bar_or_bars].flatten 
Powiązane problemy