industrialist 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +88 -7
- data/lib/industrialist/factory.rb +5 -1
- data/lib/industrialist/manufacturable.rb +9 -4
- data/lib/industrialist/version.rb +1 -1
- data/lib/industrialist/warning_helper.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 858f0f4e068299c8eab65bf53cc4b78b5d582ad1a36a81bd85c41654c21e9855
|
|
4
|
+
data.tar.gz: ed03501fc2ab8f74f5ac29d1e47675ac77977e5c859a5a9ddd9701b28afdbc70
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 751a1bbef0a2f80b1936d0b23608880fd5a3cec7a4dcdeea0d8f705c96a4c86d37c5576364cf484159054be6845deadb3bb038fb298daa959d96fe7add723877
|
|
7
|
+
data.tar.gz: 8ec6e11e6851d7f17a0f7e92e3ebb6e246daab3b747534cf365ea623a1d4ff3390a202cdb92d7e815320b3062439fe82a0981a06837e19c0f93d98822f35e170
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -36,7 +36,7 @@ end
|
|
|
36
36
|
AutomobileFactory.build(:sedan)
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Another way to do this is with a hash:
|
|
40
40
|
|
|
41
41
|
```ruby
|
|
42
42
|
class Sedan; end
|
|
@@ -60,9 +60,23 @@ AutomobileFactory.build(:coupe)
|
|
|
60
60
|
|
|
61
61
|
But, both of these approaches require you to maintain your factory by hand. In order to extend these factories, you must modify them, which violates the Open/Closed Principle.
|
|
62
62
|
|
|
63
|
+
The Ruby way to do this is with conventions and metaprogramming:
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
class AutomobileFactory
|
|
67
|
+
def self.build(automobile_type, *args)
|
|
68
|
+
Object.get_const("#{automobile_type.capitalize}").new(*args)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
But, factories of this type also have issues. If your keys are not easily mapped to a convention, you won't be able to use this type of factory. For example, the `Cabriolet` class above corresponds to the key `:convertible`.
|
|
74
|
+
|
|
75
|
+
You can find a deeper dive into the motivations behind Industrialst [here](https://engineering.entelo.com/extension-without-modification-cb0f9cfb64a3).
|
|
76
|
+
|
|
63
77
|
## Usage
|
|
64
78
|
|
|
65
|
-
Industrialist creates factories for you. Just include the Manufacturable module in a base class and
|
|
79
|
+
Industrialist creates factories for you. Just include the Manufacturable module in a base class and call `create_factory` with a name. Industrialist also allows children of the base class to register themselves with the factory by specifying their corresponding key.
|
|
66
80
|
|
|
67
81
|
```ruby
|
|
68
82
|
class Automobile
|
|
@@ -78,11 +92,71 @@ class Coupe < Automobile
|
|
|
78
92
|
corresponds_to :coupe
|
|
79
93
|
end
|
|
80
94
|
|
|
95
|
+
AutomobileFactory.build(:sedan) # => #<Sedan:0x00007ff64d88ce58>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Manufacturable classes may also correspond to multiple keys:
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
81
101
|
class Cabriolet < Automobile
|
|
102
|
+
corresponds_to :cabriolet
|
|
82
103
|
corresponds_to :convertible
|
|
83
104
|
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
By default, Industrialist factories will return `nil` when built with an unregistered key. If you would instead prefer a default object, you can designate a `manufacturable_default`.
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
class Airplane
|
|
111
|
+
include Industrialist::Manufacturable
|
|
112
|
+
create_factory :AirplaneFactory
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class Biplane < Airplane
|
|
116
|
+
manufacturable_default
|
|
117
|
+
corresponds_to :biplane
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
class FighterJet < Airplane
|
|
121
|
+
corresponds_to :fighter
|
|
122
|
+
end
|
|
84
123
|
|
|
85
|
-
|
|
124
|
+
AirplaneFactory.build(:plane) # => #<Biplane:0x00007ffcd4165610>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Finally, Industrialist will accept any Ruby object as a key, which is handy when you need to define more complex keys. For example, you could use a hash:
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
class Train
|
|
131
|
+
include Industrialist::Manufacturable
|
|
132
|
+
create_factory :TrainFactory
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
class SteamEngine < Train
|
|
136
|
+
corresponds_to engine: :steam
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
class Diesel < Train
|
|
140
|
+
corresponds_to engine: :diesel
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class Boxcar < Train
|
|
144
|
+
corresponds_to cargo: :boxcar
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class Carriage < Train
|
|
148
|
+
corresponds_to passenger: :carriage
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class Sleeper < Train
|
|
152
|
+
corresponds_to passenger: :sleeper
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def train_car(role, type)
|
|
156
|
+
TrainFactory.build(role => type)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
train_car(:engine, :diesel) # => #<Diesel:0x00007ff64f846640>
|
|
86
160
|
```
|
|
87
161
|
|
|
88
162
|
## Installation
|
|
@@ -101,15 +175,22 @@ Or install it yourself as:
|
|
|
101
175
|
|
|
102
176
|
$ gem install industrialist
|
|
103
177
|
|
|
104
|
-
|
|
178
|
+
If you are using Industrialist with Rails, you'll need to preload your manufacturable objects in the development and test environments in an intializer, like this:
|
|
105
179
|
|
|
106
|
-
|
|
180
|
+
```ruby
|
|
181
|
+
def require_factory(class_type)
|
|
182
|
+
Dir[Rails.root.join('app', "#{class_type}", '**', '*.rb').to_s].each { |file| require file }
|
|
183
|
+
end
|
|
107
184
|
|
|
108
|
-
|
|
185
|
+
if %w(development test).include?(Rails.env)
|
|
186
|
+
require_factory('automobiles')
|
|
187
|
+
require_factory('books')
|
|
188
|
+
end
|
|
189
|
+
```
|
|
109
190
|
|
|
110
191
|
## Contributing
|
|
111
192
|
|
|
112
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/entelo/industrialist.
|
|
193
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/entelo/industrialist.
|
|
113
194
|
|
|
114
195
|
## License
|
|
115
196
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
module Industrialist
|
|
2
2
|
class Factory
|
|
3
|
+
DEFAULT_KEY = :__manufacturable_default__
|
|
4
|
+
|
|
3
5
|
attr_reader :registry
|
|
4
6
|
|
|
5
7
|
def initialize
|
|
@@ -11,10 +13,12 @@ module Industrialist
|
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def build(key, *args)
|
|
14
|
-
klass = registry[factory_key(key)]
|
|
16
|
+
klass = registry[factory_key(key)] || registry[DEFAULT_KEY]
|
|
15
17
|
klass&.new(*args)
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
private
|
|
21
|
+
|
|
18
22
|
def factory_key(key)
|
|
19
23
|
(key.respond_to?(:to_sym) && key.to_sym) || key
|
|
20
24
|
end
|
|
@@ -3,12 +3,11 @@ require 'industrialist/warning_helper'
|
|
|
3
3
|
|
|
4
4
|
module Industrialist
|
|
5
5
|
module Manufacturable
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
ALREADY_INCLUDED_WARNING_MESSAGE = 'warning: a factory is already defined on this class hierarchy'.freeze
|
|
6
|
+
ALREADY_INCLUDED_WARNING_MESSAGE = 'warning: overriding previously defined factory on this class hierarchy'.freeze
|
|
7
|
+
MULTIPLE_DEFAULT_WARNING_MESSAGE = 'warning: overriding a previously registered default class'.freeze
|
|
9
8
|
|
|
10
9
|
def self.included(base)
|
|
11
|
-
warning(ALREADY_INCLUDED_WARNING_MESSAGE) if base.class_variable_defined?(:@@factory)
|
|
10
|
+
WarningHelper.warning(ALREADY_INCLUDED_WARNING_MESSAGE) if base.class_variable_defined?(:@@factory)
|
|
12
11
|
|
|
13
12
|
base.extend ClassMethods
|
|
14
13
|
base.class_variable_set(:@@factory, Industrialist::Factory.new)
|
|
@@ -23,6 +22,12 @@ module Industrialist
|
|
|
23
22
|
factory.register(key, self)
|
|
24
23
|
end
|
|
25
24
|
|
|
25
|
+
def manufacturable_default
|
|
26
|
+
WarningHelper.warning(MULTIPLE_DEFAULT_WARNING_MESSAGE) if factory.registry[Industrialist::Factory::DEFAULT_KEY]
|
|
27
|
+
|
|
28
|
+
factory.register(Industrialist::Factory::DEFAULT_KEY, self)
|
|
29
|
+
end
|
|
30
|
+
|
|
26
31
|
def factory
|
|
27
32
|
class_variable_get(:@@factory)
|
|
28
33
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: industrialist
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alan Ridlehoover
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2019-03-
|
|
12
|
+
date: 2019-03-24 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: bundler
|