方法来判断在Ruby中,祖是类还是模块?

时间:2023-01-15 18:46:59

If I have a class like the following, how do I tell when an ancestor is a class vs. a module?

如果我有一个类,如下面所示,如何判断祖先是类还是模块?

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"
]

I would like to be able to do something like this:

我想做这样的事情:

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

or...

还是……

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

It boils down to, how do you check if an object is a class or module?

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

2 个解决方案

#1


13  

Well, that is what included_modules is for, so what you're probably looking for is:

这就是included_modules的目的,所以你可能想要的是:

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

Or, with a helper method:

或者,使用辅助方法:

class Class
  def ancestor_classes
    ancestors - included_modules
  end
end

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

#2


10  

Use Object#instance_of?:

使用对象# instance_of ?:

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

#1


13  

Well, that is what included_modules is for, so what you're probably looking for is:

这就是included_modules的目的,所以你可能想要的是:

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

Or, with a helper method:

或者,使用辅助方法:

class Class
  def ancestor_classes
    ancestors - included_modules
  end
end

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

#2


10  

Use Object#instance_of?:

使用对象# instance_of ?:

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