metode kirim ruby ​​lewat beberapa parameter

129

Mencoba membuat objek dan memanggil metode secara dinamis oleh

Object.const_get(class_name).new.send(method_name,parameters_array)

yang berfungsi dengan baik saat

Object.const_get(RandomClass).new.send(i_take_arguments,[10.0])

tetapi melemparkan jumlah argumen 1 untuk 2 yang salah untuk

Object.const_get(RandomClass).new.send(i_take_multiple_arguments,[25.0,26.0])

Kelas Acak yang didefinisikan adalah

class RandomClass
def i_am_method_one
    puts "I am method 1"
end
def i_take_arguments(a)
    puts "the argument passed is #{a}"
end
def i_take_multiple_arguments(b,c)
    puts "the arguments passed are #{b} and #{c}"
end
    end

Dapatkah seseorang membantu saya tentang cara mengirim parameter mutiple ke metode ruby ​​secara dinamis

rails4sandeep
sumber

Jawaban:

232
send("i_take_multiple_arguments", *[25.0,26.0]) #Where star is the "splat" operator

atau

send(:i_take_multiple_arguments, 25.0, 26.0)
Seanny123
sumber
22
Mungkin perlu dicatat bahwa *dalam konteks ini adalah operator "percikan".
Andrew Marshall
8

Anda dapat menelepon secara bergantian senddengan sinonimnya __send__:

r = RandomClass.new
r.__send__(:i_take_multiple_arguments, 'a_param', 'b_param')

Ngomong-ngomong * Anda dapat melewatkan hash saat param dipisahkan oleh koma seperti:

imaginary_object.__send__(:find, :city => "city100")

atau sintaks hash baru:

imaginary_object.__send__(:find, city: "city100", loc: [-76, 39])

Menurut Black, __send__lebih aman untuk namespace.

“Mengirim adalah konsep luas: email dikirim, data dikirim ke soket I / O, dan sebagainya. Bukan hal yang aneh bagi program untuk mendefinisikan metode yang disebut kirim yang bertentangan dengan metode pengiriman bawaan Ruby. Oleh karena itu, Ruby memberi Anda cara alternatif untuk panggilan mengirim: __send__. Dengan konvensi, tidak ada yang pernah menulis metode dengan nama itu, jadi versi Ruby bawaan selalu tersedia dan tidak pernah bertentangan dengan metode yang baru ditulis. Itu terlihat aneh, tapi ini lebih aman daripada versi pengiriman biasa dari sudut pandang bentrok metode-nama ”

Black juga menyarankan untuk membungkus panggilan __send__masuk if respond_to?(method_name).

if r.respond_to?(method_name)
    puts r.__send__(method_name)
else
    puts "#{r.to_s} doesn't respond to #{method_name}"
end

Ref: Black, David A. Rubyist yang beralasan. Manning, 2009. P.171.

* Saya datang ke sini untuk mencari sintaks hash __send__, jadi semoga bermanfaat untuk googler lain. ;)

Tony Cronin
sumber