Apa yang dilakukan oleh operator ganda * (percikan)


214

Pernahkah Anda melihat fungsi yang dideklarasikan seperti ini?

def foo a, **b
  ...
end

Saya mengerti bahwa satu *adalah operator percikan. Apa **artinya

Jawaban:


373

Ruby 2.0 memperkenalkan argumen kata kunci, dan **bertindak seperti *, tetapi untuk argumen kata kunci. Ini mengembalikan hash dengan pasangan kunci / nilai.

Untuk kode ini:

def foo(a, *b, **c)
  [a, b, c]
end

Ini 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}]

44
Ini menjawab pertanyaan dengan sempurna, tapi saya punya sedikit tambahan. Sama seperti operator percikan dapat digunakan pada array yang Anda lewati, percikan ganda dapat digunakan pada hashes. Jika opts = {d: 40, e: 50}, maka foo 10, opts, f: 60akan menetapkan {f: 60}ke c, sedangkan foo 10, **opts, f: 60akan menetapkan {d: 40, e: 50, f: 60}. Untuk mencapai efek kedua, sebelumnya Anda akan memiliki mergearray secara eksplisit.
brymck

Saya akan menganggap ini berguna untuk menetapkan parameter hash opsional untuk suatu metode
bigpotato

Mungkin patut dicatat bahwa jika mencampur argumen kata kunci dengan kata kunci percikan, kata kunci percikan perlu muncul setelah argumen kata kunci.
MrMesees

43

Itu adalah operator percikan ganda yang tersedia sejak Ruby 2.0.

Itu menangkap semua argumen kata kunci (yang juga bisa menjadi hash sederhana, yang merupakan cara idiomatis untuk meniru argumen kata kunci sebelum mereka menjadi bagian dari bahasa Ruby)

def my_method(**options)
  puts options.inspect
end

my_method(key: "value")

Kode di atas mencetak {key:value}ke konsol.

Sama seperti operator percikan tunggal menangkap semua argumen reguler, tetapi bukannya array Anda mendapatkan hash .

Contoh kehidupan nyata:

Sebagai contoh di Rails, cyclemetodenya terlihat seperti ini:

def cycle(first_value, *values)
  options = values.extract_options!
  # ...
end

Metode ini bisa disebut seperti ini: cycle("red", "green", "blue", name: "colors").

Ini adalah pola yang cukup umum: Anda menerima daftar argumen dan yang terakhir adalah hash opsi, yang dapat diekstraksi - misalnya - menggunakan ActiveSupport extract_options!.

Di Ruby 2.0 Anda dapat menyederhanakan metode ini:

def cycle(first_value, *values, **options)
  # Same code as above without further changes!
end

Memang ini hanya perbaikan kecil jika Anda sudah menggunakan ActiveSupport tetapi untuk Ruby biasa kode ini mendapatkan cukup banyak keringkasan.


20

Selain itu, Anda dapat menggunakannya di sisi pemanggil seperti ini:

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}

5
Wow, double-splat analog dengan operator penyebaran objek ES6.
mpoisot

1
Terima kasih, itu konfirmasi yang saya cari.
Qortex
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.