2010-09-13 2 views
58

Wenn ein Idiom verwenden wie:Geben eines Hash Funktion (* args) und seine Bedeutung

def func(*args) 
    ... 
end 

Was ist die Bedeutung von * args? Diese spezifische Frage zu googeln war ziemlich schwierig und ich konnte nichts finden.

Es scheint, alle Argumente in args erscheinen tatsächlich [0] so finde ich mich defensiven Code zu schreiben wie:

my_var = args[0].delete(:var_name) if args[0] 

Aber ich bin sicher, dass es einen besseren Weg, ich heraus bin fehlt.

Antwort

88

Die * ist die splat (oder Sternchen) -Operator. Im Kontext einer Methode gibt sie eine Argumentliste mit variabler Länge an. In Ihrem Fall werden alle Argumente, die an func übergeben werden, in ein Array namens args eingefügt.

def func2(arg1, arg2, *other_args) 
    # ... 
end 

Lassen Sie uns sagen, dass wir diese Methode aufrufen: Sie können auch bestimmte Argumente, bevor ein variabler Länge Argument wie so angeben

func2(1, 2, 3, 4, 5) 

Wenn Sie arg1, arg2 und other_args innerhalb func2 jetzt untersuchen, werden Sie bekomme folgende Ergebnisse:

In deinem Fall scheinst du einen Hash als Argument zu übergeben Ihre func, in diesem Fall args[0] wird den Hash enthalten, wie Sie beobachten.

Ressourcen:


aktualisieren basierend auf OP Kommentare

Wenn Sie einen Hash als Argument übergeben möchten, sollten Sie nicht nutzen der Splat-Operator. Mit Ruby können Sie Klammern, , einschließlich derjenigen, die einen Hash angeben (mit einem Vorbehalt, lesen Sie weiter), in Ihren Methodenaufrufen auslassen. Deshalb:

my_func arg1, arg2, :html_arg => value, :html_arg2 => value2 

entspricht

my_func(arg1, arg2, {:html_arg => value, :html_arg2 => value2}) 

Wenn Rubin sieht der => Operator in Ihrer Argumentliste, es kennt das Argument als Hash zu nehmen, auch ohne ausdrückliche {...} Notation (beachten Sie, dass diese trifft nur zu, wenn das Hash-Argument das letzte ist!).

Wenn Sie diesen Hash sammeln möchten, müssen Sie nichts Besonderes tun (obwohl Sie wahrscheinlich eine leere Hash als Standardwert in der Methodendefinition angeben wollen):

def my_func(arg1, arg2, html_args = {}) 
    # ... 
end 
+0

Also muss ich beim Zugriff auf die Params die defensive 'if args [0]' Technik verwenden? – shmichael

+0

@shmichael Wie rufst du deine Methode an? Wenn Sie nicht möchten, dass Ihre Argumente in ein Array wie dieses eingefügt werden, verwenden Sie nicht den Splat. –

+0

Ich verwende die Rails-Konvention (z. B. 'my_func arg1, arg2,: html_arg => value,: html_arg2 => value2'). Idealerweise würde ich gerne ein 'args' * Hash * und kein' args' * Array erhalten, das einen Hash * enthalten könnte. – shmichael

-3
def func(map={}) 
    x = map.delete(:y) 
end