beacon 0.1 → 0.9.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.
- data/.gitignore +3 -2
- data/.travis.yml +11 -0
- data/CHANGES +11 -0
- data/Gemfile +2 -0
- data/README.rdoc +46 -1
- data/Rakefile +15 -23
- data/beacon.gemspec +8 -17
- data/lib/beacon.rb +23 -4
- data/spec/fire_spec.rb +27 -0
- data/spec/isolated_spec.rb +23 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/watch_spec.rb +43 -0
- metadata +59 -61
data/.gitignore
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
doc
|
2
|
-
|
1
|
+
/doc
|
2
|
+
/pkg
|
3
|
+
/Gemfile.lock
|
data/.travis.yml
ADDED
data/CHANGES
ADDED
data/Gemfile
ADDED
data/README.rdoc
CHANGED
@@ -25,6 +25,10 @@ Each time you call <tt>watch</tt> with a given name, you register a different
|
|
25
25
|
handler for that name. Each time you call <tt>fire</tt> <b>all</b> handlers
|
26
26
|
for that event are run, in the order they were registered.
|
27
27
|
|
28
|
+
You can use <tt>on</tt> as an alias of <tt>watch</tt>, and <tt>trigger</tt> as
|
29
|
+
an alias of <tt>fire</tt>, since those seem to be popular choices among event
|
30
|
+
observing libraries.
|
31
|
+
|
28
32
|
== Passing arguments
|
29
33
|
|
30
34
|
If you want to pass arguments to the watchers, just pass them along in
|
@@ -38,6 +42,47 @@ And you'll get them as arguments on the block that handles the message:
|
|
38
42
|
# here object == "cuack", index == 3
|
39
43
|
end
|
40
44
|
|
41
|
-
==
|
45
|
+
== Advanced handlers
|
46
|
+
|
47
|
+
Instead of blocks, <tt>Beacon.watch</tt> can receive any object that responds
|
48
|
+
to <tt>call</tt>, so if you need any advanced logic in your handlers, you can
|
49
|
+
declare them like this:
|
50
|
+
|
51
|
+
class MyHandler
|
52
|
+
def call(foo, bar=0)
|
53
|
+
puts foo.inspect, bar
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
Beacon.watch :an_event, MyHandler.new
|
58
|
+
|
59
|
+
== Isolated events
|
60
|
+
|
61
|
+
You can include Beacon into your objects to have isolated events on a per-object
|
62
|
+
basis if you need that:
|
63
|
+
|
64
|
+
class MyObservable
|
65
|
+
include Beacon
|
66
|
+
end
|
67
|
+
|
68
|
+
obj = MyObservable.new
|
69
|
+
obj.watch(:an_event) { |object, *args| puts *args }
|
70
|
+
obj.trigger(:an_event, "foo")
|
71
|
+
|
72
|
+
== Installing with rubygems
|
73
|
+
|
74
|
+
gem install beacon
|
75
|
+
|
76
|
+
== Contributing
|
77
|
+
|
78
|
+
Clone our git repo from <tt>git://github.com/foca/beacon.git</tt>. The preffered
|
79
|
+
way to send a patch is to push to a clone of the repo on github[http://github.com]
|
80
|
+
but if you want to mail me a patch or point me to a diff I won't complain. Though
|
81
|
+
I'll probably take more to apply it :)
|
82
|
+
|
83
|
+
== Authors
|
84
|
+
|
85
|
+
Code written by foca[http://github.com/foca], with the help and ideas of
|
86
|
+
halorgium[http://github.com/halorgium], and tizoc[http://github.com/tizoc].
|
42
87
|
|
43
88
|
The code is licensed under an MIT license. Check the LICENSE file for details.
|
data/Rakefile
CHANGED
@@ -1,33 +1,25 @@
|
|
1
|
-
require "
|
2
|
-
|
3
|
-
|
4
|
-
require "hanna/rdoctask"
|
5
|
-
rescue LoadError
|
6
|
-
require "rake/rdoctask"
|
7
|
-
end
|
8
|
-
|
9
|
-
begin
|
10
|
-
require "metric_fu"
|
11
|
-
rescue LoadError
|
12
|
-
end
|
13
|
-
|
14
|
-
begin
|
15
|
-
require "mg"
|
16
|
-
MG.new("beacon.gemspec")
|
17
|
-
rescue LoadError
|
18
|
-
end
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
require "hanna/rdoctask"
|
3
|
+
require "rubygems/package_task"
|
19
4
|
|
20
5
|
desc "Default: run all tests"
|
21
|
-
task :
|
6
|
+
task default: :spec
|
22
7
|
|
23
|
-
desc "Run
|
24
|
-
|
25
|
-
t.
|
8
|
+
desc "Run library tests"
|
9
|
+
RSpec::Core::RakeTask.new do |t|
|
10
|
+
t.pattern = "spec/**/*_spec.rb"
|
11
|
+
t.rspec_opts = %w(-fs --color)
|
26
12
|
end
|
27
13
|
|
28
14
|
Rake::RDocTask.new do |rd|
|
29
|
-
rd.main = "README"
|
30
15
|
rd.title = "Beacon Documentation"
|
16
|
+
rd.main = "README.rdoc"
|
31
17
|
rd.rdoc_files.include("README.rdoc", "LICENSE", "lib/**/*.rb")
|
32
18
|
rd.rdoc_dir = "doc"
|
33
19
|
end
|
20
|
+
|
21
|
+
gem_spec = eval(File.read("./beacon.gemspec")) rescue nil
|
22
|
+
Gem::PackageTask.new(gem_spec) do |pkg|
|
23
|
+
pkg.need_zip = false
|
24
|
+
pkg.need_tar = false
|
25
|
+
end
|
data/beacon.gemspec
CHANGED
@@ -1,31 +1,22 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "beacon"
|
3
|
-
s.version = "0.
|
4
|
-
s.date = "
|
3
|
+
s.version = "0.9.0"
|
4
|
+
s.date = "2012-03-20"
|
5
5
|
|
6
6
|
s.description = "Simple and straightforward observers for your code"
|
7
7
|
s.summary = "Simple and straightforward observers for your code"
|
8
8
|
s.homepage = "http://github.com/foca/beacon"
|
9
9
|
|
10
|
-
s.authors = ["
|
10
|
+
s.authors = ["Nicolas Sanguinetti"]
|
11
11
|
s.email = "contacto@nicolassanguinetti.info"
|
12
12
|
|
13
13
|
s.require_paths = ["lib"]
|
14
14
|
s.has_rdoc = true
|
15
|
-
s.
|
15
|
+
s.rubyforge_project = "beacon"
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
s.add_development_dependency "contest"
|
20
|
-
s.add_development_dependency "redgreen"
|
21
|
-
end
|
17
|
+
s.add_development_dependency "rspec", "~> 2.0"
|
18
|
+
s.add_development_dependency "hanna", "~> 0.1"
|
22
19
|
|
23
|
-
s.files =
|
24
|
-
.
|
25
|
-
LICENSE
|
26
|
-
README.rdoc
|
27
|
-
Rakefile
|
28
|
-
beacon.gemspec
|
29
|
-
lib/beacon.rb
|
30
|
-
]
|
20
|
+
s.files = `git ls-files`.split "\n"
|
21
|
+
s.platform = Gem::Platform::RUBY
|
31
22
|
end
|
data/lib/beacon.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
module Beacon
|
2
|
+
extend self
|
3
|
+
|
2
4
|
# Fire an event to be processed by all the watchers. You pass the event name
|
3
5
|
# and any arguments you want passed to the event handlers.
|
4
6
|
#
|
5
7
|
# Beacon.fire(:some_event, "an argument", 2, "another")
|
6
|
-
def
|
8
|
+
def fire(event, *args)
|
7
9
|
events[event].each do |callback|
|
8
10
|
callback.call(*args)
|
9
11
|
end
|
10
12
|
end
|
13
|
+
alias_method :trigger, :fire
|
11
14
|
|
12
15
|
# Register a callback for a given event. Each time you call <tt>fire</tt> then
|
13
16
|
# all the callbacks registered for that name will be called in order.
|
@@ -15,12 +18,28 @@ module Beacon
|
|
15
18
|
# Beacon.watch :some_event do |foo, bar, baz|
|
16
19
|
# # do stuff with foo, bar, and baz
|
17
20
|
# end
|
18
|
-
|
21
|
+
#
|
22
|
+
# Instead of passing a block, you can pass any object that responds to
|
23
|
+
# <tt>#call</tt>. Like this:
|
24
|
+
#
|
25
|
+
# class MyHandler
|
26
|
+
# def call(foo=1, bar=2, baz=3)
|
27
|
+
# puts foo, bar, baz
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# Beacon.watch :some_event, MyHandler.new
|
32
|
+
def watch(event, handler=nil, &default_handler)
|
33
|
+
if handler && block_given?
|
34
|
+
raise ArgumentError, "You cannot register a handler with both a block and an object"
|
35
|
+
end
|
36
|
+
handler = handler || default_handler || raise(ArgumentError, "You must provide a handler")
|
19
37
|
events[event] << handler
|
20
38
|
end
|
39
|
+
alias_method :on, :watch
|
21
40
|
|
22
|
-
def
|
41
|
+
def events
|
23
42
|
@events ||= Hash.new {|h,k| h[k] = [] }
|
24
43
|
end
|
25
|
-
|
44
|
+
private :events
|
26
45
|
end
|
data/spec/fire_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Beacon do
|
4
|
+
describe "with a pass-through handler watching :event" do
|
5
|
+
before(:each) do
|
6
|
+
@args = nil
|
7
|
+
Beacon.watch(:event) do |*args|
|
8
|
+
@args = args
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "allows firing an event with no args" do
|
13
|
+
Beacon.fire(:event)
|
14
|
+
@args.should == []
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows firing an event with 1 arg" do
|
18
|
+
Beacon.fire(:event, :test)
|
19
|
+
@args.should == [:test]
|
20
|
+
end
|
21
|
+
|
22
|
+
it "allows firing an event with args and options" do
|
23
|
+
Beacon.fire(:event, :foo, :bar, :baz => :quux)
|
24
|
+
@args.should == [:foo, :bar, {:baz => :quux}]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Beacon do
|
4
|
+
class Observable < Struct.new(:int)
|
5
|
+
include Beacon
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:observable_1) { Observable.new(1) }
|
9
|
+
let(:observable_2) { Observable.new(1) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
observable_1.watch(:inc) { observable_1.int += 1 }
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can listen to events on instances of objects where you mix in Beacon" do
|
16
|
+
expect { observable_1.trigger(:inc) }.to change { observable_1.int }.by(1)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "will ignore events fired on other instances" do
|
20
|
+
expect { observable_2.trigger(:inc) }.to_not change { observable_1.int }.by(1)
|
21
|
+
expect { Beacon.trigger(:inc) }.to_not change { observable_1.int }.by(1)
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/watch_spec.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class Handler
|
4
|
+
def initialize
|
5
|
+
@value = nil
|
6
|
+
end
|
7
|
+
attr_reader :value
|
8
|
+
|
9
|
+
def call
|
10
|
+
@value = 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Beacon do
|
15
|
+
it "allows watching an event with a block" do
|
16
|
+
value = nil
|
17
|
+
Beacon.watch(:event) do
|
18
|
+
value = 1
|
19
|
+
end
|
20
|
+
Beacon.fire(:event)
|
21
|
+
value.should == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it "allows watching an event with an object" do
|
25
|
+
handler = Handler.new
|
26
|
+
Beacon.watch(:event, handler)
|
27
|
+
Beacon.fire(:event)
|
28
|
+
handler.value.should == 1
|
29
|
+
end
|
30
|
+
|
31
|
+
it "disallows watching an event without either a block or an object" do
|
32
|
+
lambda { Beacon.watch(:event) }.
|
33
|
+
should raise_error(ArgumentError, "You must provide a handler")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "disallows watching an event both a block and an object" do
|
37
|
+
lambda {
|
38
|
+
Beacon.watch(:event, Handler.new) do
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
}.should raise_error(ArgumentError, "You cannot register a handler with both a block and an object")
|
42
|
+
end
|
43
|
+
end
|
metadata
CHANGED
@@ -1,87 +1,85 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: beacon
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
-
-
|
7
|
+
authors:
|
8
|
+
- Nicolas Sanguinetti
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
date: 2012-03-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70336345771700 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
17
22
|
type: :development
|
18
|
-
|
19
|
-
version_requirements:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
-
|
26
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70336345771700
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hanna
|
27
|
+
requirement: &70336345769800 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.1'
|
27
33
|
type: :development
|
28
|
-
|
29
|
-
version_requirements:
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: "0"
|
34
|
-
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: redgreen
|
37
|
-
type: :development
|
38
|
-
version_requirement:
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: "0"
|
44
|
-
version:
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70336345769800
|
45
36
|
description: Simple and straightforward observers for your code
|
46
37
|
email: contacto@nicolassanguinetti.info
|
47
38
|
executables: []
|
48
|
-
|
49
39
|
extensions: []
|
50
|
-
|
51
40
|
extra_rdoc_files: []
|
52
|
-
|
53
|
-
files:
|
41
|
+
files:
|
54
42
|
- .gitignore
|
43
|
+
- .travis.yml
|
44
|
+
- CHANGES
|
45
|
+
- Gemfile
|
55
46
|
- LICENSE
|
56
47
|
- README.rdoc
|
57
48
|
- Rakefile
|
58
49
|
- beacon.gemspec
|
59
50
|
- lib/beacon.rb
|
60
|
-
|
51
|
+
- spec/fire_spec.rb
|
52
|
+
- spec/isolated_spec.rb
|
53
|
+
- spec/spec_helper.rb
|
54
|
+
- spec/watch_spec.rb
|
61
55
|
homepage: http://github.com/foca/beacon
|
56
|
+
licenses: []
|
62
57
|
post_install_message:
|
63
58
|
rdoc_options: []
|
64
|
-
|
65
|
-
require_paths:
|
59
|
+
require_paths:
|
66
60
|
- lib
|
67
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
hash: -1274202390002964611
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
hash: -1274202390002964611
|
79
79
|
requirements: []
|
80
|
-
|
81
|
-
|
82
|
-
rubygems_version: 1.3.1
|
80
|
+
rubyforge_project: beacon
|
81
|
+
rubygems_version: 1.8.11
|
83
82
|
signing_key:
|
84
|
-
specification_version:
|
83
|
+
specification_version: 3
|
85
84
|
summary: Simple and straightforward observers for your code
|
86
85
|
test_files: []
|
87
|
-
|