class YARD::CodeObjects::Base

Base is the superclass of all code objects recognized by YARD. A code object is any entity in the Ruby language (class, method, module). A DSL might subclass Base to create a new custom object representing a new entity type.

Registry Integration

Any created object associated with a namespace is immediately registered with the registry. This allows the Registry to act as an identity map to ensure that no object is represented by more than one Ruby object in memory. A unique {#path} is essential for this identity map to work correctly.

Custom Attributes

Code objects allow arbitrary custom attributes to be set using the {#[]=} assignment method.

Namespaces

There is a special type of object called a “namespace”. These are subclasses of the {NamespaceObject} and represent Ruby entities that can have objects defined within them. Classically these are modules and classes, though a DSL might create a custom {NamespaceObject} to describe a specific set of objects.

Separators

Custom classes with different separator tokens should define their own separators using the {NamespaceMapper.register_separator} method. The standard Ruby separators have already been defined ('::', '#', '.', etc).

@abstract This class should not be used directly. Instead, create a

subclass that implements {#path}, {#sep} or {#type}. You might also
need to register custom separators if {#sep} uses alternate separator
tokens.

@see Registry @see path @see []= @see NamespaceObject @see NamespaceMapper.register_separator

Attributes

base_docstring[R]

The non-localized documentation string associated with the object @return [Docstring] the documentation string @since 0.8.4

dynamic[RW]

Marks whether or not the method is conditionally defined at runtime @return [Boolean] true if the method is conditionally defined at runtime

files[R]

The files the object was defined in. To add a file, use {#add_file}. @return [Array<String>] a list of files @see add_file

group[RW]

@return [String] the group this object is associated with @since 0.6.0

namespace[R]

The namespace the object is defined in. If the object is in the top level namespace, this is {Registry.root} @return [NamespaceObject] the namespace object

parent[R]

The namespace the object is defined in. If the object is in the top level namespace, this is {Registry.root} @return [NamespaceObject] the namespace object

signature[RW]

The one line signature representing an object. For a method, this will be of the form “def meth(arguments…)”. This is usually the first source line.

@return [String] a line of source

source[R]

The source code associated with the object @return [String, nil] source, if present, or nil

source_type[RW]

Language of the source code associated with the object. Defaults to :ruby.

@return [Symbol] the language type

visibility[RW]

@return [Symbol] the visibility of an object (:public, :private, :protected)

Public Class Methods

===(other) click to toggle source

Compares the class with subclasses

@param [Object] other the other object to compare classes with @return [Boolean] true if other is a subclass of self

# File lib/yard/code_objects/base.rb, line 215
def ===(other)
  other.is_a?(self)
end
new(namespace, name, *args) { |obj| ... } click to toggle source

Allocates a new code object @return [Base] @see initialize

Calls superclass method
# File lib/yard/code_objects/base.rb, line 189
def new(namespace, name, *args, &block)
  raise ArgumentError, "invalid empty object name" if name.to_s.empty?
  if namespace.is_a?(ConstantObject)
    namespace = Proxy.new(namespace.namespace, namespace.value)
  end

  if name.to_s[0, 2] == NSEP
    name = name.to_s[2..-1]
    namespace = Registry.root
  end

  if name =~ /(?:#{NSEPQ})([^:]+)$/
    return new(Proxy.new(namespace, $`), $1, *args, &block)
  end

  obj = super(namespace, name, *args)
  existing_obj = Registry.at(obj.path)
  obj = existing_obj if existing_obj && existing_obj.class == self
  yield(obj) if block_given?
  obj
end
new(namespace, name, *) { |self| ... } click to toggle source

Creates a new code object

@example Create a method in the root namespace

CodeObjects::Base.new(:root, '#method') # => #<yardoc method #method>

@example Create class Z inside namespace X::Y

CodeObjects::Base.new(P("X::Y"), :Z) # or
CodeObjects::Base.new(Registry.root, "X::Y")

@param [NamespaceObject] namespace the namespace the object belongs in,

{Registry.root} or :root should be provided if it is associated with
the top level namespace.

@param [Symbol, String] name the name (or complex path) of the object. @yield [self] a block to perform any extra initialization on the object @yieldparam [Base] self the newly initialized code object @return [Base] the newly created object

# File lib/yard/code_objects/base.rb, line 234
def initialize(namespace, name, *)
  if namespace && namespace != :root &&
     !namespace.is_a?(NamespaceObject) && !namespace.is_a?(Proxy)
    raise ArgumentError, "Invalid namespace object: #{namespace}"
  end

  @files = []
  @current_file_has_comments = false
  @name = name.to_sym
  @source_type = :ruby
  @visibility = :public
  @tags = []
  @docstrings = {}
  @docstring = Docstring.new!('', [], self)
  @namespace = nil
  self.namespace = namespace
  yield(self) if block_given?
end

Public Instance Methods

==(other)
Alias for: equal?
[](key) click to toggle source

Accesses a custom attribute on the object @param [#to_s] key the name of the custom attribute @return [Object, nil] the custom attribute or nil if not found. @see []=

# File lib/yard/code_objects/base.rb, line 338
def [](key)
  if respond_to?(key)
    send(key)
  elsif instance_variable_defined?("@#{key}")
    instance_variable_get("@#{key}")
  end
end
[]=(key, value) click to toggle source

Sets a custom attribute on the object @param [#to_s] key the name of the custom attribute @param [Object] value the value to associate @return [void] @see []

# File lib/yard/code_objects/base.rb, line 351
def []=(key, value)
  if respond_to?("#{key}=")
    send("#{key}=", value)
  else
    instance_variable_set("@#{key}", value)
  end
end
add_file(file, line = nil, has_comments = false) click to toggle source

Associates a file with a code object, optionally adding the line where it was defined. By convention, '<stdin>' should be used to associate code that comes form standard input.

@param [String] file the filename ('<stdin>' for standard input) @param [Fixnum, nil] line the line number where the object lies in the file @param [Boolean] has_comments whether or not the definition has comments associated. This

will allow {#file} to return the definition where the comments were made instead
of any empty definitions that might have been parsed before (module namespaces for instance).
# File lib/yard/code_objects/base.rb, line 286
def add_file(file, line = nil, has_comments = false)
  raise(ArgumentError, "file cannot be nil or empty") if file.nil? || file == ''
  obj = [file.to_s, line]
  return if files.include?(obj)
  if has_comments && !@current_file_has_comments
    @current_file_has_comments = true
    @files.unshift(obj)
  else
    @files << obj # back of the line
  end
end
add_tag(*tags) click to toggle source

Add tags to the {#docstring} @see Docstring#add_tag @since 0.8.4

# File lib/yard/code_objects/base.rb, line 545
def add_tag(*tags)
  @docstrings.clear
  @docstring.add_tag(*tags)
end
copy_to(other) click to toggle source

Copies all data in this object to another code object, except for uniquely identifying information (path, namespace, name, scope).

@param [Base] other the object to copy data to @return [Base] the other object @since 0.8.0

# File lib/yard/code_objects/base.rb, line 259
def copy_to(other)
  copyable_attributes.each do |ivar|
    ivar = "@#{ivar}"
    other.instance_variable_set(ivar, instance_variable_get(ivar))
  end
  other.docstring = @docstring.to_raw
  other
end
docstring(locale = I18n::Locale.default) click to toggle source

The documentation string associated with the object

@param [String, I18n::Locale] locale (I18n::Locale.default)

the locale of the documentation string.

@return [Docstring] the documentation string

# File lib/yard/code_objects/base.rb, line 397
def docstring(locale = I18n::Locale.default)
  if locale.nil?
    @docstring.resolve_reference
    return @docstring
  end

  if locale.is_a?(String)
    locale_name = locale
    locale = nil
  else
    locale_name = locale.name
  end
  @docstrings[locale_name] ||=
    translate_docstring(locale || Registry.locale(locale_name))
end
docstring=(comments) click to toggle source

Attaches a docstring to a code object by parsing the comments attached to the statement and filling the {#tags} and {#docstring} methods with the parsed information.

@param [String, Array<String>, Docstring] comments

the comments attached to the code object to be parsed
into a docstring and meta tags.
# File lib/yard/code_objects/base.rb, line 419
def docstring=(comments)
  @docstrings.clear
  @docstring = Docstring === comments ?
    comments : Docstring.new(comments, self)
end
dynamic?() click to toggle source

Is the object defined conditionally at runtime? @see dynamic

# File lib/yard/code_objects/base.rb, line 178
def dynamic?; @dynamic end
eql?(other)
Alias for: equal?
equal?(other) click to toggle source

Tests if another object is equal to this, including a proxy @param [Base, Proxy] other if other is a {Proxy}, tests if

the paths are equal

@return [Boolean] whether or not the objects are considered the same

Calls superclass method
# File lib/yard/code_objects/base.rb, line 318
def equal?(other)
  if other.is_a?(Base) || other.is_a?(Proxy)
    path == other.path
  else
    super
  end
end
Also aliased as: ==, eql?
file() click to toggle source

Returns the filename the object was first parsed at, taking definitions with docstrings first.

@return [String] a filename

# File lib/yard/code_objects/base.rb, line 302
def file
  @files.first ? @files.first[0] : nil
end
format(options = {}) click to toggle source

Renders the object using the {Templates::Engine templating system}.

@example Formats a class in plaintext

puts P('MyClass').format

@example Formats a method in html with rdoc markup

puts P('MyClass#meth').format(:format => :html, :markup => :rdoc)

@param [Hash] options a set of options to pass to the template @option options [Symbol] :format (:text) :html, :text or another output format @option options [Symbol] :template (:default) a specific template to use @option options [Symbol] :markup (nil) the markup type (:rdoc, :markdown, :textile) @option options [Serializers::Base] :serializer (nil) see Serializers @return [String] the rendered template @see Templates::Engine#render

# File lib/yard/code_objects/base.rb, line 494
def format(options = {})
  options = options.merge(:object => self)
  options = options.merge(:type => type) unless options[:type]
  Templates::Engine.render(options)
end
has_tag?(name) click to toggle source

Tests if the {#docstring} has a tag @see Docstring#has_tag?

# File lib/yard/code_objects/base.rb, line 540
def has_tag?(name); docstring.has_tag?(name) end
hash() click to toggle source

@return [Integer] the object's hash value (for equality checking)

# File lib/yard/code_objects/base.rb, line 329
def hash; path.hash end
inspect() click to toggle source

Inspects the object, returning the type and path @return [String] a string describing the object

# File lib/yard/code_objects/base.rb, line 502
def inspect
  "#<yardoc #{type} #{path}>"
end
line() click to toggle source

Returns the line the object was first parsed at (or nil)

@return [Fixnum] the line where the object was first defined. @return [nil] if there is no line associated with the object

# File lib/yard/code_objects/base.rb, line 310
def line
  @files.first ? @files.first[1] : nil
end
method_missing(meth, *args, &block) click to toggle source

@overload dynamic_attr_name

@return the value of attribute named by the method attribute name
@raise [NoMethodError] if no method or custom attribute exists by
  the attribute name
@see #[]

@overload dynamic_attr_name=(value)

@param value a value to set
@return +value+
@see #[]=
Calls superclass method
# File lib/yard/code_objects/base.rb, line 368
def method_missing(meth, *args, &block)
  if meth.to_s =~ /=$/
    self[meth.to_s[0..-2]] = args.first
  elsif instance_variable_get("@#{meth}")
    self[meth]
  else
    super
  end
end
name(prefix = false) click to toggle source

The name of the object @param [Boolean] prefix whether to show a prefix. Implement

this in a subclass to define how the prefix is showed.

@return [Symbol] if prefix is false, the symbolized name @return [String] if prefix is true, prefix + the name as a String.

This must be implemented by the subclass.
# File lib/yard/code_objects/base.rb, line 274
def name(prefix = false)
  prefix ? @name.to_s : (defined?(@name) && @name)
end
namespace=(obj) click to toggle source

Sets the namespace the object is defined in.

@param [NamespaceObject, :root, nil] obj the new namespace (:root

for {Registry.root}). If obj is nil, the object is unregistered
from the Registry.
# File lib/yard/code_objects/base.rb, line 511
def namespace=(obj)
  if @namespace
    @namespace.children.delete(self)
    Registry.delete(self)
  end

  @namespace = (obj == :root ? Registry.root : obj)

  if @namespace
    reg_obj = Registry.at(path)
    return if reg_obj && reg_obj.class == self.class
    @namespace.children << self unless @namespace.is_a?(Proxy)
    Registry.register(self)
  end
end
Also aliased as: parent=
parent=(obj)
Alias for: namespace=
path() click to toggle source

Represents the unique path of the object. The default implementation joins the path of {#namespace} with {#name} via the value of {#sep}. Custom code objects should ensure that the path is unique to the code object by either overriding {#sep} or this method.

@example The path of an instance method

MethodObject.new(P("A::B"), :c).path # => "A::B#c"

@return [String] the unique path of the object @see sep

# File lib/yard/code_objects/base.rb, line 442
def path
  @path ||= if parent && !parent.root?
              [parent.path, name.to_s].join(sep)
            else
              name.to_s
            end
end
Also aliased as: to_s
relative_path(other) click to toggle source

@param [Base, String] other another code object (or object path) @return [String] the shortest relative path from this object to other @since 0.5.3

# File lib/yard/code_objects/base.rb, line 464
def relative_path(other)
  other = Registry.at(other) if String === other && Registry.at(other)
  same_parent = false
  if other.respond_to?(:path)
    same_parent = other.parent == parent
    other = other.path
  end
  return other unless namespace
  common = [path, other].join(" ").match(/^(\S*)\S*(?: \1\S*)*$/)[1]
  common = path unless common =~ /(\.|::|#)$/
  common = common.sub(/(\.|::|#)[^:#\.]*?$/, '') if same_parent
  suffix = %w(. :).include?(common[-1, 1]) || other[common.size, 1] == '#' ?
    '' : '(::|\.)'
  result = other.sub(/^#{Regexp.quote common}#{suffix}/, '')
  result.empty? ? other : result
end
root?() click to toggle source

@return whether or not this object is a RootObject

# File lib/yard/code_objects/base.rb, line 551
def root?; false end
sep() click to toggle source

Override this method with a custom component separator. For instance, {MethodObject} implements sep as '#' or '.' (depending on if the method is instance or class respectively). {#path} depends on this value to generate the full path in the form: namespace.path + sep + name

@return [String] the component that separates the namespace path

and the name (default is {NSEP})
# File lib/yard/code_objects/base.rb, line 560
def sep; NSEP end
source=(statement) click to toggle source

Attaches source code to a code object with an optional file location

@param [#source, String] statement

the +Parser::Statement+ holding the source code or the raw source
as a +String+ for the definition of the code object only (not the block)
# File lib/yard/code_objects/base.rb, line 383
def source=(statement)
  if statement.respond_to?(:source)
    self.signature = statement.first_line
    @source = format_source(statement.source.strip)
  else
    @source = format_source(statement.to_s)
  end
end
tag(name) click to toggle source

Gets a tag from the {#docstring} @see Docstring#tag

# File lib/yard/code_objects/base.rb, line 532
def tag(name); docstring.tag(name) end
tags(name = nil) click to toggle source

Gets a list of tags from the {#docstring} @see Docstring#tags

# File lib/yard/code_objects/base.rb, line 536
def tags(name = nil); docstring.tags(name) end
title() click to toggle source

@note

Override this method if your object has a special title that does
not match the {#path} attribute value. This title will be used
when linking or displaying the object.

@return [String] the display title for an object @see 0.8.4

# File lib/yard/code_objects/base.rb, line 457
def title
  path
end
to_ary() click to toggle source

@return [nil] this object does not turn into an array

# File lib/yard/code_objects/base.rb, line 332
def to_ary; nil end
to_s()
Alias for: path
type() click to toggle source

Default type is the lowercase class name without the “Object” suffix. Override this method to provide a custom object type

@return [Symbol] the type of code object this represents

# File lib/yard/code_objects/base.rb, line 429
def type
  self.class.name.split('::').last.gsub(/Object$/, '').downcase.to_sym
end
visibility=(v) click to toggle source
# File lib/yard/code_objects/base.rb, line 183
def visibility=(v) @visibility = v.to_sym end

Protected Instance Methods

copyable_attributes() click to toggle source

Override this method if your code object subclass does not allow copying of certain attributes.

@return [Array<String>] the list of instance variable names (without

"@" prefix) that should be copied when {#copy_to} is called

@see copy_to @since 0.8.0

# File lib/yard/code_objects/base.rb, line 571
def copyable_attributes
  vars = instance_variables.map {|ivar| ivar.to_s[1..-1] }
  vars -= %w(docstring docstrings namespace name path)
  vars
end

Private Instance Methods

format_source(source) click to toggle source

Formats source code by removing leading indentation

@param [String] source the source code to format @return [String] formatted source

# File lib/yard/code_objects/base.rb, line 583
def format_source(source)
  source = source.chomp
  last = source.split(/\r?\n/).last
  indent = last ? last[/^([ \t]*)/, 1].length : 0
  source.gsub(/^[ \t]{#{indent}}/, '')
end
translate_docstring(locale) click to toggle source
# File lib/yard/code_objects/base.rb, line 590
def translate_docstring(locale)
  @docstring.resolve_reference
  return @docstring if locale.nil?

  text = I18n::Text.new(@docstring)
  localized_text = text.translate(locale)
  docstring = Docstring.new(localized_text, self)
  docstring.add_tag(*@docstring.tags)
  docstring
end