Saya tidak tahu mengapa semua orang menyarankan Anda harus menggunakan instance_methods
dan include?
kapan method_defined?
melakukan pekerjaan.
class Test
def hello; end
end
Test.method_defined? :hello #=> true
CATATAN
Jika Anda datang ke Ruby dari bahasa OO lain ATAU Anda berpikir itu method_defined
HANYA metode yang Anda tetapkan secara eksplisit dengan:
def my_method
end
kemudian baca ini:
Di Ruby, properti (atribut) pada model Anda pada dasarnya juga merupakan metode. Jadi method_defined?
juga akan mengembalikan true untuk properti, bukan hanya metode.
Sebagai contoh:
Diberikan turunan dari kelas yang memiliki atribut String first_name
:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
karena first_name
merupakan atribut dan metode (dan string tipe String).
String.instance_methods(false).include? :freeze
, yang palsu argumen bisa tahu persis apakahfreeze
metode didefinisikan dalam kelas String atau tidak. Dalam hal ini ia akan mengembalikan false karenafreeze
metode diwarisi dari modul Kernel oleh String, tetapiString.method_defined? :freeze
akan selalu kembali benar, yang tidak dapat banyak membantu dengan tujuan seperti itu.method_defined?
harus digunakan di kelas (mis.Array
), tetapi Anda mencoba menggunakannya dalam instance (mis[]
)Anda dapat menggunakan
method_defined?
sebagai berikut:Jauh lebih mudah, portabel, dan efisien daripada yang
instance_methods.include?
disarankan orang lain.Ingatlah bahwa Anda tidak akan tahu apakah kelas merespons secara dinamis beberapa panggilan dengan
method_missing
, misalnya dengan mendefinisikan ulangrespond_to?
, atau sejak Ruby 1.9.2 dengan mendefinisikanrespond_to_missing?
.sumber
instance.class.method_defined? :upcase
Sebenarnya ini tidak berfungsi untuk Obyek dan Kelas.
Ini tidak:
Jadi dengan jawaban yang diberikan, ini berfungsi:
Tapi ini TIDAK berhasil:
Jadi saya menggunakan ini untuk kelas dan objek:
Kelas:
Benda:
sumber
Jawaban untuk " Diberikan kelas, lihat apakah instance memiliki metode (Ruby) " lebih baik. Rupanya Ruby memiliki built-in ini, dan entah bagaimana saya melewatkannya. Jawaban saya dibiarkan untuk referensi, terlepas.
Kelas Ruby merespons metode
instance_methods
danpublic_instance_methods
. Di Ruby 1.8, yang pertama mencantumkan semua nama metode instance dalam array string, dan yang kedua membatasi ke metode publik. Perilaku kedua adalah apa yang kemungkinan besar Anda inginkan, karenarespond_to?
membatasi dirinya pada metode publik secara default, juga.Di Ruby 1.9, metode tersebut mengembalikan array simbol.
Jika Anda berencana sering melakukan ini, Anda mungkin ingin memperluas
Module
untuk memasukkan metode pintas. (Ini mungkin aneh untuk menempatkan iniModule
daripadaClass
, tetapi karena di situlahinstance_methods
metode tinggal, yang terbaik untuk tetap sejalan dengan pola itu.)Jika Anda ingin mendukung Ruby 1.8 dan Ruby 1.9, itu akan menjadi tempat yang nyaman untuk menambahkan logika untuk mencari string dan simbol, juga.
sumber
method_defined?
lebih baik :)Mencoba
Foo.instance_methods.include? :bar
sumber
Tidak yakin apakah ini cara terbaik, tetapi Anda selalu bisa melakukan ini:
sumber
Saya pikir ada sesuatu yang salah dengan
method_defined?
Rails. Mungkin tidak konsisten atau semacamnya, jadi jika Anda menggunakan Rails, lebih baik menggunakan sesuatu dariattribute_method?(attribute)
." pengujian untuk method_defined? di kelas ActiveRecord tidak berfungsi sampai instantiasi " adalah pertanyaan tentang ketidakkonsistenan.
sumber
Jika Anda memeriksa untuk melihat apakah suatu objek dapat merespons serangkaian metode, Anda dapat melakukan sesuatu seperti:
yang
methods & something.methods
akan bergabung dengan dua array pada umum / pencocokan elemen mereka. something.methods mencakup semua metode yang Anda periksa, itu akan sama dengan metode. Sebagai contoh:begitu
Dalam situasi ini, Anda ingin menggunakan simbol, karena ketika Anda memanggil .methods, ia mengembalikan array simbol dan jika Anda menggunakannya
["my", "methods"]
, itu akan mengembalikan false.sumber
klass.instance_methods.include :method_name
atau"method_name"
, tergantung pada versi Ruby yang saya pikir.sumber
Semoga ini bisa membantu Anda!
sumber
Pada kasus saya bekerja dengan ruby 2.5.3 kalimat berikut ini telah bekerja dengan baik:
Ini akan mengembalikan nilai boolean benar atau salah.
sumber
Meskipun
respond_to?
akan mengembalikan true hanya untuk metode publik, memeriksa "definisi metode" pada kelas juga mungkin berkaitan dengan metode pribadi.Pada Ruby v2.0 + memeriksa set publik dan pribadi dapat dicapai dengan
sumber