2011-02-01 5 views
22

메소드가 상속 또는 포함/확장에 의해 직접 생성되는 것이 아닌 클래스에 직접 정의되어 있는지 어떻게 확인합니까? 나는 'foo'와 같은 것을 원한다. 다음에 : 객체의 경우메서드가 클래스에 정의되어 있는지 확인

class A 
    def a; end 
end 

module B 
    def b; end 
end 

class C < A 
    include B 
    def c; end 
end 

C.foo?(:a) #=> false 
C.foo?(:b) #=> false 
C.foo?(:c) #=> true 

답변

36

사용이 : 방법은이 클래스의 인스턴스가있을 것입니다 방법의 배열을 반환 instance_methods

C.instance_methods(false).include?(:a) 
C.instance_methods(false).include?(:b) 
C.instance_methods(false).include?(:c) 

. 첫 번째 매개 변수로 false을 전달하면이 클래스의 메서드 만 반환되며 수퍼 클래스 메서드는 반환되지 않습니다.

그래서 C.instance_methods(false)C으로 정의 된 메서드 목록을 반환합니다.

그런 다음 해당 메서드가 반환 된 배열에 있는지 확인하면됩니다 (이것은 include? 호출이하는 것입니다).

See docs

+0

이것은 또한 모든 경우에 해당됩니다. – sawa

+0

방금 ​​답변을 업데이트했습니다. C로 정의 된 메서드 만 반환하려면 instance_methods의 첫 번째 매개 변수를 false로 설정하면됩니다. – arnaud576875

+0

알았습니다. 나는 그 방법을 알고 있었지만 그러한 매개 변수를 취했다는 것을 알지 못했습니다. 감사. – sawa

24

당신은 Object.respond_to?를 사용할 수 있습니다.

obj가 주어진 메소드에 응답하면 true를 리턴합니다. 클래스에 대한

Module.instance_methods

수신기에서 공공 및 보호 인스턴스 메소드의 이름을 포함하고있는 배열을 돌려줍니다 좀 봐.

+0

이것은 주어진 클래스의 인스턴스에서만 작동합니다 :-) – arnaud576875

+0

C.new.foo? (:a), C.new.foo?(:b), C.new. foo? (: c) – sawa

+4

클래스들 *은 * 객체이기 때문에'respond_to? '도 그것들에서 동작합니다. – bfontaine

0
정확히

아니 질문에 대한 답변,하지만 당신은이 질문을 읽고, 당신이에 관심이있을 수는, 예를 들어 .instance_methods(false)

class Object 
    # This is more or less how Ruby does method lookup internally 
    def who_responds_to?(method, klass_ancestors = nil) 
    if klass_ancestors.nil? 
     return who_responds_to?(method, self.class.ancestors) 
    end 

    if klass_ancestors.empty? 
     return nil 
    end 

    if klass_ancestors[0].instance_methods(false).include?(method) 
     return klass_ancestors[0] 
    end 

    klass_ancestors.shift 

    who_responds_to?(method, klass_ancestors) 
    end 
end 

사용하는

class Person 
end 

module Drummer 
    def drum 
    end 
end 

module Snowboarder 
    def jump 
    end 
end 

module Engineer 
    def code 
    end 
end 

class Bob < Person 
    include Drummer 
    include Snowboarder 
    include Engineer 

    def name 
    end 
end 

puts "who responds to name" 
puts bob.who_responds_to?(:name) 
puts "\n" 

puts "who responds to code" 
puts bob.who_responds_to?(:code) 
puts "\n" 

puts "who responds to jump" 
puts bob.who_responds_to?(:jump) 
puts "\n" 

puts "who responds to drum" 
puts bob.who_responds_to?(:drum) 
puts "\n" 

puts "who responds to dance" 
puts bob.who_responds_to?(:dance) 

수율

who responds to name 
Bob 

who responds to code 
Engineer 

who responds to jump 
Snowboarder 

who responds to drum 
Drummer 

who responds to dance 
[this line intentionally blank because return value is nil] 
관련 문제