Nhận danh sách các phương thức cá thể của một lớp


98

Tôi có một lớp học:

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

Làm thế nào tôi có thể nhận được một danh sách các phương pháp của tôi trong lớp này ( method1, method2, method3)?

Câu trả lời:


114

Bạn thực sự muốn TestClass.instance_methods, trừ khi bạn quan tâm đến những gì TestClassnó có thể làm.

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

TestClass.methods.grep(/method1/) # => []
TestClass.instance_methods.grep(/method1/) # => ["method1"]
TestClass.methods.grep(/new/) # => ["new"]

Hoặc bạn có thể gọi methods(không instance_methods) trên đối tượng:

test_object = TestClass.new
test_object.methods.grep(/method1/) # => ["method1"]

3
Heh, bạn đánh bại tôi với nó 47 giây. +1
Phrogz

2
Khi tôi cố gắng print TestClass.new.instance_methods, tôi nhận được lỗi nàymy_class.rb:10:in <main>: undefined method instance_methods for #<TestClass:0x96b9d20> (NoMethodError)
Vladimir Tsukanov

Bạn chỉ cần làm TestClass.new.methods. Có lẽ "nó" đã mơ hồ trong câu trả lời của tôi.
Andrew Grimm

Lưu ý rằng trong Ruby 1.9+, mảng tên phương thức là ký hiệu, không phải chuỗi.
Phrogz

1
@Phrogz: Có, nhưng bạn được phép sử dụng biểu thức chính quy trên chúng. Bạn thậm chí không triệu hồi Cthulhu! :) Mặc dù bạn sẽ nhận được [:method1]thay thế.
Andrew Grimm

113
TestClass.methods(false) 

để chỉ nhận các phương thức chỉ thuộc về lớp đó.

TestClass.instance_methods(false) sẽ trả về các phương thức từ ví dụ đã cho của bạn (vì chúng là các phương thức thể hiện của TestClass).


2
Đây là cách tuyệt vời để kiểm tra xem một lớp có các phương thức đa hình từ một lớp cơ sở giả Giao diện / Trừu tượng mà không cần phải thử và gọi các phương thức trực tiếp hay không.
Daniel Doezema,

2
Câu trả lời được chấp nhận là tuyệt vời nhưng câu trả lời này có khả năng nhiều người sẽ đến đây hơn!
Aaron

Đây chắc chắn phải là câu trả lời được chấp nhận. CẢM ƠN!
Vinicius Brasil,

38
TestClass.instance_methods

hoặc không có tất cả các phương pháp kế thừa

TestClass.instance_methods - Object.methods

(Là 'TestClass.methods - Object.methods')


25
hoặc không có kế thừa phương pháp: TestClass.methods(false).
sawa

2
@sawa TestClass.methods(false)trả về trống
Vladimir Tsukanov

1
Câu trả lời này là sai; kết quả sẽ không bao gồm method1, method2hoặc method3, vì đó là các phương thức của các thể hiện của lớp, không phải phương thức của TestClasschính đối tượng.
Phrogz

1
@Phrogz: Rất tiếc ... vâng, 'TestClass.instance_methods - Object.methods' hoặc 'TestClass.new.methods - Object.methods' ... sẽ dạy tôi cách không kích hoạt bảng điều khiển. Tốt nhất là tôi nên xóa câu trả lời này, hay chỉnh sửa nó?
Pavling

1
@Pavling Chắc chắn sẽ chỉnh sửa câu trả lời của bạn cho đúng. (Nhanh chóng, trước khi OP chuyển nhượng tín dụng cho người khác! :)
Phrogz

6

Bạn có thể nhận được một danh sách chi tiết hơn (ví dụ được cấu trúc bằng cách xác định lớp) với các viên ngọc như gỡ lỗi hoặc looksee .


6
$ irb --simple-prompt

class TestClass
  def method1
  end

  def method2
  end

  def method3
  end
end

tc_list = TestClass.instance_methods(false)
#[:method1, :method2, :method3]
puts tc_list
#method1
#method2
#method3

2
Điều này quá giống với các câu trả lời khác và không thêm thông tin bổ sung hoặc không rõ ràng.
trọng

3
Bạn ấp úng đề cập thì cũng đã muộn. : D
Douglas G. Allen

2

Theo Ruby Doc instance_methods

Trả về một mảng chứa tên của các phương thức cá thể công khai và được bảo vệ trong bộ thu. Đối với một mô-đun, đây là các phương thức công khai và được bảo vệ; đối với một lớp, chúng là các phương thức instance (không phải singleton). Nếu tham số tùy chọn là false, các phương thức của bất kỳ tổ tiên nào sẽ không được đưa vào. Tôi đang lấy ví dụ tài liệu chính thức.

module A
  def method1()  
    puts "method1 say hi"
  end
end
class B
  include A #mixin
  def method2()  
     puts "method2 say hi"
  end
end
class C < B #inheritance
  def method3() 
     puts "method3 say hi"
  end
end

Hãy xem đầu ra.

A.instance_methods(false)
  => [:method1]

A.instance_methods
  => [:method1]
B.instance_methods
 => [:method2, :method1, :nil?, :===, ...# ] # methods inherited from parent class, most important :method1 is also visible because we mix module A in class B

B.instance_methods(false)
  => [:method2]
C.instance_methods
  => [:method3, :method2, :method1, :nil?, :===, ...#] # same as above
C.instance_methods(false)
 => [:method3]

0

Để chỉ nhận các phương thức của riêng mình và loại trừ các phương thức kế thừa:

Từ trong ví dụ:

self.methods - self.class.superclass.instance_methods

Từ bên ngoài:

TestClass.instance_methods - TestClass.superclass.instance_methods

Thêm nó vào lớp:

class TestClass
  class << self
    def own_methods
      self.instance_methods - self.superclass.instance_methods
    end
  end
end

TestClass.own_methods
=> [:method1, :method2, method3]

(với ruby ​​2,6.x)

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.