apakah ada cara di Ruby untuk menemukan nama metode panggilan di dalam metode?
Sebagai contoh:
class Test
def self.foo
Fooz.bar
end
end
class Fooz
def self.bar
# get Test.foo or foo
end
end
apakah ada cara di Ruby untuk menemukan nama metode panggilan di dalam metode?
Sebagai contoh:
class Test
def self.foo
Fooz.bar
end
end
class Fooz
def self.bar
# get Test.foo or foo
end
end
Jawaban:
puts caller[0]
atau mungkin...
puts caller[0][/`.*'/][1..-2]
caller[0][/`(.*)'/,1]
"block in make_lambda". Saya kira ini hanya untuk Ruby.
Di Ruby 2.0.0, Anda dapat menggunakan:
caller_locations(1,1)[0].label
Ini jauh lebih cepat daripada solusi Ruby 1.8+:
caller[0][/`([^']*)'/, 1]
Akan disertakan backportssaat saya mendapatkan waktu (atau permintaan tarik!).
caller_locations[0].labeldi Ruby 2.2.0 lagi Anda selalu memiliki send_actionhasil
Menggunakan caller_locations(1,1)[0].label (untuk ruby> = 2.0)
Sunting : Jawaban saya mengatakan untuk digunakan __method__tetapi saya salah, ia mengembalikan nama metode saat ini.
saya menggunakan
caller[0][/`([^']*)'/, 1]
'luar yang Anda cari (dan saya anggap tidak bisa), hasilnya akan sama, tentu. Namun, [^']*akan tampil lebih baik karena mesin regex akan berhenti berusaha untuk mencocokkan bagian ekspresi saat itu mencapai '(versi Anda akan pergi ke akhir, lalu mundur karena tidak menemukan 'di akhir). Perbedaannya cukup diabaikan dalam kasus ini tentu saja, tetapi itu kebiasaan yang baik untuk dihindari .di regex jika memungkinkan.
Bagaimana tentang
caller[0].split("`").pop.gsub("'", "")
Imo jauh lebih bersih.
Sebagai gantinya, Anda dapat menuliskannya sebagai fungsi perpustakaan dan melakukan panggilan di mana pun diperlukan. Kode tersebut sebagai berikut:
module CallChain
def self.caller_method(depth=1)
parse_caller(caller(depth+1).first).last
end
private
# Copied from ActionMailer
def self.parse_caller(at)
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
file = Regexp.last_match[1]
line = Regexp.last_match[2].to_i
method = Regexp.last_match[3]
[file, line, method]
end
end
end
Untuk memicu metode modul di atas, Anda perlu memanggil seperti ini:
caller = CallChain.caller_method
Untuk melihat penelepon dan meninggalkan informasi dalam bahasa apa pun, apakah itu ruby atau java atau python, Anda selalu ingin melihat jejak stack. Dalam beberapa bahasa, seperti Rust dan C ++, ada opsi yang dibangun ke dalam kompiler untuk menyalakan semacam mekanisme profil yang dapat Anda lihat selama waktu berjalan. Saya percaya satu ada untuk Ruby yang disebut ruby-prof.
Dan seperti yang disebutkan di atas, Anda bisa melihat tumpukan eksekusi untuk ruby. Tumpukan eksekusi ini adalah array yang berisi objek lokasi jejak balik.
Pada dasarnya yang perlu Anda ketahui tentang perintah ini adalah sebagai berikut:
pemanggil (mulai = 1, panjang = nihil) → array atau nihil