Antworten:
Ruby 2.0 führte Schlüsselwortargumente ein und **
verhält sich wie *
, jedoch für Schlüsselwortargumente. Es gibt einen Hash mit Schlüssel / Wert-Paaren zurück.
Für diesen Code:
def foo(a, *b, **c)
[a, b, c]
end
Hier ist eine Demo:
> foo 10
=> [10, [], {}]
> foo 10, 20, 30
=> [10, [20, 30], {}]
> foo 10, 20, 30, d: 40, e: 50
=> [10, [20, 30], {:d=>40, :e=>50}]
> foo 10, d: 40, e: 50
=> [10, [], {:d=>40, :e=>50}]
Dies ist der Double-Splat- Operator, der seit Ruby 2.0 verfügbar ist.
Es erfasst alle Schlüsselwortargumente (was auch ein einfacher Hash sein kann, was die idiomatische Methode war, Schlüsselwortargumente zu emulieren, bevor sie Teil der Ruby-Sprache wurden).
def my_method(**options)
puts options.inspect
end
my_method(key: "value")
Der obige Code wird {key:value}
auf der Konsole gedruckt .
Genau wie der einzelne Splat-Operator alle regulären Argumente erfasst, erhalten Sie jedoch anstelle eines Arrays einen Hash .
Beispiel aus der Praxis:
In Rails cycle
sieht die Methode beispielsweise folgendermaßen aus:
def cycle(first_value, *values)
options = values.extract_options!
# ...
end
Diese Methode kann folgendermaßen aufgerufen werden : cycle("red", "green", "blue", name: "colors")
.
Dies ist ein weit verbreitetes Muster: Sie akzeptieren eine Liste von Argumenten und das letzte ist ein Options-Hash, der beispielsweise mit ActiveSupport extrahiert werden kann extract_options!
.
In Ruby 2.0 können Sie diese Methoden vereinfachen:
def cycle(first_value, *values, **options)
# Same code as above without further changes!
end
Zugegeben, es ist nur eine geringfügige Verbesserung, wenn Sie ActiveSupport bereits verwenden, aber für einfaches Ruby gewinnt der Code ziemlich viel Prägnanz.
Darüber hinaus können Sie es auf der Anruferseite wie folgt verwenden:
def foo(opts); p opts end
bar = {a:1, b:2}
foo(bar, c: 3)
=> ArgumentError: wrong number of arguments (given 2, expected 1)
foo(**bar, c: 3)
=> {:a=>1, :b=>2, :c=>3}
opts = {d: 40, e: 50}
, dannfoo 10, opts, f: 60
wird zuweisen{f: 60}
zuc
, währendfoo 10, **opts, f: 60
zuweist{d: 40, e: 50, f: 60}
. Um den zweiten Effekt zu erzielen, hätten Sie zuvormerge
die Arrays explizit d.