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.

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

subclass that implements {#path}, {#sep} or {#type}.

@see Registry @see path @see []= @see NamespaceObject

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 193
def ===(other)
  other.is_a?(self)
end
new(namespace, name, *args) { |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 212
def initialize(namespace, name, *args, &block)
  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
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 167
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

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 316
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 329
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 264
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 YARD::Docstring#add_tag @since 0.8.4

# File lib/yard/code_objects/base.rb, line 528
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 237
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 375
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 397
def docstring=(comments)
  @docstrings.clear
  if Docstring === comments
    @docstring = comments
  else
    @docstring = Docstring.new(comments, self)
  end
end
dynamic?() click to toggle source

Is the object defined conditionally at runtime? @see dynamic

# File lib/yard/code_objects/base.rb, line 156
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 296
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 280
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 478
def format(options = {})
  options = options.merge(:object => self)
  Templates::Engine.render(options)
end
has_tag?(name) click to toggle source

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

# File lib/yard/code_objects/base.rb, line 523
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 307
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 485
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 288
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 346
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 252
def name(prefix = false)
  prefix ? @name.to_s : @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 494
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 423
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 445
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
  if %w(. :).include?(common[-1,1]) || other[common.size,1] == '#'
    suffix = ''
  else
    suffix = '(::|\.)'
  end
  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 534
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 543
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 361
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 YARD::Docstring#tag

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

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

# File lib/yard/code_objects/base.rb, line 519
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 438
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 310
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 410
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 161
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 554
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 566
def format_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 573
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