2011-02-01 31 views
22

sınıfında tanımlanıp ayarlanmadığını kontrol etme Bir yöntemin miras yoluyla değil mi yoksa ek/uzantı ile değil, doğrudan bir sınıfta mı tanımlandığını nasıl kontrol ederim? 'Foo' gibi bir şey istiyorum? aşağıda: nesneler içinBir yöntemin

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 

cevap

36

bunu kullanın: yöntem bu sınıfının bir örneği olurdu yöntemlerin Array iade instance_methods

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

. false'u ilk parametre olarak geçmek, yalnızca bu sınıfın yöntemlerini döndürür, süper sınıf yöntemleri değil.

C.instance_methods(false)C tarafından tanımlanan yöntemlerin listesini döndürür.

Ardından, bu yöntemin döndürülen Dizilim içinde olup olmadığını kontrol etmeniz gerekir (bu, include? çağrılarının yaptığı şeydir).

See docs

+0

Bu, tüm vakalara da geçerlidir. – sawa

+0

sadece cevabı güncelledi; Sadece, yalnızca, C. – arnaud576875

+0

tarafından tanımlanan yöntemleri döndürmek için, example_methods öğesinin ilk parametresini ayarlamak zorundasınız. Bu yöntemi biliyordum ama böyle bir parametre aldığını bilmiyordum. Teşekkürler. – sawa

24

sen Object.respond_to? kullanabilirsiniz.

Belirtilen yönteme, obj yanıt verdiğinde true döndürür. sınıfları için

Module.instance_methods

alıcıda ortak ve korunmuş örnek yöntemleri adlarını içeren bir dizi döner bakabilirsiniz.

+0

Bu, yalnızca verilen sınıfların örneklerinde çalışacaktır :-) – arnaud576875

+0

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

+4

Ayrıca * sınıflarının * nesneler olduğunu, bu nedenle de response_to? 'nun da çalıştığını unutmayın. – bfontaine

0
tam

Değil soruya bir cevap ama bu soruyu okuyorsanız, bu ilginizi çekebilir Örneğin .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 

kullandığı

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) 

verir

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] 
İlgili konular