【问题标题】:Method to tell if ancestor is a Class or Module in Ruby?判断祖先是Ruby中的类还是模块的方法?
【发布时间】:2011-04-11 05:19:57
【问题描述】:

如果我有一个像下面这样的类,我如何判断祖先是类还是模块?

ActiveRecord::Base.send(:include, SomeLibrary)

class Group < ActiveRecord::Base
  include SomeLibrary::Core
end

class SubGroup < Group

end

ancestor_names = SubGroup.ancestors.map(&:name)
puts ancestor_names.inspect
  #=> [
  "SubGroup", "SomeLibrary::Core::InstanceMethods", "SomeLibrary::Core", 
  "Group", "ActiveRecord::Base", "SomeLibrary", "ActiveRecord::Aggregations", 
  "ActiveRecord::Transactions", "ActiveRecord::Reflection", "ActiveRecord::Batches", 
  "ActiveRecord::Calculations", "ActiveRecord::Serialization", "ActiveRecord::AutosaveAssociation", 
  "ActiveRecord::NestedAttributes", "ActiveRecord::Associations", "ActiveRecord::AssociationPreload", 
  "ActiveRecord::NamedScope", "ActiveRecord::Callbacks", "ActiveRecord::Observing", 
  "ActiveRecord::Timestamp", "ActiveRecord::Dirty", "ActiveRecord::AttributeMethods", 
  "ActiveRecord::Locking::Optimistic", "ActiveRecord::Locking::Pessimistic", 
  "ActiveSupport::Callbacks", "ActiveRecord::Validations", "Object", "Mocha::ObjectMethods", 
  "JSON::Pure::Generator::GeneratorMethods::Object", "ActiveSupport::Dependencies::Loadable", 
  "Base64::Deprecated", "Base64", "PP::ObjectMixin", "Kernel"
]

我希望能够做这样的事情:

ancestor_names.each do |name|
  if class?(name)
    puts "#{name} is a Class"
  elsif module?(name)
    puts "#{name} is a Module"
  end
end

或者...

SubGroup.ancestor_classes #=> only the classes in the tree
SubGroup.ancestor_modules #=> only the modules in the tree

归结为,如何检查对象是类还是模块?

【问题讨论】:

    标签: ruby class module


    【解决方案1】:

    嗯,这就是 included_modules 的用途,所以您可能正在寻找的是:

    SubGroup.included_modules                       #=> module ancestors
    SubGroup.ancestors - SubGroup.included_modules  #=> class ancestors
    

    或者,使用辅助方法:

    class Class
      def ancestor_classes
        ancestors - included_modules
      end
    end
    
    SubGroup.included_modules  #=> module ancestors
    SubGroup.ancestor_classes  #=> class ancestors
    

    【讨论】:

      【解决方案2】:

      使用Object#instance_of?:

      Object.instance_of? Class  # => true
      Object.instance_of? Module # => false
      Kernel.instance_of? Class  # => false
      Kernel.instance_of? Module # => true
      

      【讨论】:

        【解决方案3】:

        以上答案已经足够了。下面的内容也可能会有所帮助。

        pp SubGroup.ancestors.map {|c| c.instance_of?(Class) ? "CLASS: #{c}" : "MODULE: #{c}" }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-19
          • 2019-11-19
          • 1970-01-01
          • 2012-09-22
          • 1970-01-01
          • 1970-01-01
          • 2010-11-24
          • 1970-01-01
          相关资源
          最近更新 更多