Có cách nào trong Ruby để tìm tên phương thức gọi bên trong một phương thức không?
Ví dụ:
class Test
def self.foo
Fooz.bar
end
end
class Fooz
def self.bar
# get Test.foo or foo
end
end
Có cách nào trong Ruby để tìm tên phương thức gọi bên trong một phương thức không?
Ví dụ:
class Test
def self.foo
Fooz.bar
end
end
class Fooz
def self.bar
# get Test.foo or foo
end
end
Câu trả lời:
puts caller[0]
hoặc có lẽ...
puts caller[0][/`.*'/][1..-2]
caller[0][/`(.*)'/,1]
"block in make_lambda"
. Tôi đoán cái này chỉ dành cho Ruby.
Trong Ruby 2.0.0, bạn có thể sử dụng:
caller_locations(1,1)[0].label
Nó nhanh hơn nhiều so với giải pháp Ruby 1.8+:
caller[0][/`([^']*)'/, 1]
Sẽ được bao gồm trong backports
khi tôi nhận được thời gian (hoặc yêu cầu kéo!).
caller_locations[0].label
trên Ruby 2.2.0, bạn luôn có send_action
kết quả
Sử dụng caller_locations(1,1)[0].label
(cho ruby> = 2.0)
Chỉnh sửa : Câu trả lời của tôi là nói sử dụng __method__
nhưng tôi đã sai, nó trả về tên phương thức hiện tại.
tôi sử dụng
caller[0][/`([^']*)'/, 1]
'
vượt quá cái bạn đang tìm kiếm (và tôi cho rằng nó không thể), kết quả sẽ giống nhau, chắc chắn. Tuy nhiên, [^']*
sẽ hoạt động tốt hơn vì công cụ regex sẽ ngừng cố gắng khớp phần đó với biểu thức thời điểm nó đạt đến '
(phiên bản của bạn sẽ kết thúc, sau đó quay lại vì không tìm thấy '
ở cuối). Tất nhiên, sự khác biệt là không đáng kể trong trường hợp này, nhưng đó là một thói quen tốt để tránh .
trong các chế độ có thể.
Thay vào đó bạn có thể viết nó dưới dạng chức năng thư viện và thực hiện cuộc gọi bất cứ khi nào cần. Mã này như sau:
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
Để kích hoạt phương thức mô-đun trên, bạn cần gọi như sau:
caller = CallChain.caller_method
Để xem thông tin người gọi và callee bằng bất kỳ ngôn ngữ nào, cho dù đó là ruby hay java hay python, bạn sẽ luôn muốn nhìn vào dấu vết ngăn xếp. Trong một số ngôn ngữ, chẳng hạn như Rust và C ++, có các tùy chọn được tích hợp trong trình biên dịch để bật một số loại cơ chế định hình mà bạn có thể xem trong thời gian chạy. Tôi tin rằng một tồn tại cho Ruby được gọi là ruby-prof.
Và như đã đề cập ở trên, bạn có thể nhìn vào ngăn xếp thực thi cho ruby. Ngăn xếp thực thi này là một mảng chứa các đối tượng vị trí backtrace.
Về cơ bản tất cả những gì bạn cần biết về lệnh này như sau:
người gọi (start = 1, length = nil) → mảng hoặc nil