natural_born_slugger 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c53161bfaee3307f0789e14966a1cef3def933f3
4
- data.tar.gz: b0d8d1d8e94fae0798e5ad1b6411d21ff50a18c0
3
+ metadata.gz: cf8a2e95a9e37528207d180abcfefda53ee8c4a2
4
+ data.tar.gz: 3b12053c7a01c7805a19750ed9eaa73082552fbb
5
5
  SHA512:
6
- metadata.gz: 4847802082fabbcb6f537d607f8cabf918fda7a258966c4ac0b43e9a7fe7a89794f1880a2b1a9918c800a80c1d9ab23c3fb15d2f0fca151b32eb6a5e1d443390
7
- data.tar.gz: b93c87ae94fec058f6dac6e6027cc5dde19ab2880a7d292dfd89f5eeca71cada422cc8fbc326a3acfb3755789c5469716190bc7ac0167d943ad2d063ead921fc
6
+ metadata.gz: 4e7781ec967dc3e89fca75c3a232e203cecd8098841ceecea00878a300353089fbef75c3a4889a06dd2b0beaa8eda0a9a1b5650d5c72bebf3ba23202cdacef76
7
+ data.tar.gz: 0fd95992883ed518d066ae9fbdf545466820556bd870c361e41c6dc25cc110775424f9b7cc7313b0e1535f15dd42db912be4ba9d555ea3d8333af2649be6c5aa
data/.rspec ADDED
@@ -0,0 +1,11 @@
1
+ # Autoload spec helper
2
+ --require spec_helper
3
+
4
+ # Show more colorful RSpec results
5
+ --color
6
+
7
+ # Verbose display
8
+ --format documentation
9
+
10
+ # Use full backtraces
11
+ -b
data/README.md CHANGED
@@ -116,22 +116,7 @@ The options hash is where you define the attribute's dependencies. It also uses
116
116
 
117
117
  bambino = Person.new('Babe', nil, 'Ruth')
118
118
  bambino.slug #=> "Babe-Ruth"
119
- ```
120
-
121
- ##### `:compact`
122
- - Removes nil dependencies before joining.
123
- - Default: true
124
- - Example: Notice the extra dash in the example below:
125
119
 
126
- ```
127
- Person = Struct.new(:first_name, :middle_name, :last_name) do
128
- include NaturalBornSlugger
129
- has_slug first_name: nil, middle_name: nil, last_name: nil, compact: false, join_with: '-'
130
- end
131
-
132
- bambino = Person.new('Babe', nil, 'Ruth')
133
- bambino.slug #=> "Babe--Ruth"
134
- ```
135
120
 
136
121
  ##### `:require_all`
137
122
  - Checks to make sure all attributes exist before composing attribute.
@@ -152,7 +137,7 @@ The options hash is where you define the attribute's dependencies. It also uses
152
137
  bambino.slug #=> "George-Herman-Ruth"
153
138
  ```
154
139
 
155
- ##### `:track`
140
+ ##### `:callback`
156
141
  - Provides a callback function `#{attribute_name}_change` to allow you to persist old slugs as you please.
157
142
  - Default: false
158
143
  - Example:
@@ -160,13 +145,12 @@ The options hash is where you define the attribute's dependencies. It also uses
160
145
  ```
161
146
  Person = Struct.new(:first_name, :middle_name, :last_name) do
162
147
  include NaturalBornSlugger
163
- has_slug first_name: nil, middle_name: nil, last_name: nil, track: true
164
-
165
148
  attr_accessor :formerly_known_as
166
- def slug_change(old_slug, new_slug)
167
- @formerly_known_as ||= []
168
- @formerly_known_as << old_slug
149
+ has_slug first_name: nil, middle_name: nil, last_name: nil, callback: ->(old_name, new_name) do
150
+ self.formerly_known_as ||= []
151
+ self.formerly_known_as << old_name
169
152
  end
153
+
170
154
  end
171
155
 
172
156
  bambino = Person.new('George', 'Herman', 'Ruth')
@@ -179,4 +163,4 @@ The options hash is where you define the attribute's dependencies. It also uses
179
163
 
180
164
  ##### _Note:_
181
165
 
182
- If you happen to have methods or attributes called `join_with`, `compact`, `require_all`, or `track`, you can still build composite attributes out of them. Just use a string instead of a symbol when declaring your attribute's dependencies. `NaturalBornSlugger` only looks for symbols when reading your dependencies for these settings.
166
+ If you happen to have methods or attributes called `join_with`, `require_all`, or `callback`, you can still build composite attributes out of them. Just use a string instead of a symbol when declaring your attribute's dependencies. `NaturalBornSlugger` only looks for symbols when reading your dependencies for these settings.
@@ -0,0 +1,116 @@
1
+ module NaturalBornSlugger
2
+ class AttributeComposer
3
+
4
+ def initialize(name, options)
5
+ @name = name.to_s
6
+ @dependencies, options = self.class.extract_dependencies_from_options(options)
7
+ options.each do |option, value|
8
+ self.instance_variable_set("@#{option}", value)
9
+ end
10
+ raise ConfigurationError.new(self.name, name, "no dependent attributes were specified") if @dependencies.empty?
11
+ end
12
+
13
+ def self.default_options
14
+ {
15
+ require_all: false,
16
+ join_with: '',
17
+ callback: false
18
+ }
19
+ end
20
+
21
+ def self.extract_dependencies_from_options(dependencies={})
22
+ options = default_options.dup
23
+ options.keys.each do |option|
24
+ if dependencies.has_key? option
25
+ options[option] = dependencies.delete(option)
26
+ end
27
+ end
28
+ [dependencies, options]
29
+ end
30
+
31
+ def self.resolve_dependency(object, dependency)
32
+ dependency_chain = dependency.to_s.split('.')
33
+ dependency_chain.each do |method|
34
+ object = object.try :send, method
35
+ break unless object
36
+ end
37
+ object
38
+ end
39
+
40
+
41
+ def compose_attribute(resolved_dependencies)
42
+ resolved_dependencies.map do |resolved_dependency, strategy|
43
+ case strategy
44
+ when Symbol # Symbols represent string methods to call on the resolved dependency
45
+ resolved_dependency.to_s.send(strategy)
46
+ when String # Strings represent formats to fit the resolved dependency into
47
+ strategy % resolved_dependency
48
+ when Regexp # Regexps represent patterns to pull out of the resolved dependency and join
49
+ resolved_dependency.scan(strategy).join(@join_with)
50
+ when Proc # Procs should take one parameter and return a string or nil
51
+ strategy.call(resolved_dependency)
52
+ else # If no strategy provided, use resolved dependency as is
53
+ resolved_dependency.to_s
54
+ end
55
+ # Remove nil components if `compact_dependencies` is true
56
+ end.reject{|string| not string or string.empty? }.join(@join_with)
57
+ end
58
+
59
+ def evaluate(object)
60
+ resolved_dependencies = @dependencies.map do |dependency, strategy|
61
+ [self.class.resolve_dependency(object, dependency), strategy]
62
+ end
63
+ # Check existence of all attribute dependencies if `require_all` is true
64
+ if @require_all ? resolved_dependencies.map(&:first).all? : true
65
+ compose_attribute(resolved_dependencies)
66
+ end
67
+ end
68
+
69
+ def callback(object, old_value, new_value)
70
+ if @callback
71
+ unless old_value == new_value
72
+ object.instance_exec old_value, new_value, &@callback
73
+ end
74
+ end
75
+ end
76
+
77
+ ##
78
+ # Adds composite attribute methods to the class:
79
+ # a getter, and updater method.
80
+ # Also adds a setter that either calls the updater
81
+ # or throws an error, depending on configuration
82
+ def add_to(klass)
83
+
84
+ class << klass
85
+ attr_accessor :composite_attributes
86
+ end
87
+ klass.composite_attributes ||= {}
88
+ klass.composite_attributes[@name] = self
89
+
90
+ # Define instance attribute getter
91
+ klass.send :define_method, @name do
92
+ name = __method__
93
+ self.send "update_#{name}"
94
+ end
95
+
96
+ # Define instance attribute setter: ignores assignment and just triggers an update
97
+ klass.send :define_method, "#{@name}=" do |value|
98
+ name = __method__.to_s.gsub '=', ''
99
+ self.send "update_#{name}"
100
+ end
101
+
102
+ # Update instance attribute
103
+ klass.send :define_method, "update_#{@name}" do
104
+ name = __method__.to_s.gsub 'update_', ''
105
+ composer = self.class.composite_attributes[name]
106
+ old_value = self.instance_variable_get("@#{name}")
107
+ new_value = composer.evaluate(self)
108
+ self.instance_variable_set("@#{name}", new_value)
109
+ composer.callback(self, old_value, new_value)
110
+ new_value
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+ end
@@ -1,3 +1,5 @@
1
+ require "natural_born_slugger/attribute_composer"
2
+
1
3
  module NaturalBornSlugger
2
4
  module ClassMethods
3
5
 
@@ -7,8 +9,7 @@ module NaturalBornSlugger
7
9
  def has_slug(name, options={})
8
10
  # Use default name if not provided
9
11
  name, options = 'slug', name if name.is_a?(Hash)
10
- dependencies, options = extract_composite_dependencies(name, options)
11
- build_composite_attribute(name.to_s, dependencies, options)
12
+ NaturalBornSlugger::AttributeComposer.new(name, options).add_to(self)
12
13
  end
13
14
 
14
15
  ##
@@ -17,84 +18,14 @@ module NaturalBornSlugger
17
18
  def has_natural_key(name, options={})
18
19
  # Use default name if not provided
19
20
  name, options = 'natural_key', name if name.is_a?(Hash)
20
- dependencies, options = extract_composite_dependencies(name, options)
21
- build_composite_attribute(name.to_s, dependencies, options)
21
+ NaturalBornSlugger::AttributeComposer.new(name, options).add_to(self)
22
22
  end
23
23
 
24
24
  ##
25
25
  # Adds a generic composite attribute to the class. Name is required.
26
26
  #
27
27
  def has_composite_attribute(name, options={})
28
- dependencies, options = extract_composite_dependencies(name, options)
29
- build_composite_attribute(name.to_s, dependencies, options)
30
- end
31
-
32
- private
33
-
34
- ##
35
- # Pulls method behavior options out of general options. The remaining options
36
- # are assumed to be the dependent attributes that compose this one.
37
- #
38
- def extract_composite_dependencies(name, options={})
39
- dependencies, options = options, {}
40
-
41
- options[:compact_dependencies] = dependencies.delete(:compact) || true
42
- options[:require_dependencies] = dependencies.delete(:require_all) || false
43
- options[:track_changes] = dependencies.delete(:track) || false
44
- options[:joiner] = dependencies.delete(:join_with) || ''
45
-
46
- raise ConfigurationError.new(self.name, name, "no dependent attributes were specified") if dependencies.empty?
47
-
48
- [dependencies, options]
49
- end
50
-
51
- ##
52
- # Adds a composite attribute to the class,
53
- # with a getter and updater method.
54
- # Also adds a setter that either calls the updater
55
- # or throws an error, depending on configuration.
56
- #
57
- def build_composite_attribute(name, dependencies, options)
58
-
59
- # Define instance attribute getter
60
- define_method name do
61
- self.send "update_#{name}"
62
- end
63
-
64
- # Define instance attribute setter: ignores assignment and just triggers an update
65
- define_method "#{name}=" do |value|
66
- if NaturalBornSlugger.configuration.ignore_attribute_setters
67
- # TODO: Log discarded value warning
68
- self.send "update_#{name}"
69
- else
70
- raise IllegalOperationError.new(self.class.name, "#{name}=", 'you cannot set composite attributes directly')
71
- end
72
- end
73
-
74
- # Update instance attribute
75
- define_method "update_#{name}" do
76
- # Check existence of all attribute dependencies if `require_dependencies` is true
77
- resolved_dependencies = dependencies.map do |dependency, strategy|
78
- [resolve_dependency(dependency), strategy]
79
- end
80
- if options[:require_dependencies] ? resolved_dependencies.map(&:first).all? : true
81
- new_value = self.compose_attribute(resolved_dependencies, options)
82
- if options[:track_changes]
83
- old_value = self.instance_variable_get("@#{name}")
84
- unless old_value == new_value
85
- self.send("#{name}_change".to_sym, old_value, new_value)
86
- end
87
- end
88
- self.instance_variable_set("@#{name}", new_value)
89
- end
90
- end
91
-
92
- if [:track_changes]
93
- define_method "#{name}_change" do |old_value, new_value|
94
-
95
- end
96
- end
97
-
28
+ NaturalBornSlugger::AttributeComposer.new(name, options).add_to(self)
98
29
  end
99
30
 
100
31
  end
@@ -1,11 +1,14 @@
1
+ require 'logger'
2
+
1
3
  module NaturalBornSlugger
2
4
  class Configuration
3
5
 
4
- attr_accessor :ignore_attribute_setters, :hashified_length
6
+ attr_accessor :ignore_attribute_setters, :hashified_length, :logger
5
7
 
6
8
  def initialize
7
9
  @ignore_attribute_setters = true
8
10
  @hashified_length = 7
11
+ @logger = Logger.new(STDERR)
9
12
  end
10
13
 
11
14
  end
@@ -1,4 +1,5 @@
1
- require 'active_support/inflector/transliterate'
1
+ require 'active_support/inflector'
2
+
2
3
  class String
3
4
 
4
5
  alias_method :dashify, :parameterize
@@ -1,3 +1,3 @@
1
1
  module NaturalBornSlugger
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'active_support/core_ext/object/try'
2
3
 
3
4
  require "natural_born_slugger/exceptions"
4
5
  require "natural_born_slugger/configuration"
@@ -14,8 +15,7 @@ module NaturalBornSlugger
14
15
 
15
16
  yield(configuration) if block_given?
16
17
 
17
- require "natural_born_slugger/class_methods"
18
- require "natural_born_slugger/instance_methods"
18
+ require_internals!
19
19
 
20
20
  configuration
21
21
  end
@@ -27,6 +27,12 @@ module NaturalBornSlugger
27
27
  def self.included(base)
28
28
  base.extend ClassMethods
29
29
  end
30
+
31
+ private
32
+
33
+ def self.require_internals!
34
+ require "natural_born_slugger/class_methods"
35
+ end
30
36
  end
31
37
 
32
38
  require "natural_born_slugger/extensions/string"
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "yard", "~> 0.8"
24
24
  spec.add_development_dependency "redcarpet", "~> 2.2"
25
25
  spec.add_development_dependency "rspec", "~> 2.13"
26
+ spec.add_development_dependency "pry"
26
27
 
27
28
  spec.add_dependency 'activesupport', '~> 3.1'
28
29
  end
@@ -0,0 +1,70 @@
1
+ describe NaturalBornSlugger::AttributeComposer do
2
+
3
+ context 'class methods' do
4
+ subject(:composer){ NaturalBornSlugger::AttributeComposer }
5
+
6
+ describe ".default_options" do
7
+ it "should not require that all dependent attributes be present to form composite" do
8
+ composer.composite_options[:require_all].should be_false
9
+ end
10
+ it "should not join depencencies with a special character" do
11
+ composer.composite_options[:join_with].should be_empty
12
+ end
13
+ it "should not use a callback" do
14
+ composer.composite_options[:callback].should be_false
15
+ end
16
+ end
17
+
18
+ describe ".extract_dependencies_from_options" do
19
+ let(:empty_opts) { {} }
20
+ let(:simple_opts) { {name: 'foobar', title: 'asdf'} }
21
+ let(:config_opts) { {require_all: true, join_with: '^'} }
22
+ let(:mixed_opts) { {name: 'foobar', title: 'asdf', require_all: true, join_with: '^'} }
23
+ it "should always return 3 options" do
24
+ [empty_opts, simple_opts, config_opts, mixed_opts].each do |options|
25
+ _, opts = composer.extract_dependencies_from_options(options)
26
+ opts.length.should eql composer.composite_options.length
27
+ end
28
+ end
29
+ end
30
+
31
+ describe ".resolve_dependency" do
32
+ let(:example_object) { Example.new }
33
+ it "should retrieve attributes listed as a dependency" do
34
+ composer.resolve_dependency(example_object, 'attribute').should == 'attribute'
35
+ end
36
+ it "should use the results of methods listed as a dependency" do
37
+ composer.resolve_dependency(example_object, 'meth').should == 'method'
38
+ end
39
+ it "should accept methods that return objects as a dependency" do
40
+ composer.resolve_dependency(example_object, 'child').should be_an ExampleChild
41
+ end
42
+ context "through related objects via dot syntax" do
43
+ it "should resolve a related object's attributes" do
44
+ composer.resolve_dependency(example_object, 'child.attribute').should == 'child attribute'
45
+ end
46
+ it "should resolve a related object's methods" do
47
+ composer.resolve_dependency(example_object, 'child.meth').should == 'child method'
48
+ end
49
+ it "should resolve a related object's own related objects" do
50
+ composer.resolve_dependency(example_object, 'child.child').should be_an ExampleGrandChild
51
+ end
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+
58
+ context 'instance methods' do
59
+
60
+ describe '#compose_attribute' do
61
+
62
+ end
63
+
64
+ describe '#evaluate' do
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
File without changes
@@ -0,0 +1,18 @@
1
+ describe NaturalBornSlugger::Configuration do
2
+ subject(:config) { NaturalBornSlugger.configuration }
3
+
4
+ describe "the default configuration" do
5
+
6
+ it "should ignore attribute setters" do
7
+ config.ignore_attribute_setters.should be_true
8
+ end
9
+ it "should truncate hashed values at 7" do
10
+ config.hashified_length.should eql(7)
11
+ end
12
+ it "should have a basic logger" do
13
+ config.logger.should be_a(Logger)
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,5 @@
1
+ describe String do
2
+ subject { 'foobar' }
3
+ it { should respond_to :dashify }
4
+ it { should respond_to :hashify }
5
+ end
@@ -0,0 +1,17 @@
1
+ describe NaturalBornSlugger do
2
+ subject(:library) { NaturalBornSlugger }
3
+
4
+ context "in order to be configurable" do
5
+ it { should respond_to :configuration }
6
+ it { should respond_to :configure }
7
+
8
+ it "should require library internals after configuration" do
9
+ library.should_receive(:require_internals!)
10
+ library.configure
11
+ end
12
+ end
13
+
14
+ context "in order to write to logs" do
15
+ it { should respond_to :logger }
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ require 'pry'
2
+ require 'rspec'
3
+ require 'natural_born_slugger'
4
+
5
+ NaturalBornSlugger.configure
6
+ require 'support/example'
7
+
8
+ RSpec.configure
@@ -0,0 +1,36 @@
1
+ class Example
2
+ include NaturalBornSlugger
3
+ attr_accessor :attribute
4
+ def initialize
5
+ @attribute = 'attribute'
6
+ end
7
+ def meth
8
+ 'method'
9
+ end
10
+ def child
11
+ ExampleChild.new
12
+ end
13
+ end
14
+
15
+ class ExampleChild
16
+ attr_accessor :attribute
17
+ def initialize
18
+ @attribute = 'child attribute'
19
+ end
20
+ def meth
21
+ 'child method'
22
+ end
23
+ def child
24
+ ExampleGrandChild.new
25
+ end
26
+ end
27
+
28
+ class ExampleGrandChild
29
+ attr_accessor :attribute
30
+ def initialize
31
+ @attribute = 'grandchild attribute'
32
+ end
33
+ def meth
34
+ 'grandchild method'
35
+ end
36
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: natural_born_slugger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Keele
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-18 00:00:00.000000000 Z
11
+ date: 2013-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.13'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: activesupport
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -103,19 +117,26 @@ extensions: []
103
117
  extra_rdoc_files: []
104
118
  files:
105
119
  - .gitignore
106
- - .yardopts
120
+ - .rspec
107
121
  - Gemfile
108
122
  - LICENSE.md
109
123
  - README.md
110
124
  - Rakefile
111
125
  - lib/natural_born_slugger.rb
126
+ - lib/natural_born_slugger/attribute_composer.rb
112
127
  - lib/natural_born_slugger/class_methods.rb
113
128
  - lib/natural_born_slugger/configuration.rb
114
129
  - lib/natural_born_slugger/exceptions.rb
115
130
  - lib/natural_born_slugger/extensions/string.rb
116
- - lib/natural_born_slugger/instance_methods.rb
117
131
  - lib/natural_born_slugger/version.rb
118
132
  - natural_born_slugger.gemspec
133
+ - spec/natural_born_slugger/attribute_builder_spec.rb
134
+ - spec/natural_born_slugger/class_methods_spec.rb
135
+ - spec/natural_born_slugger/configuration_spec.rb
136
+ - spec/natural_born_slugger/extensions/string_spec.rb
137
+ - spec/natural_born_slugger_spec.rb
138
+ - spec/spec_helper.rb
139
+ - spec/support/example.rb
119
140
  homepage: ''
120
141
  licenses:
121
142
  - MIT
@@ -141,5 +162,12 @@ signing_key:
141
162
  specification_version: 4
142
163
  summary: Easily define automatically-updated composed attributes. Includes ORM helpers
143
164
  and a Rack-based URL redirector.
144
- test_files: []
165
+ test_files:
166
+ - spec/natural_born_slugger/attribute_builder_spec.rb
167
+ - spec/natural_born_slugger/class_methods_spec.rb
168
+ - spec/natural_born_slugger/configuration_spec.rb
169
+ - spec/natural_born_slugger/extensions/string_spec.rb
170
+ - spec/natural_born_slugger_spec.rb
171
+ - spec/spec_helper.rb
172
+ - spec/support/example.rb
145
173
  has_rdoc:
data/.yardopts DELETED
@@ -1 +0,0 @@
1
- - LICENSE.md
@@ -1,33 +0,0 @@
1
- module NaturalBornSlugger
2
-
3
- def resolve_dependency(dependency)
4
- object = self
5
- dependency_chain = dependency.to_s.split('.')
6
- dependency_chain.each do |method|
7
- object = object.try :send, method
8
- break unless object
9
- end
10
- object
11
- end
12
-
13
- def compose_attribute(resolved_dependencies, options)
14
- resolved_dependencies.map do |resolved_dependency, strategy|
15
- case strategy
16
- when Symbol # Symbols represent string methods to call on the resolved dependency
17
- resolved_dependency.to_s.send(strategy)
18
- when String # Strings represent formats to fit the resolved dependency into
19
- strategy % resolved_dependency
20
- when Regexp # Regexps represent patterns to pull out of the resolved dependency and join
21
- resolved_dependency.scan(strategy).join(options[:joiner])
22
- when Proc # Procs should take one parameter and return a string or nil
23
- strategy.call(resolved_dependency)
24
- else # If no strategy provided, use resolved dependency as is
25
- resolved_dependency.to_s
26
- end
27
- # Remove nil components if `compact_dependencies` is true
28
- end.tap do |components|
29
- components.compact! if options[:compact_dependencies]
30
- end.join(options[:joiner])
31
- end
32
-
33
- end