# Module: YARD::Registry

Extended by:
  Enumerable

Defined in:
  lib/yard/registry.rb

## Overview

The `Registry` is the centralized data store for all CodeObjects created during parsing. The storage is a key value store with the object’s path (see CodeObjects::Base#path) as the key and the object itself as the value. Object paths must be unique to be stored in the Registry. All lookups for objects are done on the singleton Registry instance using the Registry.at or Registry.resolve methods.

## Saving / Loading a Registry

The registry is saved to a “yardoc file” (actually a directory), which can be loaded back to perform any lookups. See Registry.load! and Registry.save for information on saving and loading of a yardoc file.

## Threading Notes

The registry class is a singleton class that is accessed directly in many places across YARD. To mitigate threading issues, YARD (0.6.5+) makes the Registry thread local. This means all access to a registry for a specific object set must occur in the originating thread.

#### Examples:

#####

Loading the Registry

    Registry.load!('/path/to/yardocfile') # loads all objects into memory
    Registry.at('YARD::CodeObjects::Base').docstring
    # => "+Base+ is the superclass of all code objects ..."

#####

Getting an object by a specific path

    Registry.at('YARD::CodeObjects::Base#docstring')

#####

Performing a lookup on a method anywhere in the inheritance tree

    Registry.resolve(P('YARD::CodeObjects::Base'), '#docstring', true)

## Constant Summary collapse

DEFAULT_YARDOC_FILE =

      ".yardoc"

LOCAL_YARDOC_INDEX =

      File.expand_path(File.join(Config::CONFIG_DIR, 'gem_index'))

DEFAULT_PO_DIR =

      "po"

## Getting .yardoc File Locations collapse

- .yardoc_file ⇒ String

  Gets/sets the yardoc filename.

## Managing Internal State (Advanced / Testing Only) collapse

- .single_object_db ⇒ Boolean?

  Whether or not the Registry storage should load everything into a single object database (for disk efficiency), or spread them out (for load time efficiency).

## I18n features collapse

- .po_dir ⇒ String

  Gets/sets the directory that has LANG.po files.

## Getting .yardoc File Locations collapse

- .yardoc_file_for_gem(gem, ver_require = ">= 0", for_writing = false) ⇒ String?

  Returns the .yardoc file associated with a gem.

## Loading Data from Disk collapse

- .load(files = [], reparse = false) ⇒ Registry

  Loads the registry and/or parses a list of files.

- .load!(file = yardoc_file) ⇒ Registry

  Loads a yardoc file and forces all objects cached on disk into memory.

- .load_all ⇒ Registry

  Forces all objects cached on disk into memory.

- .load_yardoc(file = yardoc_file) ⇒ Registry

  Loads a yardoc file directly.

## Saving and Deleting Data from Disk collapse

- .delete_from_disk ⇒ void

  Deletes the yardoc file from disk.

- .save(merge = false, file = yardoc_file) ⇒ Boolean

  Saves the registry to `file`.

## Adding and Deleting Objects from the Registry collapse

- .clear ⇒ void

  Clears the registry.

- .delete(object) ⇒ void

  Deletes an object from the registry.

- .lock_for_writing(file = yardoc_file, &block) ⇒ Object

  Creates a pessmistic transactional lock on the database for writing.

- .locked_for_writing?(file = yardoc_file) ⇒ Boolean

  Whether the database is currently locked for writing.

- .register(object) ⇒ CodeObjects::Base

  Registers a new object with the registry.

## Accessing Objects in the Registry collapse

- .all(*types) ⇒ Array<CodeObjects::Base>

  Returns all objects in the registry that match one of the types provided in the `types` list (if `types` is provided).

- .at(path) ⇒ CodeObjects::Base? (also: [])

  Returns the object at a specific path.

- .each(&block) ⇒ Object

  Iterates over Registry.all with no arguments.

- .locale(name) ⇒ I18n::Locale

  The locale object for `name`.

- .paths(reload = false) ⇒ Array<String>

  Returns the paths of all of the objects in the registry.

- .resolve(namespace, name, inheritance = false, proxy_fallback = false, type = nil) ⇒ CodeObjects::Base, ...

  Attempts to find an object by name starting at `namespace`, performing a lookup similar to Ruby’s method of resolving a constant in a namespace.

- .root ⇒ CodeObjects::RootObject

  The root namespace object.

## Managing Source File Checksums collapse

- .checksum_for(data) ⇒ String

  The SHA1 checksum for data.

- .checksums ⇒ Hash{String => String}

  A set of checksums for files.

## Legacy Methods collapse

- .instance ⇒ Registry deprecated Deprecated.

  use Registry.methodname directly.

## Class Attribute Details

### .po_dir ⇒ `String`

Gets/sets the directory that has LANG.po files

Returns:

- (`String`) —

  the directory that has .po files

    349
    350
    351

    # File 'lib/yard/registry.rb', line 349

    def po_dir
      @po_dir
    end

### .single_object_db ⇒ `Boolean`?

Note:

Setting this attribute to nil will offload the decision to the storage adapter.

Whether or not the Registry storage should load everything into a single object database (for disk efficiency), or spread them out (for load time efficiency).

Returns:

- (`Boolean`, `nil`) —

  if this value is set to nil, the storage adapter will decide how to store the data.

    332
    333
    334

    # File 'lib/yard/registry.rb', line 332

    def single_object_db
      @single_object_db
    end

### .yardoc_file ⇒ `String`

Gets/sets the yardoc filename

Returns:

- (`String`) —

  the yardoc filename

See Also:

- DEFAULT_YARDOC_FILE

    84
    85
    86

    # File 'lib/yard/registry.rb', line 84

    def yardoc_file
      @yardoc_file
    end

## Class Method Details

### .all(*types) ⇒ `Array<CodeObjects::Base>`

Returns all objects in the registry that match one of the types provided in the `types` list (if `types` is provided).

#### Examples:

#####

Returns all objects

    Registry.all

#####

Returns all classes and modules

    Registry.all(:class, :module)

Parameters:

- types (`Array<Symbol>`) —

  an optional list of types to narrow the objects down by. Equivalent to performing a select:

      +Registry.all.select {|o| types.include(o.type) }+

Returns:

- (`Array<CodeObjects::Base>`) —

  the list of objects found

See Also:

- CodeObjects::Base#type

    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247

    # File 'lib/yard/registry.rb', line 237

    def all(*types)
      if types.empty?
        thread_local_store.values.select {|obj| obj != root }
      else
        list = []
        types.each do |type|
          list += thread_local_store.values_for_type(type)
        end
        list
      end
    end

### .at(path) ⇒ `CodeObjects::Base`? Also known as: []

Returns the object at a specific path.

Parameters:

- path (`String`, `:root`) —

  the pathname to look for. If `path` is `root`, returns the root object.

Returns:

- (`CodeObjects::Base`) —

  the object at path

- (`nil`) —

  if no object is found

    261

    # File 'lib/yard/registry.rb', line 261

    def at(path) path ? thread_local_store[path] : nil end

### .checksum_for(data) ⇒ `String`

Returns the SHA1 checksum for data.

Parameters:

- data (`String`) —

  data to checksum

Returns:

- (`String`) —

  the SHA1 checksum for data

    318
    319
    320

    # File 'lib/yard/registry.rb', line 318

    def checksum_for(data)
      Digest::SHA1.hexdigest(data)
    end

### .checksums ⇒ `Hash{String => String}`

Returns a set of checksums for files.

Returns:

- (`Hash{String => String}`) —

  a set of checksums for files

    312
    313
    314

    # File 'lib/yard/registry.rb', line 312

    def checksums
      thread_local_store.checksums
    end

### .clear ⇒ `void`

This method returns an undefined value.

Clears the registry

    200
    201
    202

    # File 'lib/yard/registry.rb', line 200

    def clear
      self.thread_local_store = RegistryStore.new
    end

### .delete(object) ⇒ `void`

This method returns an undefined value.

Deletes an object from the registry

Parameters:

- object (`CodeObjects::Base`) —

  the object to remove

    194
    195
    196

    # File 'lib/yard/registry.rb', line 194

    def delete(object)
      thread_local_store.delete(object.path)
    end

### .delete_from_disk ⇒ `void`

This method returns an undefined value.

Deletes the yardoc file from disk

    176
    177
    178

    # File 'lib/yard/registry.rb', line 176

    def delete_from_disk
      thread_local_store.destroy
    end

### .each(&block) ⇒ `Object`

Iterates over all with no arguments

    221
    222
    223

    # File 'lib/yard/registry.rb', line 221

    def each(&block)
      all.each(&block)
    end

### .instance ⇒ `Registry`

Deprecated.

use Registry.methodname directly.

The registry singleton instance.

Returns:

- (`Registry`) —

  returns the registry instance

    363

    # File 'lib/yard/registry.rb', line 363

    def instance; self end

### .load(files = [], reparse = false) ⇒ `Registry`

Loads the registry and/or parses a list of files

#### Examples:

#####

Loads the yardoc file or parses files ‘a’, ‘b’ and ‘c’ (but not both)

    Registry.load(['a', 'b', 'c'])

#####

Reparses files ‘a’ and ‘b’ regardless of whether yardoc file exists

    Registry.load(['a', 'b'], true)

Parameters:

- files (`String`, `Array`) (defaults to: `[]`) —

  if `files` is an Array, it should represent a list of files that YARD should parse into the registry. If reload is set to false and the yardoc file already exists, these files are skipped. If files is a String, it should represent the yardoc file to load into the registry.

- reparse (`Boolean`) (defaults to: `false`) —

  if reparse is false and a yardoc file already exists, any files passed in will be ignored.

Returns:

- (`Registry`) —

  the registry object (for chaining)

Raises:

- (`ArgumentError`) —

  if files is not a String or Array

    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124

    # File 'lib/yard/registry.rb', line 109

    def load(files = [], reparse = false)
      if files.is_a?(Array)
        if File.exist?(yardoc_file) && !reparse
          load_yardoc
        else
          size = thread_local_store.keys.size
          YARD.parse(files)
          save if thread_local_store.keys.size > size
        end
      elsif files.is_a?(String)
        load_yardoc(files)
      else
        raise ArgumentError, "Must take a list of files to parse or the .yardoc file to load."
      end
      self
    end

### .load!(file = yardoc_file) ⇒ `Registry`

Loads a yardoc file and forces all objects cached on disk into memory. Equivalent to calling load_yardoc followed by load_all

Parameters:

- file (`String`) (defaults to: `yardoc_file`) —

  the yardoc file to load

Returns:

- (`Registry`) —

  the registry object (for chaining)

See Also:

- #load_yardoc
- #load_all

Since:

- 0.5.1

    144
    145
    146
    147
    148

    # File 'lib/yard/registry.rb', line 144

    def load!(file = yardoc_file)
      clear
      thread_local_store.load!(file)
      self
    end

### .load_all ⇒ `Registry`

Forces all objects cached on disk into memory

#### Examples:

#####

Loads all objects from disk

    Registry.load
    Registry.all.count #=> 0
    Registry.load_all
    Registry.all.count #=> 17

Returns:

- (`Registry`) —

  the registry object (for chaining)

Since:

- 0.5.1

    159
    160
    161
    162

    # File 'lib/yard/registry.rb', line 159

    def load_all
      thread_local_store.load_all
      self
    end

### .load_yardoc(file = yardoc_file) ⇒ `Registry`

Loads a yardoc file directly

Parameters:

- file (`String`) (defaults to: `yardoc_file`) —

  the yardoc file to load.

Returns:

- (`Registry`) —

  the registry object (for chaining)

    130
    131
    132
    133
    134

    # File 'lib/yard/registry.rb', line 130

    def load_yardoc(file = yardoc_file)
      clear
      thread_local_store.load(file)
      self
    end

### .locale(name) ⇒ `I18n::Locale`

Returns the locale object for `name`.

Parameters:

- name (`String`) —

  the locale name.

Returns:

- (`I18n::Locale`) —

  the locale object for `name`.

Since:

- 0.8.3

    271
    272
    273

    # File 'lib/yard/registry.rb', line 271

    def locale(name)
      thread_local_store.locale(name)
    end

### .lock_for_writing(file = yardoc_file, &block) ⇒ `Object`

Creates a pessmistic transactional lock on the database for writing. Use with YARD.parse to ensure the database is not written multiple times.

See Also:

- locked_for_writing?

    209
    210
    211

    # File 'lib/yard/registry.rb', line 209

    def lock_for_writing(file = yardoc_file, &block)
      thread_local_store.lock_for_writing(file, &block)
    end

### .locked_for_writing?(file = yardoc_file) ⇒ `Boolean`

Returns whether the database is currently locked for writing.

Returns:

- (`Boolean`) —

  whether the database is currently locked for writing

    214
    215
    216

    # File 'lib/yard/registry.rb', line 214

    def locked_for_writing?(file = yardoc_file)
      thread_local_store.locked_for_writing?(file)
    end

### .paths(reload = false) ⇒ `Array<String>`

Returns the paths of all of the objects in the registry.

Parameters:

- reload (`Boolean`) (defaults to: `false`) —

  whether to load entire database

Returns:

- (`Array<String>`) —

  all of the paths in the registry.

    252
    253
    254

    # File 'lib/yard/registry.rb', line 252

    def paths(reload = false)
      thread_local_store.keys(reload).map(&:to_s)
    end

### .register(object) ⇒ `CodeObjects::Base`

Registers a new object with the registry

Parameters:

- object (`CodeObjects::Base`) —

  the object to register

Returns:

- (`CodeObjects::Base`) —

  the registered object

    186
    187
    188
    189

    # File 'lib/yard/registry.rb', line 186

    def register(object)
      return if object.is_a?(CodeObjects::Proxy)
      thread_local_store[object.path] = object
    end

### .resolve(namespace, name, inheritance = false, proxy_fallback = false, type = nil) ⇒ `CodeObjects::Base`, ...

Attempts to find an object by name starting at `namespace`, performing a lookup similar to Ruby’s method of resolving a constant in a namespace.

#### Examples:

#####

Looks for instance method #reverse starting from A::B::C

    Registry.resolve(P("A::B::C"), "#reverse")

#####

Looks for a constant in the root namespace

    Registry.resolve(nil, 'CONSTANT')

#####

Looks for a class method respecting the inheritance tree

    Registry.resolve(myclass, 'mymethod', true)

#####

Looks for a constant but returns a proxy if not found

    Registry.resolve(P('A::B::C'), 'D', false, true) # => #<yardoc proxy A::B::C::D>

#####

Looks for a complex path from a namespace

    Registry.resolve(P('A::B'), 'B::D') # => #<yardoc class A::B::D>

Parameters:

- namespace (`CodeObjects::NamespaceObject`, `nil`) —

  the starting namespace (module or class). If `nil` or `:root`, starts from the root object.

- name (`String`, `Symbol`) —

  the name (or complex path) to look for from `namespace`.

- inheritance (`Boolean`) (defaults to: `false`) —

  Follows inheritance chain (mixins, superclass) when performing name resolution if set to `true`.

- proxy_fallback (`Boolean`) (defaults to: `false`) —

  If `true`, returns a proxy representing the unresolved path (namespace + name) if no object is found.

- type (`Symbol`, `nil`) (defaults to: `nil`) —

  the CodeObjects::Base#type that the resolved object must be equal to. No type checking if nil.

Returns:

- (`CodeObjects::Base`) —

  the object if it is found

- (`CodeObjects::Proxy`) —

  a Proxy representing the object if `proxy_fallback` is `true`.

- (`nil`) —

  if `proxy_fallback` is `false` and no object was found.

See Also:

- P

    303
    304
    305
    306
    307

    # File 'lib/yard/registry.rb', line 303

    def resolve(namespace, name, inheritance = false, proxy_fallback = false, type = nil)
      thread_local_resolver.lookup_by_path name,
        :namespace => namespace, :inheritance => inheritance,
        :proxy_fallback => proxy_fallback, :type => type
    end

### .root ⇒ `CodeObjects::RootObject`

The root namespace object.

Returns:

- (`CodeObjects::RootObject`) —

  the root object in the namespace

    266

    # File 'lib/yard/registry.rb', line 266

    def root; thread_local_store[:root] end

### .save(merge = false, file = yardoc_file) ⇒ `Boolean`

Saves the registry to `file`

Parameters:

- file (`String`) (defaults to: `yardoc_file`) —

  the yardoc file to save to

Returns:

- (`Boolean`) —

  true if the file was saved

    170
    171
    172

    # File 'lib/yard/registry.rb', line 170

    def save(merge = false, file = yardoc_file)
      thread_local_store.save(merge, file)
    end

### .yardoc_file_for_gem(gem, ver_require = ">= 0", for_writing = false) ⇒ `String`?

Returns the .yardoc file associated with a gem.

Parameters:

- gem (`String`) —

  the name of the gem to search for

- ver_require (`String`) (defaults to: `">= 0"`) —

  an optional Gem version requirement

- for_writing (`Boolean`) (defaults to: `false`) —

  whether or not the method should search for writable locations

Returns:

- (`String`) —

  if `for_writing` is set to `true`, returns the best location suitable to write the .yardoc file. Otherwise, the first existing location associated with the gem’s .yardoc file.

- (`nil`) —

  if `for_writing` is set to false and no yardoc file is found, returns nil.

    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79

    # File 'lib/yard/registry.rb', line 53

    def yardoc_file_for_gem(gem, ver_require = ">= 0", for_writing = false)
      specs = YARD::GemIndex.find_all_by_name(gem, ver_require)
      return if specs.empty?

      result = nil
      specs.reverse.each do |spec|
        if gem =~ /^yard-doc-/
          path = File.join(spec.full_gem_path, DEFAULT_YARDOC_FILE)
          result = File.exist?(path) && !for_writing ? path : nil
          result ? break : next
        end

        if for_writing
          result = global_yardoc_file(spec, for_writing) ||
                   old_global_yardoc_file(spec, for_writing) ||
                   local_yardoc_file(spec, for_writing)
        else
          result = local_yardoc_file(spec, for_writing) ||
                   global_yardoc_file(spec, for_writing) ||
                   old_global_yardoc_file(spec, for_writing)
        end

        break if result
      end

      result
    end