Saya mencoba mengotak-atik Ruby. Untuk itu saya mencoba mengimplementasikan algoritma (diberikan dengan Python) dari buku "Programming Collective Intelligence" Ruby.
Dalam bab 8, penulis menggunakan metode a sebagai parameter. Ini sepertinya bekerja dengan Python tetapi tidak di Ruby.
Saya memiliki metode di sini
def gaussian(dist, sigma=10.0)
foo
end
dan ingin menyebutnya dengan metode lain
def weightedknn(data, vec1, k = 5, weightf = gaussian)
foo
weight = weightf(dist)
foo
end
Yang saya dapatkan hanyalah kesalahan
ArgumentError: wrong number of arguments (0 for 1)
sumber
foo.bar(a,b)
pengiriman, itu sajafoo.send(:bar, a, b)
. Operator percikan (*) memungkinkan Anda melakukannyafoo.send(:bar, *[a,b])
jika Anda merasa ingin memiliki array argumen memanjang yang sewenang-wenang - dengan asumsi metode bilah dapat menyerapnyaKomentar yang merujuk pada blok dan Procs benar karena lebih umum di Ruby. Tapi Anda bisa melewatkan metode jika Anda mau. Anda memanggil
method
untuk mendapatkan metode dan.call
menyebutnya:sumber
method( :<name> )
hanya memanggil sekali saat mengubah nama metode Anda menjadi simbol yang dapat dipanggil. Anda dapat menyimpan hasil itu dalam variabel atau parameter dan terus meneruskannya ke fungsiSomewhereElse.method(:method_name)
. Itu sangat keren!:func.class
tetapi itu hanyasymbol
Anda bisa melewatkan metode sebagai parameter dengan
method(:function)
cara. Di bawah ini adalah contoh yang sangat sederhana:sumber
method_with_function_as_param(Class.method(:method_name),...)
dan bukanmethod(:Class.method_name)
method
. Membuat hari saya menyenangkan tetapi saya rasa itu sebabnya saya lebih suka bahasa fungsional, tidak perlu melakukan akrobat seperti itu untuk mendapatkan apa yang Anda inginkan. Bagaimanapun, saya menggali rubyCara biasa Ruby untuk melakukan ini adalah dengan menggunakan blok.
Jadi itu akan menjadi seperti ini:
Dan digunakan seperti:
Pola ini digunakan secara luas di Ruby.
sumber
Anda dapat menggunakan
&
operator padaMethod
contoh metode Anda untuk mengubah metode menjadi blok .Contoh:
Detail lebih lanjut di http://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html
sumber
Anda harus memanggil metode "panggilan" dari objek fungsi:
EDIT: seperti yang dijelaskan di komentar, pendekatan ini salah. Ini akan berfungsi jika Anda menggunakan Procs daripada fungsi normal.
sumber
weightf = gaussian
di daftar arg itu sebenarnya mencoba untuk mengeksekusigaussian
dan menetapkan hasilnya sebagai nilai default dari weightf. Panggilan tidak membutuhkan args dan crash. Jadi weightf bahkan bukan objek proc dengan metode panggilan dulu.Saya akan merekomendasikan untuk menggunakan ampersand untuk memiliki akses ke blok bernama dalam suatu fungsi. Mengikuti rekomendasi yang diberikan dalam artikel ini Anda dapat menulis sesuatu seperti ini (ini adalah potongan nyata dari program kerja saya):
Selanjutnya, Anda dapat memanggil fungsi ini seperti ini:
Jika Anda tidak perlu memfilter pilihan Anda, Anda cukup menghilangkan pencekalan:
Begitu hebatnya kekuatan blok Ruby.
sumber
Anda juga bisa menggunakan "eval", dan meneruskan metode sebagai argumen string, lalu cukup evaluasi di metode lain.
sumber
eval
dapat mengeksekusi kode arbitrer sehingga sangat rentan terhadap berbagai serangan.