Class: Dry::System::Component

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/system/component.rb

Overview

Components are objects providing information about auto-registered files. They expose an API to query this information and use a configurable loader object to initialize class instances.

Components are created automatically through auto-registration and can be accessed through ‘Container.auto_register!` which yields them.

Constant Summary collapse

DEFAULT_OPTIONS =
{
  separator: DEFAULT_SEPARATOR,
  namespace: nil,
  inflector: Dry::Inflector.new
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(identifier, path, options) ⇒ Component

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Component.



87
88
89
90
91
92
93
94
# File 'lib/dry/system/component.rb', line 87

def initialize(identifier, path, options)
  @identifier = identifier
  @path = path
  @options = options
  @file = "#{path}#{RB_EXT}"
  @loader = options.fetch(:loader)
  freeze
end

Instance Attribute Details

#fileObject (readonly)



40
41
42
# File 'lib/dry/system/component.rb', line 40

def file
  @file
end

#identifierObject (readonly)



32
33
34
# File 'lib/dry/system/component.rb', line 32

def identifier
  @identifier
end

#loaderObject (readonly)



48
49
50
# File 'lib/dry/system/component.rb', line 48

def loader
  @loader
end

#optionsObject (readonly)



44
45
46
# File 'lib/dry/system/component.rb', line 44

def options
  @options
end

#pathObject (readonly)



36
37
38
# File 'lib/dry/system/component.rb', line 36

def path
  @path
end

Class Method Details

.cacheObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



82
83
84
# File 'lib/dry/system/component.rb', line 82

def self.cache
  @cache ||= Concurrent::Map.new
end

.extract_identifier(name, ns, sep) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



67
68
69
70
71
72
# File 'lib/dry/system/component.rb', line 67

def self.extract_identifier(name, ns, sep)
  name_s = name.to_s
  identifier = ns ? remove_namespace_from_name(name_s, ns) : name_s

  identifier.scan(WORD_REGEX).join(sep)
end

.new(*args, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/dry/system/component.rb', line 51

def self.new(*args, &block)
  cache.fetch_or_store([*args, block].hash) do
    name, options = args
    options = DEFAULT_OPTIONS.merge(options || EMPTY_HASH)

    ns, sep, inflector = options.values_at(:namespace, :separator, :inflector)
    identifier = extract_identifier(name, ns, sep)

    path = name.to_s.gsub(sep, PATH_SEPARATOR)
    loader = options.fetch(:loader, Loader).new(path, inflector)

    super(identifier, path, options.merge(loader: loader))
  end
end

.remove_namespace_from_name(name, ns) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



75
76
77
78
79
# File 'lib/dry/system/component.rb', line 75

def self.remove_namespace_from_name(name, ns)
  match_value = name.match(/^(?<remove_namespace>#{ns})(?<separator>\W)(?<identifier>.*)/)

  match_value ? match_value[:identifier] : name
end

Instance Method Details

#auto_register?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


154
155
156
# File 'lib/dry/system/component.rb', line 154

def auto_register?
  !!options.fetch(:auto_register) { true }
end

#boot?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


120
121
122
# File 'lib/dry/system/component.rb', line 120

def boot?
  false
end

#file_exists?(paths) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


125
126
127
# File 'lib/dry/system/component.rb', line 125

def file_exists?(paths)
  paths.any? { |path| path.join(file).exist? }
end

#instance(*args) ⇒ Object

Returns components instance

Examples:

class MyApp < Dry::System::Container
  configure do |config|
    config.name = :my_app
    config.root = Pathname('/my/app')
  end

  auto_register!('lib/clients') do |component|
    # some custom initialization logic, ie:
    constant = component.loader.constant
    constant.create
  end
end

Returns:

  • (Object)

    component’s class instance



115
116
117
# File 'lib/dry/system/component.rb', line 115

def instance(*args)
  loader.call(*args)
end

#namespaceObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



149
150
151
# File 'lib/dry/system/component.rb', line 149

def namespace
  options[:namespace]
end

#namespaced(namespace) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



137
138
139
140
141
# File 'lib/dry/system/component.rb', line 137

def namespaced(namespace)
  self.class.new(
    path, options.merge(loader: loader.class, namespace: namespace)
  )
end

#prepend(name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



130
131
132
133
134
# File 'lib/dry/system/component.rb', line 130

def prepend(name)
  self.class.new(
    [name, identifier].join(separator), options.merge(loader: loader.class)
  )
end

#root_keyObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



159
160
161
# File 'lib/dry/system/component.rb', line 159

def root_key
  namespaces.first
end

#separatorObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



144
145
146
# File 'lib/dry/system/component.rb', line 144

def separator
  options[:separator]
end