簡體   English   中英

ruby/rails:如何確定是否包含模塊?

[英]ruby/rails: How to determine if module is included?

在這里擴展我的問題( ruby/rails:擴展或包含其他模塊),使用我現有的解決方案,確定是否包含我的模塊的最佳方法是什么?

我現在所做的是在每個模塊上定義實例方法,這樣當它們被包含時,一個方法將可用,然后我只是向父模塊添加了一個捕獲器( method_missing() ),這樣我就可以捕獲它們是否不包含。 我的解決方案代碼如下:

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

所以在我的模型中,我有:

# 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

然后我可以

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

我寫的對嗎? 或者,還有更好的方法?

如果我正確理解您的問題,您可以使用Module#include?

Man.include?(Features)

例如:

module M
end

class C
  include M
end

C.include?(M) # => true

其他方法

檢查Module#included_modules

這是有效的,但它有點間接,因為它生成中間的included_modules數組。

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

因為C.included_modules的值為[M, Kernel]

檢查Module#ancestors

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

因為C.ancestors的值為[C, M, Object, Kernel, BasicObject]

使用像<

Module類還聲明了幾個比較運算符:

例子:

C < M # => true 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM