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.
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.
Code objects allow arbitrary custom attributes to be set using the {#[]=} assignment method.
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
The documentation string associated with the object @return [Docstring] the documentation string
Marks whether or not the method is conditionally defined at runtime @return [Boolean] true if the method is conditionally defined at runtime
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
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
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
The source code associated with the object @return [String, nil] source, if present, or nil
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 190 def ===(other) other.is_a?(self) end
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 209 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 = [] @docstring = Docstring.new('', self) @docstring_extra = nil @docstring_extra_tags = nil @namespace = nil self.namespace = namespace yield(self) if block_given? end
Allocates a new code object @return [Base] @see initialize
# File lib/yard/code_objects/base.rb, line 164 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
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 314 def [](key) if respond_to?(key) send(key) elsif instance_variable_defined?("@#{key}") instance_variable_get("@#{key}") end end
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 327 def []=(key, value) if respond_to?("#{key}=") send("#{key}=", value) else instance_variable_set("@#{key}", value) end end
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 262 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
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 235 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
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 389 def docstring=(comments) if comments =~ /\A\s*\(see (\S+)\s*\)(?:\s|$)/ path, extra = $1, $' @docstring_extra = Docstring.new(extra, self) @docstring_extra_tags = Docstring === comments ? comments.tags : [] @docstring_extra.add_tag(*@docstring_extra_tags) @docstring = Proxy.new(namespace, path) else @docstring_extra = nil @docstring_extra_tags = nil @docstring = Docstring === comments ? comments : Docstring.new(comments, self) end end
Is the object defined conditionally at runtime? @see dynamic
# File lib/yard/code_objects/base.rb, line 153 def dynamic?; @dynamic end
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
# File lib/yard/code_objects/base.rb, line 294 def equal?(other) if other.is_a?(Base) || other.is_a?(Proxy) path == other.path else super end end
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 278 def file @files.first ? @files.first[0] : nil end
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 465 def format(options = {}) options = options.merge(:object => self) Templates::Engine.render(options) end
Tests if the {docstring} has a tag @see Docstring#has_tag?
# File lib/yard/code_objects/base.rb, line 510 def has_tag?(name); docstring.has_tag?(name) end
@return [Integer] the object's hash value (for equality checking)
# File lib/yard/code_objects/base.rb, line 305 def hash; path.hash end
Inspects the object, returning the type and path @return [String] a string describing the object
# File lib/yard/code_objects/base.rb, line 472 def inspect "#<yardoc #{type} #{path}>" end
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 286 def line @files.first ? @files.first[1] : nil end
@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 #[]=
# File lib/yard/code_objects/base.rb, line 344 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
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 250 def name(prefix = false) prefix ? @name.to_s : @name end
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 481 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
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 420 def path @path ||= if parent && !parent.root? [parent.path, name.to_s].join(sep) else name.to_s end end
@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 432 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*(?: \11\\S*)*$/)[1] common = path unless common =~ /(\.|::|#)$/ common = common.sub(/(\.|::|#)[^:#\.]*?$/, '') if same_parent if %(. :).include?(common[-1,1]) || other[common.size,1] == '#' suffix = '' else suffix = '(::|\.)' end result = other.sub(/^#{Regexp.quote common}#{suffix}/, '') result.empty? ? other : result end
@return whether or not this object is a RootObject
# File lib/yard/code_objects/base.rb, line 513 def root?; false end
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 522 def sep; NSEP end
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 359 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
Gets a tag from the {docstring} @see Docstring#tag
# File lib/yard/code_objects/base.rb, line 502 def tag(name); docstring.tag(name) end
@return [nil] this object does not turn into an array
# File lib/yard/code_objects/base.rb, line 308 def to_ary; nil end
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 407 def type self.class.name.split(/#{NSEPQ}/).last.gsub(/Object$/, '').downcase.to_sym end
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 533 def copyable_attributes vars = instance_variables.map {|ivar| ivar.to_s[1..-1] } vars -= %(docstring namespace name path) vars end
Generated with the Darkfish Rdoc Generator 2.