2015-01-18 17 views
5

Mam metoda zdefiniowana tak:Czy można wywołać tę metodę Ruby bez ** {} na końcu?

def woot(a = nil, b: nil) 
    ... 
end 

Jaki jest najmniej brzydki sposób przekazać Hash instancji a gdy b został pominięty?

Próbowałem

woot(x: 1) 
woot({x: 1}) 
h = {x: 1} 
woot(h) 

ale wszystkie one podnieść

ArgumentError: unknown keyword: x 

Jedynym sposobem, aby nawiązać połączenie, że zorientowali się, jest

woot({x: 1}, **{}) 

Czy jest ładniejszy sposób?

+1

http://stackoverflow.com/questions/27821422/how-can-i-collapse-double-splat-arguments-into-nothing :: ** TLDNR; ** to prawdopodobnie błąd w aktualnym implingu ruby. – mudasobwa

Odpowiedz

1

Twój pierwszy argument jest opcjonalny, więc Ruby przyjmuje, że hasz, który przekazujesz, dotyczy podanych argumentów (*).

Nie sądzę, istnieje lepszy obejście, choć jest to nieco krótsza (ale niekoniecznie czystsze):

woot({x: 1}, {}) 

Gdybym był tobą chciałbym zmienić podpis metody rozwiązywania niejednoznaczności.


(*): Cóż, nie zawsze: woot({1=>3}) chętnie przechodzą hash do pierwszego opcjonalnego argumentu.

Jeszcze dziwniejsze, w przypadku woot({1=> 5, :b => 4}), Ruby podzieli słownik i przekaże {1=>5} do pierwszego opcjonalnego parametru.

Wygląda na to, że próbuje przechwycić wymienione parametry najpierw (i będzie narzekać na nieistniejące nazwy), a następnie przekazać resztę do opcjonalnych parametrów.

Ale chciałbym zobaczyć jakiś język-prawnik wyjaśnienie ...

+0

Wow, masz rację. To jeszcze bardziej dziwne. Typ argumentu nie tylko zmienia sposób jego przetwarzania, ale także rodzaj kluczy zawartych w argumencie. Tyle za zasadę najmniejszej niespodzianki. – jedediah

+0

Jest jeszcze więcej niespodzianek ... :) Niestety Ruby jest w większości "zdefiniowana" przez to, co robi MRI, więc ciężko jest cytować akapity, możesz chcieć sprawdzić źródło MRI ... –

0

Jeśli nie oczekiwać b jest wartość domyślna zmienić, kiedykolwiek, jak o przepuszczenie go wyraźnie?

woot({x: 1}, b: nil) 

Oczywiście, jeśli b jest wartość domyślna robi zmienić jeden dzień, można by nadal być przekazując nil, zastępując wartość b dla tego zaproszenia do czegoś innego niż jego nowej wartości domyślnej.

Powiązane problemy