Lấy tên của phương thức hiện đang thực thi


198

$0 là biến cho chương trình Ruby cấp cao nhất, nhưng có một biến cho phương thức hiện tại không?


Một lần sử dụng là kiểm tra supercó thể được gọi trong một đối tượng SimpleDelegator:def description; __getobj__.respond_to?(__method__) ? super : 'No description'; end
Kris

Câu trả lời:


334

Thậm chí tốt hơn câu trả lời đầu tiên của tôi, bạn có thể sử dụng __method__:

class Foo
  def test_method
    __method__
  end
end

Điều này trả về một biểu tượng - ví dụ , :test_method. Để trả về tên phương thức dưới dạng chuỗi, hãy gọi __method__.to_sthay thế.

Lưu ý: Điều này đòi hỏi Ruby 1.8.7.


11
':' chỉ là biểu tượng biểu tượng. :) chỉ cần làm __method__.to_svà nó sẽ là tên phương thức, không có gì khác
Lambart

Nếu tôi đang làm nhiệm vụ cào thì sao?
Imran Ahmad

24

Từ http://snippets.dzone.com/posts/show/2785 :

module Kernel
private
    def this_method_name
      caller[0] =~ /`([^']*)'/ and $1
    end
end

class Foo
  def test_method
    this_method_name
  end
end

puts Foo.new.test_method    # => test_method

5
Điều này rất hữu ích với tôi khi tìm tên của phương thức gọi (trái ngược với phương thức hiện tại).
Lambart

Không __callee__làm điều này?
Joshua Pinter

Giải pháp tuyệt vời Mark Giải pháp tốt nhất hiện nay. Công việc tuyệt vời
jonathanccalix đến

18

Tùy thuộc vào những gì bạn thực sự muốn, bạn có thể sử dụng __method__hoặc __callee__trả về tên của phương thức hiện đang thực thi làm biểu tượng.

Trên ruby ​​1.9, cả hai đều hành xử giống hệt nhau (theo như các tài liệu và thử nghiệm của tôi có liên quan).

Trên ruby ​​2.1 & 2.2 __callee__hoạt động khác đi nếu bạn gọi bí danh của phương thức đã xác định. Các tài liệu cho hai là khác nhau:

  • __method__: "tên theo định nghĩa của phương thức hiện tại" (nghĩa là tên như được định nghĩa)
  • __callee__: "tên được gọi của phương thức hiện tại" (tức là tên như được gọi (được gọi))

Kịch bản thử nghiệm:

require 'pp'
puts RUBY_VERSION
class Foo
  def orig
    {callee: __callee__, method: __method__}
  end
  alias_method :myalias, :orig
end
pp( {call_orig: Foo.new.orig, call_alias: Foo.new.myalias} )

1.9.3 Đầu ra:

1.9.3
{:call_orig=>{:callee=>:orig, :method=>:orig},
 :call_alias=>{:callee=>:orig, :method=>:orig}}

2.1.2 Đầu ra ( __callee__trả về tên bí danh, nhưng __method__trả về tên tại điểm phương thức được xác định):

2.1.2
{:call_orig=>{:callee=>:orig, :method=>:orig},
 :call_alias=>{:callee=>:myalias, :method=>:orig}}

10

Đối với Ruby 1.9+ tôi khuyên bạn nên sử dụng __callee__


3
__callee__cư xử khác nhau trước 1.9, vì vậy tốt nhất bạn nên tuân thủ __method__vì nó có hành vi nhất quán. __callee__hành xử giống như __method__sau 1.9.
Leigh McCulloch

@LeighMcCulloch bạn có thể giải thích sự khác biệt bằng một ví dụ (có thể trong một câu trả lời mới) không?
Ciro Santilli 郝海东 冠状 病 事件

@CiroSantilli 事件 法轮功 纳米比亚def m1() puts("here is #{__method__} method. My caller is #{__callee__}.") end; def m2() puts("here is #{__method__} method. Let's call m1"); m1 end; m2Bạn không thấy gì lạ à?
jgburet

4
@LeighMcCulloch thực sự bây giờ __callee____method__có hành vi khác nhau. Xem pastie.org/10380985 (ruby 2.1.5)
goodniceweb

1
pastie.org là xuống. Mãi mãi hay chỉ là bây giờ?
Nakilon

-3

Tôi gặp vấn đề tương tự để lấy tên phương thức trong tệp xem. Tôi đã có giải pháp bằng cách

params[:action] # it will return method's name

nếu bạn muốn lấy tên của trình điều khiển thì

params[:controller] # it will return you controller's name

4
Tôi nghĩ rằng bạn đã hiểu sai câu hỏi về các hành động của bộ điều khiển rails & các phương thức http ... câu trả lời này có lẽ nên bị xóa.
Nhân tố huyền bí

Hữu ích cho việc lấy tên của phương thức (bộ điều khiển) hiện đang thực thi từ khung nhìn.
avjaarsveld
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.