assembler 1.0.0 → 1.1.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/.travis.yml +2 -2
- data/CHANGES.md +6 -0
- data/README.md +95 -30
- data/lib/assembler.rb +26 -5
- data/lib/assembler/version.rb +1 -1
- data/spec/assembler_spec.rb +24 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 459053f97aea6e47c8993857b8bdb82695c39354
|
|
4
|
+
data.tar.gz: eb0b24fda83cfe8b556a97f0cdcd5108af2970b7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6a52ab6904aec79e71a8725aded5372880c75172c52a3101c6794b50a8bd5e4520a12f20d8e7ae4fe4c369376b1d6e5d2c8a4440679e5a62611aa0bf8cb4d3ec
|
|
7
|
+
data.tar.gz: 4566485a70fc557fb3321bf0586d58e11f1f69f041f946ce166b7e34d7188e5df3d2ab664683142e54def16f3b6e014912e94d5479aec5e18c07836ba97979a0
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
data/README.md
CHANGED
|
@@ -17,10 +17,10 @@ care of storing the parameters and gives you private accessors, too.
|
|
|
17
17
|
You use it like this:
|
|
18
18
|
|
|
19
19
|
```ruby
|
|
20
|
-
class
|
|
20
|
+
class IMAPConnection
|
|
21
21
|
extend Assembler
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
assemble_from :hostname, use_ssl: true, port: nil
|
|
24
24
|
|
|
25
25
|
# Additional business logic here...
|
|
26
26
|
end
|
|
@@ -31,51 +31,116 @@ For example:
|
|
|
31
31
|
|
|
32
32
|
```ruby
|
|
33
33
|
# These two are equivalent:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
aw.
|
|
34
|
+
IMAPConnection.new(hostname: 'imap.example.com')
|
|
35
|
+
IMAPConnection.new do |aw|
|
|
36
|
+
aw.hostname = 'imap.example.com'
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
# These two are equivalent:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
aw.
|
|
43
|
-
aw.
|
|
40
|
+
IMAPConnection.new(hostname: 'imap.example.com', use_ssl: false)
|
|
41
|
+
IMAPConnection.new do |aw|
|
|
42
|
+
aw.hostname = 'imap.example.com'
|
|
43
|
+
aw.use_ssl = false
|
|
44
44
|
end
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Note that when we set `use_ssl` to `false`, the code respects that, rather than
|
|
48
|
+
over-writing anything falsey with the default. If you don't want that, override
|
|
49
|
+
it like with `port`, below.
|
|
50
|
+
|
|
51
|
+
You get private `attr_reader`s for the parameters you specify, but you can
|
|
52
|
+
always override them, if you like. You might have this lower down in your
|
|
53
|
+
`IMAPConnection` class:
|
|
48
54
|
|
|
49
55
|
```ruby
|
|
50
|
-
class
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
class IMAPConnection
|
|
57
|
+
attr_reader :hostname # makes `hostname` public
|
|
58
|
+
|
|
59
|
+
def ssl?
|
|
60
|
+
!!use_ssl
|
|
61
|
+
end
|
|
53
62
|
|
|
54
|
-
def
|
|
55
|
-
|
|
63
|
+
def port
|
|
64
|
+
@port ||= ssl? ? 993 : 143
|
|
56
65
|
end
|
|
57
66
|
end
|
|
67
|
+
```
|
|
58
68
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
foo.name = name
|
|
62
|
-
foo.awesome = awesome
|
|
69
|
+
These various syntaxes enable some trickery when you're dealing with a world of
|
|
70
|
+
uncertainty. Let's look at a more complicated example.
|
|
63
71
|
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
Say we've got a class that lets us describe an Elastic Load Balancer for Amazon
|
|
73
|
+
Web Services. There's a lot of complexity in what each of these arguments might
|
|
74
|
+
be, but the key thing for our example is this: If you have `subnets`, you
|
|
75
|
+
shouldn't have `availability_zones` and if you have `availability_zones`, you
|
|
76
|
+
shouldn't have `subnets`. And, importantly, you shouldn't send in extraneous
|
|
77
|
+
keys.
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
class AmazonELB
|
|
81
|
+
extend Assembler
|
|
82
|
+
assemble_from(
|
|
83
|
+
:name,
|
|
84
|
+
load_balancer_name: nil,
|
|
85
|
+
health_check: nil,
|
|
86
|
+
listeners: nil,
|
|
87
|
+
security_groups: nil,
|
|
88
|
+
instances: nil,
|
|
89
|
+
subnets: nil,
|
|
90
|
+
availability_zones: nil,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Additional, complex business logic...
|
|
66
94
|
end
|
|
67
95
|
```
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
97
|
+
Now, since there's a lot of complexity in what each of these arguments might be,
|
|
98
|
+
say we've developed some best-practices about what each of them should be. And
|
|
99
|
+
we want to make it easy to pop off slight variations on what we consider to be a
|
|
100
|
+
"standard" ELB.
|
|
101
|
+
|
|
102
|
+
``` ruby
|
|
103
|
+
module ELBFactory
|
|
104
|
+
def self.make_me_an_elb(subnet_ids=nil, availability_zones=nil, name_prefix='', instance_ids=[], security_groups=[])
|
|
105
|
+
AmazonELB.new do |elb|
|
|
106
|
+
elb.name = name(name_prefix)
|
|
107
|
+
elb.load_balancer_name = name(name_prefix)
|
|
108
|
+
elb.security_groups = security_groups
|
|
109
|
+
elb.instance_ids = instance_ids
|
|
110
|
+
|
|
111
|
+
elb.health_check = HealthCheck.new (
|
|
112
|
+
target: 'HTTP:8000/',
|
|
113
|
+
healthy_threshold: '3',
|
|
114
|
+
unhealthy_threshold: '5',
|
|
115
|
+
interval: '30',
|
|
116
|
+
timeout: '5'
|
|
117
|
+
)
|
|
118
|
+
elb.listeners = [Listener.new(...), Listener.new(...)]
|
|
119
|
+
|
|
120
|
+
if subnet_ids
|
|
121
|
+
elb.subnets = subnet_ids
|
|
122
|
+
else
|
|
123
|
+
elb.availability_zones = availability_zones
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def self.name(name_prefix)
|
|
129
|
+
"#{sanitize_for_name(name_prefix)}LoadBalancer"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def self.sanitize_for_name(string)
|
|
133
|
+
# ...
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
```
|
|
73
137
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
138
|
+
Note the `if`/`else` block near the end of the initialization block. If the
|
|
139
|
+
initialization method only took hashes, you would either have to wrap object
|
|
140
|
+
creation in an `if`/`else` and repeat all the constructor arguments that were
|
|
141
|
+
shared between the two cases, or else pre-construct your argument hash, which
|
|
142
|
+
would look similar to the above, but require you to assign an intermediate
|
|
143
|
+
variable for no semantic benefit.
|
|
79
144
|
|
|
80
145
|
|
|
81
146
|
## Contributing
|
data/lib/assembler.rb
CHANGED
|
@@ -2,16 +2,37 @@ require "assembler/version"
|
|
|
2
2
|
require "assembler/initializer"
|
|
3
3
|
|
|
4
4
|
module Assembler
|
|
5
|
-
|
|
5
|
+
attr_writer :required_params, :optional_params
|
|
6
|
+
|
|
7
|
+
def assemble_from(*args)
|
|
8
|
+
optional = args.last.is_a?(Hash) ? args.pop : {}
|
|
9
|
+
required = args
|
|
6
10
|
|
|
7
|
-
def assembler_initializer(*required, **optional)
|
|
8
11
|
include Assembler::Initializer
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@all_param_names = (required + optional.keys).map(&:to_sym)
|
|
13
|
+
self.required_params += required
|
|
14
|
+
self.optional_params = optional_params.merge(optional)
|
|
13
15
|
|
|
14
16
|
attr_reader *all_param_names
|
|
15
17
|
private *all_param_names
|
|
16
18
|
end
|
|
19
|
+
alias_method :assemble_with, :assemble_from
|
|
20
|
+
|
|
21
|
+
def assembler_initializer(*args)
|
|
22
|
+
caller_file, caller_line, _ = caller.first.split(':')
|
|
23
|
+
warn "The `assembler_initializer` method is deprecated and will be phased out in version 2.0. Please use `assemble_from` instead. Called from #{caller_file}:#{caller_line}."
|
|
24
|
+
assemble_from(*args)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def required_params
|
|
28
|
+
@required_params ||= []
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def optional_params
|
|
32
|
+
@optional_params ||= {}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def all_param_names
|
|
36
|
+
(required_params + optional_params.keys).map(&:to_sym)
|
|
37
|
+
end
|
|
17
38
|
end
|
data/lib/assembler/version.rb
CHANGED
data/spec/assembler_spec.rb
CHANGED
|
@@ -2,13 +2,13 @@ require 'spec_helper'
|
|
|
2
2
|
require 'assembler'
|
|
3
3
|
|
|
4
4
|
describe Assembler do
|
|
5
|
-
describe "#
|
|
5
|
+
describe "#assemble_from" do
|
|
6
6
|
context "without parameters" do
|
|
7
7
|
subject do
|
|
8
8
|
Class.new do
|
|
9
9
|
extend Assembler
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
assemble_from
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -30,7 +30,7 @@ describe Assembler do
|
|
|
30
30
|
Class.new do
|
|
31
31
|
extend Assembler
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
assemble_from :foo, bar: 'bar'
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -83,5 +83,26 @@ describe Assembler do
|
|
|
83
83
|
}.to raise_error(NoMethodError)
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
|
+
|
|
87
|
+
context "when called more than once" do
|
|
88
|
+
subject do
|
|
89
|
+
Class.new do
|
|
90
|
+
extend Assembler
|
|
91
|
+
|
|
92
|
+
assemble_from :foo
|
|
93
|
+
assemble_from bar: 'bar'
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "still takes both arguments" do
|
|
98
|
+
built_object = subject.new do |builder|
|
|
99
|
+
builder.foo = 'baz'
|
|
100
|
+
builder.bar = 'qux'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
expect(built_object.instance_variable_get(:@foo)).to eq('baz')
|
|
104
|
+
expect(built_object.instance_variable_get(:@bar)).to eq('qux')
|
|
105
|
+
end
|
|
106
|
+
end
|
|
86
107
|
end
|
|
87
108
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: assembler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ben Hamill
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-03-
|
|
11
|
+
date: 2014-03-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|