2015-02-23 20 views
12

Buradaki soruyu genişletmek için (ruby/rails: extending or including other modules), mevcut çözümümün kullanılmasıyla, modülümün dahil olup olmadığını belirlemenin en iyi yolu nedir?ruby ​​/ raylar: Modülün dahil olup olmadığı nasıl belirlenir?

Şimdilik yaptığım şey, her bir modülde örnek yöntemlerin tanımlanmasıydı, böylece bir yöntemin dahil edilmesini sağladıkları zaman, ve daha sonra üst modüle bir alıcı (method_missing()) ekledim. dahil.

# Sample models 
class Man < ActiveRecord::Base 
    # Include features modules 
    include Features 

    # Define what man can do 
    can_walk 
    can_run 
end 

class Car < ActiveRecord::Base 
    # Include features modules 
    include Features 

    # Define what man can do 
    can_run 
end 

Sonra

Man.new.can_walk? 
# => true 
Car.new.can_run? 
# => true 
Car.new.can_walk? # method_missing catches this 
# => false 

bunu doğru yazdınız edebilirsiniz: my modellerinde Yani

module Features 
    FEATURES = [Running, Walking] 

    # include Features::Running 
    FEATURES.each do |feature| 
    include feature 
    end 

    module ClassMethods 
    # include Features::Running::ClassMethods 
    FEATURES.each do |feature| 
     include feature::ClassMethods 
    end 
    end 

    module InstanceMethods 
    def method_missing(meth) 
     # Catch feature checks that are not included in models to return false 
     if meth[-1] == '?' && meth.to_s =~ /can_(\w+)\z?/ 
     false 
     else 
     # You *must* call super if you don't handle the method, 
     # otherwise you'll mess up Ruby's method lookup 
     super 
     end 
    end 
    end 

    def self.included(base) 
    base.send :extend, ClassMethods 
    base.send :include, InstanceMethods 
    end 
end 

# lib/features/running.rb 
module Features::Running 
    module ClassMethods 
    def can_run 
     ... 

     # Define a method to have model know a way they have that feature 
     define_method(:can_run?) { true } 
    end 
    end 
end 

# lib/features/walking.rb 
module Features::Walking 
    module ClassMethods 
    def can_walk 
     ... 

     # Define a method to have model know a way they have that feature 
     define_method(:can_walk?) { true } 
    end 
    end 
end 

Ben: Benim çözümüm kodu benziyor? Yoksa daha iyi bir yolu var mı?

+1

soru biraz dolambaçlı, bu nedenle bu kontrol etmek ama aradığınızı olup olmadığından emin değilim Bir model dahil edilirse, 'object.class.include? Modül ' – makhan

+0

Bir yöntemin mevcut olup olmadığını kontrol etmek için' response_to? 'Kullanabilirsiniz. – Lesleh

cevap

29

Sorunuzu doğru anlamak, bunu yapabilirsiniz: Örneğin

Man.included_modules.include?(Features)? 

: @ gibi

:

module M 
end 

class C 
    include M 
end 

C.included_modules.include?(M) 
    #=> true 

diğer yolları

C.included_modules 
    #=> [M, Kernel] 

olarak Markan sözü:

C.include? M 
    #=> true 

ya:

C.ancestors.include?(M) 
    #=> true 

ya da sadece:

C < M 
    #=> true 
+0

"C makhan

+0

@makhan, bu yöntem [Modül # <] (http://ruby-doc.org//core-2.2.0/Module.html#method-i-3C). Russ Olsen gelen –

+0

@makhan "Eloquent Ruby" Ruby idomların güzel (ve qiet kapsamlı) bir bakış. – TNT

İlgili konular