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.


85
86
87
88
89
90
91
# File 'lib/dry/system/component.rb', line 85

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

Instance Attribute Details

#fileObject (readonly)


38
39
40
# File 'lib/dry/system/component.rb', line 38

def file
  @file
end

#identifierObject (readonly)


30
31
32
# File 'lib/dry/system/component.rb', line 30

def identifier
  @identifier
end

#loaderObject (readonly)


46
47
48
# File 'lib/dry/system/component.rb', line 46

def loader
  @loader
end

#optionsObject (readonly)


42
43
44
# File 'lib/dry/system/component.rb', line 42

def options
  @options
end

#pathObject (readonly)


34
35
36
# File 'lib/dry/system/component.rb', line 34

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.


80
81
82
# File 'lib/dry/system/component.rb', line 80

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.


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

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.


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

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.


73
74
75
76
77
# File 'lib/dry/system/component.rb', line 73

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)

151
152
153
# File 'lib/dry/system/component.rb', line 151

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)

117
118
119
# File 'lib/dry/system/component.rb', line 117

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)

122
123
124
# File 'lib/dry/system/component.rb', line 122

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


112
113
114
# File 'lib/dry/system/component.rb', line 112

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.


146
147
148
# File 'lib/dry/system/component.rb', line 146

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.


134
135
136
137
138
# File 'lib/dry/system/component.rb', line 134

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.


127
128
129
130
131
# File 'lib/dry/system/component.rb', line 127

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.


156
157
158
# File 'lib/dry/system/component.rb', line 156

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.


141
142
143
# File 'lib/dry/system/component.rb', line 141

def separator
  options[:separator]
end