class RDoc::ClassModule - rdoc: Ruby Standard Library Documentation

# class RDoc::ClassModule

`ClassModule` is the base class for objects representing either a class or a module.

### Attributes

comment_location[RW]

Comment and the location it came from. Use `add_comment` to add comments

constant_aliases[RW]

Constants that are aliases for this class or module

is_alias_for[RW]

Class or module this constant is an alias for

### Public Class Methods

from_module(class_type, mod) click to toggle source

Return a `RDoc::ClassModule` of class `class_type` that is a copy of module `module`. Used to promote modules to classes.

    # File rdoc/code_object/class_module.rb, line 50
    def self.from_module class_type, mod
      klass = class_type.new mod.name

      mod.comment_location.each do |comment, location|
        klass.add_comment comment, location
      end

      klass.parent = mod.parent
      klass.section = mod.section
      klass.viewer = mod.viewer

      klass.attributes.concat mod.attributes
      klass.method_list.concat mod.method_list
      klass.aliases.concat mod.aliases
      klass.external_aliases.concat mod.external_aliases
      klass.constants.concat mod.constants
      klass.includes.concat mod.includes
      klass.extends.concat mod.extends

      klass.methods_hash.update mod.methods_hash
      klass.constants_hash.update mod.constants_hash

      klass.current_section = mod.current_section
      klass.in_files.concat mod.in_files
      klass.sections.concat mod.sections
      klass.unmatched_alias_lists = mod.unmatched_alias_lists
      klass.current_section = mod.current_section
      klass.visibility = mod.visibility

      klass.classes_hash.update mod.classes_hash
      klass.modules_hash.update mod.modules_hash
      klass.metadata.update mod.metadata

      klass.document_self = mod.received_nodoc ? nil : mod.document_self
      klass.document_children = mod.document_children
      klass.force_documentation = mod.force_documentation
      klass.done_documenting = mod.done_documenting

      # update the parent of all children

      (klass.attributes +
       klass.method_list +
       klass.aliases +
       klass.external_aliases +
       klass.constants +
       klass.includes +
       klass.extends +
       klass.classes +
       klass.modules).each do |obj|
        obj.parent = klass
        obj.full_name = nil
      end

      klass
    end

new(name, superclass = nil) click to toggle source

Creates a new `ClassModule` with `name` with optional `superclass`

This is a constructor for subclasses, and must never be called directly.

Calls superclass method `RDoc::Context::new`

    # File rdoc/code_object/class_module.rb, line 111
    def initialize(name, superclass = nil)
      @constant_aliases = []
      @diagram          = nil
      @is_alias_for     = nil
      @name             = name
      @superclass       = superclass
      @comment_location = [] # [[comment, location]]

      super()
    end

### Public Instance Methods

add_comment(comment, location) click to toggle source

Adds `comment` to this ClassModule’s list of comments at `location`. This method is preferred over `comment=` since it allows ri data to be updated across multiple runs.

    # File rdoc/code_object/class_module.rb, line 127
    def add_comment comment, location
      return unless document_self

      original = comment

      comment = case comment
                when RDoc::Comment then
                  comment.normalize
                else
                  normalize_comment comment
                end

      if location.parser == RDoc::Parser::C
        @comment_location.delete_if { |(_, l)| l == location }
      end

      @comment_location << [comment, location]

      self.comment = original
    end

ancestors() click to toggle source

Ancestors list for this ClassModule: the list of included modules (classes will add their superclass if any).

Returns the included classes or modules, not the includes themselves. The returned values are either String or `RDoc::NormalModule` instances (see `RDoc::Include#module`).

The values are returned in reverse order of their inclusion, which is the order suitable for searching methods/attributes in the ancestors. The superclass, if any, comes last.

    # File rdoc/code_object/class_module.rb, line 171
    def ancestors
      includes.map { |i| i.module }.reverse
    end

Also aliased as: direct_ancestors
aref() click to toggle source

HTML fragment reference for this module or class. See `RDoc::NormalClass#aref` and `RDoc::NormalModule#aref`

    # File rdoc/code_object/class_module.rb, line 183
    def aref
      "#{aref_prefix}-#{full_name}"
    end

clear_comment() click to toggle source

Clears the comment. Used by the Ruby parser.

    # File rdoc/code_object/class_module.rb, line 195
    def clear_comment
      @comment = ''
    end

complete(min_visibility) click to toggle source

Prepares this `ClassModule` for use by a generator.

See `RDoc::Store#complete`

    # File rdoc/code_object/class_module.rb, line 223
    def complete min_visibility
      update_aliases
      remove_nodoc_children
      embed_mixins
      update_includes
      remove_invisible min_visibility
    end

description() click to toggle source

Handy wrapper for marking up this class or module’s comment

    # File rdoc/generator/markup.rb, line 131
    def description
      markup @comment_location
    end

direct_ancestors()

Ancestors of this class or module only

Alias for: ancestors
document_self_or_methods() click to toggle source

Does this `ClassModule` or any of its methods have document_self set?

    # File rdoc/code_object/class_module.rb, line 234
    def document_self_or_methods
      document_self || method_list.any?{ |m| m.document_self }
    end

documented?() click to toggle source

Does this class or module have a comment with content or is `received_nodoc` true?

    # File rdoc/code_object/class_module.rb, line 242
    def documented?
      return true if @received_nodoc
      return false if @comment_location.empty?
      @comment_location.any? { |comment, _| not comment.empty? }
    end

each_ancestor() { |module| ... } click to toggle source

Iterates the ancestors of this class or module for which an `RDoc::ClassModule` exists.

    # File rdoc/code_object/class_module.rb, line 252
    def each_ancestor # :yields: module
      return enum_for __method__ unless block_given?

      ancestors.each do |mod|
        next if String === mod
        next if self == mod
        yield mod
      end
    end

embed_mixins() click to toggle source

    # File rdoc/code_object/class_module.rb, line 829
    def embed_mixins
      return unless options.embed_mixins

      includes.each do |include|
        next if String === include.module
        include.module.method_list.each do |code_object|
          add_method(prepare_to_embed(code_object))
        end
        include.module.constants.each do |code_object|
          add_constant(prepare_to_embed(code_object))
        end
        include.module.attributes.each do |code_object|
          add_attribute(prepare_to_embed(code_object))
        end
      end

      extends.each do |ext|
        next if String === ext.module
        ext.module.method_list.each do |code_object|
          add_method(prepare_to_embed(code_object, true))
        end
        ext.module.attributes.each do |code_object|
          add_attribute(prepare_to_embed(code_object, true))
        end
      end
    end

find_ancestor_local_symbol(symbol) click to toggle source

Looks for a symbol in the `ancestors`. See Context#find_local_symbol.

    # File rdoc/code_object/class_module.rb, line 265
    def find_ancestor_local_symbol symbol
      each_ancestor do |m|
        res = m.find_local_symbol(symbol)
        return res if res
      end

      nil
    end

find_class_named(name) click to toggle source

Finds a class or module with `name` in this namespace or its descendants

    # File rdoc/code_object/class_module.rb, line 277
    def find_class_named name
      return self if full_name == name
      return self if @name == name

      @classes.values.find do |klass|
        next if klass == self
        klass.find_class_named name
      end
    end

full_name() click to toggle source

Return the fully qualified name of this class or module

    # File rdoc/code_object/class_module.rb, line 290
    def full_name
      @full_name ||= if RDoc::ClassModule === parent then
                       "#{parent.full_name}::#{@name}"
                     else
                       @name
                     end
    end

merge(class_module) click to toggle source

Merges `class_module` into this `ClassModule`.

The data in `class_module` is preferred over the receiver.

    # File rdoc/code_object/class_module.rb, line 436
    def merge class_module
      @parent      = class_module.parent
      @parent_name = class_module.parent_name

      other_document = parse class_module.comment_location

      if other_document then
        document = parse @comment_location

        document = document.merge other_document

        @comment = @comment_location = document
      end

      cm = class_module
      other_files = cm.in_files

      merge_collections attributes, cm.attributes, other_files do |add, attr|
        if add then
          add_attribute attr
        else
          @attributes.delete attr
          @methods_hash.delete attr.pretty_name
        end
      end

      merge_collections constants, cm.constants, other_files do |add, const|
        if add then
          add_constant const
        else
          @constants.delete const
          @constants_hash.delete const.name
        end
      end

      merge_collections includes, cm.includes, other_files do |add, incl|
        if add then
          add_include incl
        else
          @includes.delete incl
        end
      end

      @includes.uniq! # clean up

      merge_collections extends, cm.extends, other_files do |add, ext|
        if add then
          add_extend ext
        else
          @extends.delete ext
        end
      end

      @extends.uniq! # clean up

      merge_collections method_list, cm.method_list, other_files do |add, meth|
        if add then
          add_method meth
        else
          @method_list.delete meth
          @methods_hash.delete meth.pretty_name
        end
      end

      merge_sections cm

      self
    end

module?() click to toggle source

Does this object represent a module?

    # File rdoc/code_object/class_module.rb, line 571
    def module?
      false
    end

name=(new_name) click to toggle source

Allows overriding the initial name.

Used for modules and classes that are constant aliases.

    # File rdoc/code_object/class_module.rb, line 580
    def name= new_name
      @name = new_name
    end

name_for_path() click to toggle source

Name to use to generate the url: modules and classes that are aliases for another module or class return the name of the latter.

    # File rdoc/code_object/class_module.rb, line 623
    def name_for_path
      is_alias_for ? is_alias_for.full_name : full_name
    end

non_aliases() click to toggle source

Returns the classes and modules that are not constants aliasing another class or module. For use by formatters only (caches its result).

    # File rdoc/code_object/class_module.rb, line 632
    def non_aliases
      @non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for }
    end

parse(comment_location) click to toggle source

Parses `comment_location` into an `RDoc::Markup::Document` composed of multiple RDoc::Markup::Documents with their file set.

Calls superclass method `RDoc::Text#parse`

    # File rdoc/code_object/class_module.rb, line 588
    def parse comment_location
      case comment_location
      when String then
        super
      when Array then
        docs = comment_location.map do |comment, location|
          doc = super comment
          doc.file = location
          doc
        end

        RDoc::Markup::Document.new(*docs)
      when RDoc::Comment then
        doc = super comment_location.text, comment_location.format
        doc.file = comment_location.location
        doc
      when RDoc::Markup::Document then
        return comment_location
      else
        raise ArgumentError, "unknown comment class #{comment_location.class}"
      end
    end

path() click to toggle source

Path to this class or module for use with HTML generator output.

    # File rdoc/code_object/class_module.rb, line 614
    def path
      http_url @store.rdoc.generator.class_dir
    end

remove_nodoc_children() click to toggle source

Updates the child modules or classes of class/module `parent` by deleting the ones that have been removed from the documentation.

`parent_hash` is either `parent.modules_hash` or `parent.classes_hash` and `all_hash` is ::all_modules_hash or ::all_classes_hash.

    # File rdoc/code_object/class_module.rb, line 644
    def remove_nodoc_children
      prefix = self.full_name + '::'

      modules_hash.each_key do |name|
        full_name = prefix + name
        modules_hash.delete name unless @store.modules_hash[full_name]
      end

      classes_hash.each_key do |name|
        full_name = prefix + name
        classes_hash.delete name unless @store.classes_hash[full_name]
      end
    end

search_record() click to toggle source

Search record used by `RDoc::Generator::JsonIndex`

    # File rdoc/code_object/class_module.rb, line 673
    def search_record
      [
        name,
        full_name,
        full_name,
        '',
        path,
        '',
        snippet(@comment_location),
      ]
    end

store=(store) click to toggle source

Sets the store for this class or module and its contained code objects.

Calls superclass method `RDoc::CodeObject#store=`

    # File rdoc/code_object/class_module.rb, line 688
    def store= store
      super

      @attributes .each do |attr|  attr.store  = store end
      @constants  .each do |const| const.store = store end
      @includes   .each do |incl|  incl.store  = store end
      @extends    .each do |ext|   ext.store   = store end
      @method_list.each do |meth|  meth.store  = store end
    end

super_classes() click to toggle source

Get all super classes of this class in an array. The last element might be a string if the name is unknown.

    # File rdoc/code_object/class_module.rb, line 731
    def super_classes
      result = []
      parent = self
      while parent = parent.superclass
        result << parent
        return result if parent.is_a?(String)
      end
      result
    end

superclass() click to toggle source

Get the superclass of this class. Attempts to retrieve the superclass object, returns the name if it is not known.

    # File rdoc/code_object/class_module.rb, line 702
    def superclass
      @store.find_class_named(@superclass) || @superclass
    end

superclass=(superclass) click to toggle source

Set the superclass of this class to `superclass`

where `superclass` is one of:

- `nil`

- a String containing the full name of the superclass

- the `RDoc::ClassModule` representing the superclass

    # File rdoc/code_object/class_module.rb, line 715
    def superclass=(superclass)
      raise NoMethodError, "#{full_name} is a module" if module?
      case superclass
      when RDoc::ClassModule
        @superclass = superclass.full_name
      when nil, String
        @superclass = superclass
      else
        raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}"
      end
    end

type() click to toggle source

‘module’ or ‘class’

    # File rdoc/code_object/class_module.rb, line 752
    def type
      module? ? 'module' : 'class'
    end

update_aliases() click to toggle source

Updates the child modules & classes by replacing the ones that are aliases through a constant.

The aliased module/class is replaced in the children and in `RDoc::Store#modules_hash` or `RDoc::Store#classes_hash` by a copy that has `RDoc::ClassModule#is_alias_for` set to the aliased module/class, and this copy is added to `#aliases` of the aliased module/class.

Formatters can use the `non_aliases` method to retrieve children that are not aliases, for instance to list the namespace content, since the aliased modules are included in the constants of the class/module, that are listed separately.

    # File rdoc/code_object/class_module.rb, line 771
    def update_aliases
      constants.each do |const|
        next unless cm = const.is_alias_for
        cm_alias = cm.dup
        cm_alias.name = const.name

        # Don't move top-level aliases under Object, they look ugly there
        unless RDoc::TopLevel === cm_alias.parent then
          cm_alias.parent = self
          cm_alias.full_name = nil # force update for new parent
        end

        cm_alias.aliases.clear
        cm_alias.is_alias_for = cm

        if cm.module? then
          @store.modules_hash[cm_alias.full_name] = cm_alias
          modules_hash[const.name] = cm_alias
        else
          @store.classes_hash[cm_alias.full_name] = cm_alias
          classes_hash[const.name] = cm_alias
        end

        cm.aliases << cm_alias
      end
    end

update_extends() click to toggle source

Deletes from `extends` those whose module has been removed from the documentation.

    # File rdoc/code_object/class_module.rb, line 819
    def update_extends
      extends.reject! do |ext|
        mod = ext.module

        !(String === mod) && @store.modules_hash[mod.full_name].nil?
      end

      extends.uniq!
    end

update_includes() click to toggle source

Deletes from `includes` those whose module has been removed from the documentation.

    # File rdoc/code_object/class_module.rb, line 804
    def update_includes
      includes.reject! do |include|
        mod = include.module
        !(String === mod) && @store.modules_hash[mod.full_name].nil?
      end

      includes.uniq!
    end

### Private Instance Methods

prepare_to_embed(code_object, singleton=false) click to toggle source

    # File rdoc/code_object/class_module.rb, line 858
    def prepare_to_embed(code_object, singleton=false)
      code_object = code_object.dup
      code_object.mixin_from = code_object.parent
      code_object.singleton = true if singleton
      set_current_section(code_object.section.title, code_object.section.comment)
      # add_method and add_attribute will reassign self's visibility back to the method/attribute
      # so we need to sync self's visibility with the object's to properly retain that information
      self.visibility = code_object.visibility
      code_object
    end