2013-04-03 7 views
9

Festlegen eines Standardwert für ein Splat Argument gibt einen Fehler einen Standardwert gesetzt:Wie für ein Splat Argument in Ruby

1.9.3-p374 :001 > def a b, *c = nil 
1.9.3-p374 :002?> end 
SyntaxError: (irb):1: syntax error, unexpected '=', expecting ';' or '\n' 
def a b, *c = nil 
      ^
    from /Users/me/.rvm/rubies/ruby-1.9.3-p374/bin/irb:16:in `<main>' 

Einige Variationen Ich habe versucht, das auch nicht funktionieren:

1.9.3-p374 :003 > def a b, *c = [] 
1.9.3-p374 :005 > def a b, (*c) = nil 
1.9.3-p374 :007 > def a b, (*c = []) 
1.9.3-p374 :009 > def a b, (*c = [1,2,3]) 
1.9.3-p374 :011 > def a b, *c = [1,2,3] 

Ich sehe hier kein Unbestimmtheits-Problem, also scheint es möglich zu sein.

Verwandte: Why non-explicit splat param plus default param is wrong syntax for method definition in Ruby 1.9?

+1

Splat Argument ist standardmäßig leer Array – fl00r

+1

Ja, aber was ist mit einem Standardargument? – jordanpg

+0

Gibt es einen Grund, warum Sie eine Antwort noch nicht akzeptiert haben? – vlasits

Antwort

6

Ihre versuchte Verwendung widerspricht den Konventionen für die Verwendung von splat. Splats sollen (zumindest in Ruby) alle extra (0, 1 oder mehr) Werte übernehmen.

Wenn Sie wissen, dass Sie den zweiten Wert in Ihrer Methode Argumente auflisten möchten einen Standardwert haben, können Sie es aus dem Splat nehmen und geben Sie es kurz vor dem Splat mit einem Standardwert wie folgt aus:

def a b, c=nil, *d 
    # rest of code omitted 
end 

EDIT: Um die Antwort auf Ihre Frage, warum es nicht funktioniert, klar zu machen. Es ist eine Designentscheidung des Sprachdesigners. Matz wollte den Splat-Operator nie mit Standardeinstellungen arbeiten lassen. Dies erscheint mir sehr sinnvoll, da es dazu gedacht ist, eine unbestimmte Anzahl von Variablen zu erfassen, und weil die beschriebene Methode klarer liest als die beschriebenen Möglichkeiten und weil alle Probleme, die Ihre Beispiele lösen, auf andere Weise lösbar sind.

+1

+1 Dies ist der richtige Weg, dies zu tun. Wenn 'c' ist das spezielle, fördern Sie es zu seinem eigenen Parametereintrag, und spielen Sie Spiele nicht, die versuchen, es von der gespritzten Variable zu extrahieren. –

0

Ein Splat Argument standardmäßig ein leeres Array, ohne etwas Besonderes zu tun.

def a(b, *c) 
    c 
end 

a("foo") 
#=> [] 
+0

Ja, aber was ist mit einem Standardargument neben Null? – jordanpg

+0

Siehe meine Antwort, was zu tun ist, wenn Sie möchten, dass c einen Standardwert hat – vlasits

2

Sie können den Standardwert in der Methode selbst festlegen, da der Standardwert splat ein leeres Array zurückgibt.

def test(a, *b) 
    b = "default b" if b == [] # edited as per Tin Man's recommendation 
    puts [a, b].inspect 
end 

test("Test", 1, 2) 
# => ["Test", [1, 2]] 
test("Test") 
# => ["Test", "default b"] 

In Rails, könnten Sie für b.present? überprüfen, wie ein leeres Array leer betrachtet. Ich hoffe, das hilft.

+0

'b == [] und b =" default b "' wird nicht für den Ruby-Stil empfohlen. Verwenden Sie 'b =" default b "wenn b == []'. –

+0

Danke, ich habe deinen Vorschlag aufgenommen. Gibt es einen technischen Grund dafür? –

+4

Es ist ein Lesbarkeits- und Wartungsproblem. Die Verwendung eines Booleschen Werts für den konditionalen Test und die Zuweisung ist ein C/Perl-Konstrukt; Es ist knapp, fast kryptisch, ohne nennenswerte, wenn überhaupt, Geschwindigkeit. Wenn man in C oder Perl schreibt, ist es fast macho, dass man so schreiben kann, aber der Ruby-Weg ist, etwas mehr Knappheit für mehr Lesbarkeit zu geben.Wenn Sie 'und' verwenden und dann zusätzliche Tests oder Zuordnungen hinzufügen, kann die Rangfolge Sie beißen, was sehr schwierig zu ermitteln ist. Die Verwendung von '&&' vermeidet das Präzedenzproblem oft, erhöht aber nicht die Lesbarkeit. –

0

Dies ist sehr praktisch:

def initialize(*response_names) 
    @response_names = response_names.presence || %w(default values) 
end 
Verwandte Themen