Class: YARD::CodeObjects::Base Abstract
- Inherits:
-
Object
- Object
- YARD::CodeObjects::Base
- Defined in:
- lib/yard/code_objects/base.rb
Overview
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.
Direct Known Subclasses
ClassVariableObject, ConstantObject, MacroObject, MethodObject, NamespaceObject
Instance Attribute Summary collapse
-
#base_docstring ⇒ Docstring
readonly
The non-localized documentation string associated with the object.
-
#dynamic ⇒ Boolean
Marks whether or not the method is conditionally defined at runtime.
-
#files ⇒ Array<String>
readonly
The files the object was defined in.
-
#group ⇒ String
The group this object is associated with.
-
#namespace ⇒ NamespaceObject
(also: #parent)
The namespace the object is defined in.
-
#signature ⇒ String
The one line signature representing an object.
-
#source ⇒ String?
The source code associated with the object.
-
#source_type ⇒ Symbol
Language of the source code associated with the object.
-
#visibility ⇒ Symbol
The visibility of an object (:public, :private, :protected).
Class Method Summary collapse
-
.===(other) ⇒ Boolean
Compares the class with subclasses.
-
.new(namespace, name, *args) {|obj| ... } ⇒ Base
Allocates a new code object.
Instance Method Summary collapse
-
#[](key) ⇒ Object?
Accesses a custom attribute on the object.
-
#[]=(key, value) ⇒ void
Sets a custom attribute on the object.
-
#add_file(file, line = nil, has_comments = false) ⇒ Object
Associates a file with a code object, optionally adding the line where it was defined.
-
#add_tag(*tags) ⇒ Object
Add tags to the #docstring.
-
#copy_to(other) ⇒ Base
Copies all data in this object to another code object, except for uniquely identifying information (path, namespace, name, scope).
-
#copyable_attributes ⇒ Array<String>
protected
Override this method if your code object subclass does not allow copying of certain attributes.
-
#docstring(locale = I18n::Locale.default) ⇒ Docstring
The documentation string associated with the object.
-
#docstring=(comments) ⇒ Object
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.
-
#dynamic? ⇒ Boolean
Is the object defined conditionally at runtime?.
-
#equal?(other) ⇒ Boolean
(also: #==, #eql?)
Tests if another object is equal to this, including a proxy.
-
#file ⇒ String
Returns the filename the object was first parsed at, taking definitions with docstrings first.
-
#format(options = {}) ⇒ String
Renders the object using the templating system.
-
#has_tag?(name) ⇒ Boolean
Tests if the #docstring has a tag.
-
#hash ⇒ Integer
The object’s hash value (for equality checking).
-
#initialize(namespace, name, *args) {|self| ... } ⇒ Base
constructor
Creates a new code object.
-
#inspect ⇒ String
Inspects the object, returning the type and path.
-
#line ⇒ Fixnum?
Returns the line the object was first parsed at (or nil).
- #method_missing(meth, *args, &block) ⇒ Object
-
#name(prefix = false) ⇒ Symbol, String
The name of the object.
-
#path ⇒ String
(also: #to_s)
Represents the unique path of the object.
-
#relative_path(other) ⇒ String
The shortest relative path from this object to
other
. -
#root? ⇒ Boolean
Whether or not this object is a RootObject.
-
#sep ⇒ String
Override this method with a custom component separator.
-
#tag(name) ⇒ Object
Gets a tag from the #docstring.
-
#tags(name = nil) ⇒ Object
Gets a list of tags from the #docstring.
-
#title ⇒ String
The display title for an object.
-
#to_ary ⇒ nil
This object does not turn into an array.
-
#type ⇒ Symbol
Default type is the lowercase class name without the “Object” suffix.
Constructor Details
#initialize(namespace, name, *args) {|self| ... } ⇒ Base
Creates a new code object
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/yard/code_objects/base.rb', line 215 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 |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#dynamic_attr_name ⇒ Object #dynamic_attr_name=(value) ⇒ Object
349 350 351 352 353 354 355 356 357 |
# File 'lib/yard/code_objects/base.rb', line 349 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 |
Instance Attribute Details
#base_docstring ⇒ Docstring (readonly)
The non-localized documentation string associated with the object
145 146 147 |
# File 'lib/yard/code_objects/base.rb', line 145 def base_docstring @base_docstring end |
#dynamic ⇒ Boolean
Marks whether or not the method is conditionally defined at runtime
151 152 153 |
# File 'lib/yard/code_objects/base.rb', line 151 def dynamic @dynamic end |
#files ⇒ Array<String> (readonly)
The files the object was defined in. To add a file, use #add_file.
118 119 120 |
# File 'lib/yard/code_objects/base.rb', line 118 def files @files end |
#group ⇒ String
Returns the group this object is associated with.
155 156 157 |
# File 'lib/yard/code_objects/base.rb', line 155 def group @group end |
#namespace ⇒ NamespaceObject Also known as: parent
The namespace the object is defined in. If the object is in the top level namespace, this is Registry.root
123 124 125 |
# File 'lib/yard/code_objects/base.rb', line 123 def namespace @namespace end |
#signature ⇒ String
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.
140 141 142 |
# File 'lib/yard/code_objects/base.rb', line 140 def signature @signature end |
#source ⇒ String?
The source code associated with the object
127 128 129 |
# File 'lib/yard/code_objects/base.rb', line 127 def source @source end |
#source_type ⇒ Symbol
Language of the source code associated with the object. Defaults to :ruby
.
133 134 135 |
# File 'lib/yard/code_objects/base.rb', line 133 def source_type @source_type end |
#visibility ⇒ Symbol
Returns the visibility of an object (:public, :private, :protected).
162 163 164 |
# File 'lib/yard/code_objects/base.rb', line 162 def visibility @visibility end |
Class Method Details
.===(other) ⇒ Boolean
Compares the class with subclasses
196 197 198 |
# File 'lib/yard/code_objects/base.rb', line 196 def ===(other) other.is_a?(self) end |
.new(namespace, name, *args) {|obj| ... } ⇒ Base
Allocates a new code object
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/yard/code_objects/base.rb', line 170 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 |
Instance Method Details
#[](key) ⇒ Object?
Accesses a custom attribute on the object
319 320 321 322 323 324 325 |
# File 'lib/yard/code_objects/base.rb', line 319 def [](key) if respond_to?(key) send(key) elsif instance_variable_defined?("@#{key}") instance_variable_get("@#{key}") end end |
#[]=(key, value) ⇒ void
This method returns an undefined value.
Sets a custom attribute on the object
332 333 334 335 336 337 338 |
# File 'lib/yard/code_objects/base.rb', line 332 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) ⇒ Object
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.
267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/yard/code_objects/base.rb', line 267 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) ⇒ Object
Add tags to the #docstring
531 532 533 534 |
# File 'lib/yard/code_objects/base.rb', line 531 def add_tag(*) @docstrings.clear @docstring.add_tag(*) end |
#copy_to(other) ⇒ Base
Copies all data in this object to another code object, except for uniquely identifying information (path, namespace, name, scope).
240 241 242 243 244 245 246 247 |
# File 'lib/yard/code_objects/base.rb', line 240 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 |
#copyable_attributes ⇒ Array<String> (protected)
Override this method if your code object subclass does not allow copying of certain attributes.
557 558 559 560 561 |
# File 'lib/yard/code_objects/base.rb', line 557 def copyable_attributes vars = instance_variables.map {|ivar| ivar.to_s[1..-1] } vars -= %w(docstring docstrings namespace name path) vars end |
#docstring(locale = I18n::Locale.default) ⇒ Docstring
The documentation string associated with the object
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
# File 'lib/yard/code_objects/base.rb', line 378 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) ⇒ Object
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.
400 401 402 403 404 405 406 407 |
# File 'lib/yard/code_objects/base.rb', line 400 def docstring=(comments) @docstrings.clear if Docstring === comments @docstring = comments else @docstring = Docstring.new(comments, self) end end |
#dynamic? ⇒ Boolean
Is the object defined conditionally at runtime?
159 |
# File 'lib/yard/code_objects/base.rb', line 159 def dynamic?; @dynamic end |
#equal?(other) ⇒ Boolean Also known as: ==, eql?
Tests if another object is equal to this, including a proxy
299 300 301 302 303 304 305 |
# File 'lib/yard/code_objects/base.rb', line 299 def equal?(other) if other.is_a?(Base) || other.is_a?(Proxy) path == other.path else super end end |
#file ⇒ String
Returns the filename the object was first parsed at, taking definitions with docstrings first.
283 284 285 |
# File 'lib/yard/code_objects/base.rb', line 283 def file @files.first ? @files.first[0] : nil end |
#format(options = {}) ⇒ String
Renders the object using the templating system.
481 482 483 484 |
# File 'lib/yard/code_objects/base.rb', line 481 def format( = {}) = .merge(:object => self) Templates::Engine.render() end |
#has_tag?(name) ⇒ Boolean
Tests if the #docstring has a tag
526 |
# File 'lib/yard/code_objects/base.rb', line 526 def has_tag?(name); docstring.has_tag?(name) end |
#hash ⇒ Integer
Returns the object’s hash value (for equality checking).
310 |
# File 'lib/yard/code_objects/base.rb', line 310 def hash; path.hash end |
#inspect ⇒ String
Inspects the object, returning the type and path
488 489 490 |
# File 'lib/yard/code_objects/base.rb', line 488 def inspect "#<yardoc #{type} #{path}>" end |
#line ⇒ Fixnum?
Returns the line the object was first parsed at (or nil)
291 292 293 |
# File 'lib/yard/code_objects/base.rb', line 291 def line @files.first ? @files.first[1] : nil end |
#name(prefix = false) ⇒ Symbol, String
The name of the object
255 256 257 |
# File 'lib/yard/code_objects/base.rb', line 255 def name(prefix = false) prefix ? @name.to_s : @name end |
#path ⇒ String Also known as: to_s
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.
426 427 428 429 430 431 432 |
# File 'lib/yard/code_objects/base.rb', line 426 def path @path ||= if parent && !parent.root? [parent.path, name.to_s].join(sep) else name.to_s end end |
#relative_path(other) ⇒ String
Returns the shortest relative path from this object to other
.
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/yard/code_objects/base.rb', line 448 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? ⇒ Boolean
Returns whether or not this object is a RootObject.
537 |
# File 'lib/yard/code_objects/base.rb', line 537 def root?; false end |
#sep ⇒ String
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
546 |
# File 'lib/yard/code_objects/base.rb', line 546 def sep; NSEP end |
#tag(name) ⇒ Object
Gets a tag from the #docstring
518 |
# File 'lib/yard/code_objects/base.rb', line 518 def tag(name); docstring.tag(name) end |
#tags(name = nil) ⇒ Object
Gets a list of tags from the #docstring
522 |
# File 'lib/yard/code_objects/base.rb', line 522 def (name = nil); docstring.(name) end |
#title ⇒ String
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.
Returns the display title for an object.
441 442 443 |
# File 'lib/yard/code_objects/base.rb', line 441 def title path end |
#to_ary ⇒ nil
Returns this object does not turn into an array.
313 |
# File 'lib/yard/code_objects/base.rb', line 313 def to_ary; nil end |
#type ⇒ Symbol
Default type is the lowercase class name without the “Object” suffix. Override this method to provide a custom object type
413 414 415 |
# File 'lib/yard/code_objects/base.rb', line 413 def type self.class.name.split('::').last.gsub(/Object$/, '').downcase.to_sym end |