heed 0.0.8 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +4 -0
- data/README.md +35 -30
- data/{hark.gemspec → heed.gemspec} +5 -5
- data/lib/heed.rb +11 -0
- data/lib/{hark → heed}/ad_hoc.rb +1 -1
- data/lib/{hark → heed}/core_ext.rb +2 -2
- data/lib/{hark → heed}/dispatcher.rb +1 -1
- data/lib/{hark → heed}/listener.rb +1 -1
- data/lib/heed/version.rb +3 -0
- data/spec/{hark_spec.rb → heed_spec.rb} +4 -4
- metadata +13 -13
- data/lib/hark.rb +0 -11
- data/lib/hark/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1eee3efa688c2c5129607edf8cfa0f259921556d
|
4
|
+
data.tar.gz: 6af68b66b4511904cb27a555759ffa12295579df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cae07b49dc966fcdb17f1a0df686b79d3ed44a2a867802559bd035170f5f4218dd96ed0b2a8d82a94ca6e2ebbaf8254830b8469a51671b8c93d7528b68f957dd
|
7
|
+
data.tar.gz: 1873db35c58e1425834ec2d37a1d16c383874eec96420a9ad060be25f16b95d83ad54ca590ecaa0e8ef60f71d9eabf53d948feef5bcbc7b7d1e4686d5689f3ee
|
data/History.md
CHANGED
data/README.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
#
|
1
|
+
# `heed` (and `hark`)
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/
|
4
|
-
[![Build Status](https://travis-ci.org/ianwhite/
|
5
|
-
[![Dependency Status](https://gemnasium.com/ianwhite/
|
6
|
-
[![Code Climate](https://codeclimate.com/github/ianwhite/
|
7
|
-
[![Coverage Status](https://coveralls.io/repos/ianwhite/
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/heed.png)](https://rubygems.org/gems/heed)
|
4
|
+
[![Build Status](https://travis-ci.org/ianwhite/heed.png)](https://travis-ci.org/ianwhite/heed)
|
5
|
+
[![Dependency Status](https://gemnasium.com/ianwhite/heed.png)](https://gemnasium.com/ianwhite/heed)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/ianwhite/heed.png)](https://codeclimate.com/github/ianwhite/heed)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/ianwhite/heed/badge.png)](https://coveralls.io/r/ianwhite/heed)
|
8
8
|
|
9
|
-
Create
|
9
|
+
Create and use ad-hoc listeners with hark and heed.
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
13
|
Add this line to your application's Gemfile:
|
14
14
|
|
15
|
-
gem '
|
15
|
+
gem 'heed'
|
16
16
|
|
17
17
|
And then execute:
|
18
18
|
|
@@ -20,12 +20,12 @@ And then execute:
|
|
20
20
|
|
21
21
|
Or install it yourself as:
|
22
22
|
|
23
|
-
$ gem install
|
23
|
+
$ gem install heed
|
24
24
|
|
25
25
|
## What & Why?
|
26
26
|
|
27
|
-
**
|
28
|
-
The consumers of
|
27
|
+
**heed** enables you to use 'listener' objects very easily. It's for programming in the *hexagonal* or *tell, don't ask* style.
|
28
|
+
The consumers of heed listeners don't know anything about heed. Because heed makes it easy to create ad-hoc object, it's easy to get
|
29
29
|
started with a tell-dont-ask style, in rails controllers for example. For more detail see the 'Rationale' section.
|
30
30
|
|
31
31
|
## Usage
|
@@ -61,14 +61,14 @@ Or, a 'respond_to' style block
|
|
61
61
|
|
62
62
|
### Strict & lax listeners
|
63
63
|
|
64
|
-
By default,
|
64
|
+
By default, heed listeners are 'strict', they will only respond to the methods defined on them.
|
65
65
|
|
66
66
|
You create a 'lax' listener, responding to any message, by sending the `lax` message.
|
67
67
|
|
68
68
|
listener = hark(:foo) { "Foo" }
|
69
69
|
|
70
70
|
listener.bar
|
71
|
-
# => NoMethodError: undefined method `bar' for #<
|
71
|
+
# => NoMethodError: undefined method `bar' for #<Heed::StrictListener:0x007fc91a03e568>
|
72
72
|
|
73
73
|
listener = listener.lax
|
74
74
|
listener.bar
|
@@ -102,7 +102,7 @@ Combine with any object that support the same protocol
|
|
102
102
|
Turn any object into a listener, adding new methods as we go
|
103
103
|
|
104
104
|
hark UserLogger.new do |on|
|
105
|
-
on.created {|user| Emailer.
|
105
|
+
on.created {|user| Emailer.send_welcome_email(user) }
|
106
106
|
end
|
107
107
|
|
108
108
|
Now, when listener is sent #created, all create handlers are called.
|
@@ -125,7 +125,8 @@ You may use #heed to create an ad-hoc listener using a passed block as follows
|
|
125
125
|
end
|
126
126
|
|
127
127
|
If you want to combine listeners with an ad-hoc block, you may pass a 0-arity block that is
|
128
|
-
yielded as the listener
|
128
|
+
yielded as the listener. This means you can use the block to wire up listeners, adding
|
129
|
+
extra ones that have the caller's binding (useful in controllers for example)
|
129
130
|
|
130
131
|
heed seller, :request_valuation, item do
|
131
132
|
hark valuation_notifier do |on|
|
@@ -136,8 +137,8 @@ yielded as the listener
|
|
136
137
|
|
137
138
|
### Return value
|
138
139
|
|
139
|
-
Using the return value of a listener is not encouraged.
|
140
|
-
style of coding. That said the return value of a
|
140
|
+
Using the return value of a listener is not encouraged. Heed is designed for a *tell, don't ask*
|
141
|
+
style of coding. That said the return value of a heed listener is an array of its handlers return values.
|
141
142
|
|
142
143
|
a = hark(:foo) { 'a' }
|
143
144
|
b = Object.new.tap {|o| o.singleton_class.send(:define_method, :foo) { 'b' } }
|
@@ -149,14 +150,14 @@ style of coding. That said the return value of a hark listener is an array of i
|
|
149
150
|
|
150
151
|
### Immutable
|
151
152
|
|
152
|
-
|
153
|
+
Heed listeners are immutable and `#lax`, `#strict`, and `#heed` all return new listeners.
|
153
154
|
|
154
155
|
## Rationale
|
155
156
|
|
156
157
|
When programming in the 'tell-dont-ask' or 'hexagonal' style, program flow is managed by passing listener, or
|
157
158
|
response, objects to service objects, which call back depending on what happened. This allows logic that is concerned with the caller's domain to remain isolated from the service object.
|
158
159
|
|
159
|
-
The idea behind **
|
160
|
+
The idea behind **heed** is that there should be little ceremony involved in the listener/response mechanics, and
|
160
161
|
that simple listeners can easily be refactored into objects in their own right, without changing the protocols between
|
161
162
|
the calling and servcie objects.
|
162
163
|
|
@@ -176,13 +177,13 @@ The UserCreator object's main method will have some code as follows:
|
|
176
177
|
response.invalid_user(user)
|
177
178
|
end
|
178
179
|
|
179
|
-
Let's say a controller is calling this, and you are using
|
180
|
+
Let's say a controller is calling this, and you are using heed. In the beginning you would do something like this:
|
180
181
|
|
181
182
|
def create
|
182
|
-
user_creator
|
183
|
+
heed user_creator, :create_user, user_params do |on|
|
183
184
|
on.created_user {|user| redirect_to user, notice: "Welome!" }
|
184
185
|
on.invalid_user {|user| @user = user; render "new" }
|
185
|
-
end
|
186
|
+
end
|
186
187
|
end
|
187
188
|
|
188
189
|
This keeps the controller's handling of the user creation nicely separate from the saving of the user creator.
|
@@ -190,7 +191,7 @@ This keeps the controller's handling of the user creation nicely separate from t
|
|
190
191
|
Then, a requirement comes in to log the creation of users. The first attempt might be this:
|
191
192
|
|
192
193
|
def create
|
193
|
-
user_creator
|
194
|
+
heed user_creator, :create_user, user_params do |on|
|
194
195
|
on.created_user do |user|
|
195
196
|
redirect_to user, notice: "Welome!"
|
196
197
|
logger.info "User #{user} created"
|
@@ -205,8 +206,9 @@ to the same protocol. Also, the UX team want to log invalid users.
|
|
205
206
|
There's quite a lot going on now, we can tie it up as follows:
|
206
207
|
|
207
208
|
def create
|
208
|
-
|
209
|
-
|
209
|
+
heed user_creator, :create_user, user_params do
|
210
|
+
hark ui_response, UserEmailer.new, ux_team_response
|
211
|
+
end
|
210
212
|
end
|
211
213
|
|
212
214
|
# UserEmailer responds to #created_user(user)
|
@@ -222,12 +224,13 @@ There's quite a lot going on now, we can tie it up as follows:
|
|
222
224
|
hark(:invalid_user) {|user| logger.info("User invalid: #{user}") }
|
223
225
|
end
|
224
226
|
|
225
|
-
If some of the response code gets hairy, we can easily swap out
|
227
|
+
If some of the response code gets hairy, we can easily swap out heed ad-hoc objects for 'proper' ones.
|
226
228
|
For example, the UI response might get a bit hairy, and so we make a new object.
|
227
229
|
|
228
230
|
def create
|
229
|
-
|
230
|
-
|
231
|
+
heed user_creator, :create_user, user_params do
|
232
|
+
hark UiResponse.new(self), UserEmailer.new, ux_team_response
|
233
|
+
end
|
231
234
|
end
|
232
235
|
|
233
236
|
class UiResponse < SimpleDelegator
|
@@ -245,11 +248,11 @@ For example, the UI response might get a bit hairy, and so we make a new object.
|
|
245
248
|
end
|
246
249
|
|
247
250
|
Note that throughout this process we didn't have to modify the UserCreator code, even when we transitioned
|
248
|
-
to/from hark for different repsonses/styles.
|
251
|
+
to/from heed/hark for different repsonses/styles.
|
249
252
|
|
250
253
|
### Testing your listeners
|
251
254
|
|
252
|
-
Don't pay any attention to
|
255
|
+
Don't pay any attention to heed when you're testing, heed is just a utility to create listeners, and so what
|
253
256
|
you should be testing is the protocol.
|
254
257
|
|
255
258
|
For example the service object tests will test functionality that pertains to the actual creation of the user,
|
@@ -322,6 +325,8 @@ dictated by the protocol.
|
|
322
325
|
end
|
323
326
|
end
|
324
327
|
|
328
|
+
Note that in the above tests, there is *no mention of hark or heed*. This ensures a smooth transition to 'full blown'
|
329
|
+
response objects should the need occur.
|
325
330
|
|
326
331
|
## Contributing
|
327
332
|
|
@@ -1,16 +1,16 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require '
|
4
|
+
require 'heed/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "heed"
|
8
|
-
spec.version =
|
8
|
+
spec.version = Heed::VERSION
|
9
9
|
spec.authors = ["Ian White"]
|
10
10
|
spec.email = ["ian.w.white@gmail.com"]
|
11
|
-
spec.description = %q{Create ad-hoc
|
12
|
-
spec.summary = %q{
|
13
|
-
spec.homepage = "http://github.com/ianwhite/
|
11
|
+
spec.description = %q{Create and use ad-hoc listeners with hark and heed}
|
12
|
+
spec.summary = %q{Heed is a gem that enables writing code in a "hexagonal architecture" or "tell don't ask" style}
|
13
|
+
spec.homepage = "http://github.com/ianwhite/heed"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
data/lib/heed.rb
ADDED
data/lib/{hark → heed}/ad_hoc.rb
RENAMED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Kernel
|
2
2
|
def hark *args, &block
|
3
|
-
|
3
|
+
Heed.listener *args, &block
|
4
4
|
end
|
5
5
|
|
6
6
|
def heed object, *args, &block
|
7
|
-
listener = (block.arity == 1) ?
|
7
|
+
listener = (block.arity == 1) ? Heed.listener(&block) : block.call
|
8
8
|
object.send *args + [listener]
|
9
9
|
end
|
10
10
|
end
|
data/lib/heed/version.rb
ADDED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require '
|
2
|
+
require 'heed'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe Heed do
|
5
5
|
let(:transcript) { [] }
|
6
6
|
|
7
7
|
class PlainListener < Struct.new(:transcript)
|
@@ -125,8 +125,8 @@ describe Hark do
|
|
125
125
|
end
|
126
126
|
|
127
127
|
describe "lax/strict is preserved on #hark" do
|
128
|
-
it { hark.lax.hark.should be_a
|
129
|
-
it { hark.strict.hark.should be_a
|
128
|
+
it { hark.lax.hark.should be_a Heed::LaxListener }
|
129
|
+
it { hark.strict.hark.should be_a Heed::StrictListener }
|
130
130
|
end
|
131
131
|
|
132
132
|
describe "when methods return falsy" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian White
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description: Create ad-hoc
|
69
|
+
description: Create and use ad-hoc listeners with hark and heed
|
70
70
|
email:
|
71
71
|
- ian.w.white@gmail.com
|
72
72
|
executables: []
|
@@ -81,16 +81,16 @@ files:
|
|
81
81
|
- LICENSE.txt
|
82
82
|
- README.md
|
83
83
|
- Rakefile
|
84
|
-
-
|
85
|
-
- lib/
|
86
|
-
- lib/
|
87
|
-
- lib/
|
88
|
-
- lib/
|
89
|
-
- lib/
|
90
|
-
- lib/
|
91
|
-
- spec/
|
84
|
+
- heed.gemspec
|
85
|
+
- lib/heed.rb
|
86
|
+
- lib/heed/ad_hoc.rb
|
87
|
+
- lib/heed/core_ext.rb
|
88
|
+
- lib/heed/dispatcher.rb
|
89
|
+
- lib/heed/listener.rb
|
90
|
+
- lib/heed/version.rb
|
91
|
+
- spec/heed_spec.rb
|
92
92
|
- spec/spec_helper.rb
|
93
|
-
homepage: http://github.com/ianwhite/
|
93
|
+
homepage: http://github.com/ianwhite/heed
|
94
94
|
licenses:
|
95
95
|
- MIT
|
96
96
|
metadata: {}
|
@@ -113,8 +113,8 @@ rubyforge_project:
|
|
113
113
|
rubygems_version: 2.0.6
|
114
114
|
signing_key:
|
115
115
|
specification_version: 4
|
116
|
-
summary:
|
116
|
+
summary: Heed is a gem that enables writing code in a "hexagonal architecture" or
|
117
117
|
"tell don't ask" style
|
118
118
|
test_files:
|
119
|
-
- spec/
|
119
|
+
- spec/heed_spec.rb
|
120
120
|
- spec/spec_helper.rb
|
data/lib/hark.rb
DELETED
data/lib/hark/version.rb
DELETED