2015-01-18 9 views
5

Ho un metodo definito così:Questa chiamata al metodo Ruby può essere eseguita senza ** {} alla fine?

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

Qual è il modo meno brutto passare un'istanza Hash per a quando b è omesso?

ho cercato

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

ma tutti alzano

ArgumentError: unknown keyword: x 

L'unico modo per effettuare la chiamata che ho capito è

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

C'è un modo migliore?

+1

http://stackoverflow.com/questions/27821422/how-can-i-collapse-double-splat-arguments-into-nothing :: ** TLDNR; ** è probabile che si sia verificato un errore nell'imp. Ruby corrente. – mudasobwa

risposta

1

Il tuo primo argomento è facoltativo, quindi Ruby presuppone che l'hash che stai passando sia per gli argomenti con nome (*).

Non credo che ci sia una soluzione migliore, anche se questo è un po 'più breve (ma non necessariamente più pulito):

woot({x: 1}, {}) 

Se fossi in te io cambierei la firma del metodo per risolvere l'ambiguità.


(*): Beh, non sempre: woot({1=>3}) sarà lieto di passare l'hash al primo argomento opzionale.

Ancora più strano, in caso di woot({1=> 5, :b => 4}), Ruby dividerà il dizionario e passerà allo {1=>5} al primo parametro facoltativo.

Sembra che lo cerchi di afferrare prima i parametri denominati (e si lamenterà dei nomi non esistenti), quindi passa il resto ai parametri facoltativi.

Ma mi piacerebbe vedere qualche spiegazione lingua avvocato ...

+0

Wow, hai ragione. È ancora più strano. Non solo il tipo dell'argomento cambia il modo in cui viene analizzato, ma il tipo di chiavi contenute nell'argomento. Così tanto per il principio di minima sorpresa. – jedediah

+0

C'è più sorpresa ... :) Purtroppo Ruby è per lo più "definito" da ciò che fa l'MRI, quindi è difficile citare i paragrafi, potresti voler cercare la sorgente MRI ... –

0

Se non vi aspettate valore di default s' b per cambiare, mai, come su di passarlo in modo esplicito?

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

Naturalmente, se il valore di default b s' fa cambiamento, un giorno, saresti ancora essere di passaggio in nil, ignorando così il valore b per tale chiamata a qualcosa d'altro rispetto al suo nuovo valore predefinito.

Problemi correlati