hooked 0.0.1

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/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "awesome_print"
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Lars Gierth
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,12 @@
1
+ Ruby library for Aspect Oriented Programming
2
+ ============================================
3
+
4
+ hooked makes AOP a breeze. It lets you define and invoke code that other
5
+ gems or parts of your application can hook onto. Supported hooks are before,
6
+ after and around.
7
+
8
+ To Do
9
+ -----
10
+
11
+ * Skip hooks
12
+ * Control flow (return, next, break)
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :default => :test
5
+
6
+ require "rake/testtask"
7
+ Rake::TestTask.new do |t|
8
+ t.libs = ["lib"]
9
+ t.test_files = FileList["test/*_test.rb"]
10
+ end
data/hooked.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "hooked/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "hooked"
7
+ s.version = Hooked::VERSION
8
+ s.date = Date.today.to_s
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Lars Gierth"]
11
+ s.email = ["lars.gierth@gmail.com"]
12
+ s.homepage = "http://rubygems.org/gems/hooked"
13
+ s.summary = %q{Ruby library for Aspect Oriented Programming}
14
+ s.description = %q{hooked makes AOP a breeze. It lets you define and invoke
15
+ code that other gems or parts of your application can hook
16
+ onto. Supported hooks are before, after and around.}
17
+
18
+ s.add_dependency "depression"
19
+
20
+ s.add_development_dependency "test-unit"
21
+ s.add_development_dependency "mocha"
22
+
23
+ s.files = `git ls-files`.split("\n") - [".gitignore", ".rvmrc"]
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
27
+ end
data/lib/hooked.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "depression"
2
+
3
+ require "hooked/container"
4
+ require "hooked/controller"
5
+ require "hooked/hook"
6
+ require "hooked/hookable"
@@ -0,0 +1,52 @@
1
+ module Hooked
2
+ module Container
3
+ attr_accessor :hooked
4
+
5
+ def hookable(name, *args, &block)
6
+ hooked.invoke(name, *args, &block)
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_reader :hookables, :hooks
11
+
12
+ def hookable(name, &block)
13
+ @hookables << Hookable.new(name, &block)
14
+ end
15
+
16
+ def hook(type, hookable, name, opts = {}, &block)
17
+ opts[:before] ||= []
18
+ unless opts[:before].respond_to?(:each) or opts[:before] == :all
19
+ opts[:before] = [opts[:before]]
20
+ end
21
+
22
+ opts[:after] ||= []
23
+ unless opts[:after].respond_to?(:each) or opts[:after] == :all
24
+ opts[:after] = [opts[:after]]
25
+ end
26
+
27
+ @hooks[hookable] ||= []
28
+ @hooks[hookable] << Hook.new(type, name, opts, &block)
29
+ end
30
+
31
+ def before(*args, &block)
32
+ hook(:before, *args, &block)
33
+ end
34
+
35
+ def around(*args, &block)
36
+ hook(:around, *args, &block)
37
+ end
38
+
39
+ def after(*args, &block)
40
+ hook(:after, *args, &block)
41
+ end
42
+ end
43
+
44
+ def self.included(klass)
45
+ klass.class_eval do
46
+ extend(ClassMethods)
47
+ @hookables = []
48
+ @hooks = {}
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,92 @@
1
+ module Hooked
2
+ Result = Struct.new(:type, :value)
3
+
4
+ class Controller
5
+ attr_reader :name, :containers, :hookables, :hooks
6
+
7
+ def initialize(name, *containers)
8
+ @name = name
9
+
10
+ @containers = []
11
+ @hookables = {}
12
+ @hooks = {}
13
+
14
+ add(*containers)
15
+ refresh
16
+ end
17
+
18
+ def add(*containers)
19
+ @containers.push(*containers)
20
+ containers.each do |c|
21
+ c.class.hookables.each do |hkbl|
22
+ hkbl.container = c
23
+ hookables[hkbl.name] = hkbl
24
+ end
25
+ c.class.hooks.each do |hkbl_name, hs|
26
+ hs.each {|h| h.container = c }
27
+ @hooks[hkbl_name] ||= []
28
+ @hooks[hkbl_name].push(*hs)
29
+ end
30
+ end
31
+ end
32
+
33
+ def refresh
34
+ hooks.each {|hkbl_name, hs| hooks[hkbl_name] = Depression.process(hs) }
35
+ end
36
+
37
+ def invoke(name, *args, &block)
38
+ if block
39
+ hookable = Hookable.new(name, &block)
40
+ else
41
+ hookable = hookables[name] || raise("Unknown hookable: #{name}")
42
+ end
43
+
44
+ result = catch(:hooked) do
45
+ (hooks[name] || []).reverse.inject(hookable) do |next_item, item|
46
+ proc {|a| call_hook(item, next_item, a) }
47
+ end.call(args)
48
+ end
49
+ if (result[0] rescue nil) == :hooked_abort_chain
50
+ result[1]
51
+ else
52
+ result
53
+ end
54
+ end
55
+
56
+ protected
57
+
58
+ # def call_wrapped_hook(hook, hookable, args)
59
+ # ret = nil
60
+ #
61
+ # j = (0..1).each do |i|
62
+ # ret = call_hook(hook, hookable, args) if i == 0
63
+ # end
64
+ # unless j
65
+ # throw(:hooked, :hooked_abort_chain)
66
+ # end
67
+ #
68
+ # ret
69
+ # end
70
+
71
+ def call_hook(hook, hookable, args)
72
+ args = hook.call(*args) if hook.before?
73
+
74
+ result = catch(:hooked) do
75
+ if hook.around?
76
+ hook.call(hookable, *args)
77
+ else
78
+ hookable.call(*args)
79
+ end
80
+ end
81
+ if result == :hooked_abort_chain
82
+ throw(:hooked, [:hooked_abort_chain, args])
83
+ else
84
+ args = result
85
+ end
86
+
87
+ args = hook.call(*args) if hook.after?
88
+
89
+ args
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,33 @@
1
+ module Hooked
2
+ class Hook
3
+ attr_reader :type, :name, :relations
4
+ attr_accessor :container, :weight
5
+
6
+ def initialize(type, name, relations = {}, container = nil, &block)
7
+ raise ArgumentError, "Invalid hook type `#{type}'" unless [
8
+ :before, :after, :around
9
+ ].include?(type.to_sym)
10
+ @type, @name, @relations = type.to_sym, name.to_sym, relations
11
+
12
+ raise ArgumentError, "Hooked::Hookable.new expects a block." unless block
13
+ @container, @block = container, block
14
+ end
15
+
16
+ def call(*args)
17
+ raise RuntimeError, "No container set for hook `#{name}'" unless container
18
+ container.instance_exec(*args, &@block)
19
+ end
20
+
21
+ def before?
22
+ type == :before
23
+ end
24
+
25
+ def after?
26
+ type == :after
27
+ end
28
+
29
+ def around?
30
+ type == :around
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ module Hooked
2
+ class Hookable
3
+ attr_reader :name
4
+ attr_accessor :container
5
+
6
+ def initialize(name, container = nil, &block)
7
+ raise ArgumentError, "Hooked::Hookable.new expects a block." unless block
8
+
9
+ @name, @container, @block = name.to_sym, container, block
10
+ end
11
+
12
+ def call(*args)
13
+ if container
14
+ container.instance_exec(*args, &@block)
15
+ else
16
+ @block.call(*args)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Hooked
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper.rb"
2
+
3
+ class ContainerTest < Test::Unit::TestCase
4
+ def setup
5
+ @container = Class.new { include(Hooked::Container) }
6
+ end
7
+
8
+ def teardown
9
+ Mocha::Mockery.instance.teardown
10
+ end
11
+
12
+ def test_has_hookables
13
+ block = proc {}
14
+ @container.hookable(:foo, &block)
15
+
16
+ assert_equal :foo, @container.hookables[0].name
17
+ assert @container.hookables[0].respond_to?(:call)
18
+ end
19
+
20
+ def test_has_a_shorthand_method_for_invoking_hookables
21
+ container = @container.new
22
+ container.hooked = stub("controller") do
23
+ expects(:invoke).once.with(:foo, 123).returns("asdf")
24
+ end
25
+
26
+ assert_equal "asdf", container.hookable(:foo, 123)
27
+ end
28
+
29
+ def test_has_hooks
30
+ block = proc {}
31
+ @container.hook(:after, :work, :start_revolution, {
32
+ :before => :utopia
33
+ }, &block)
34
+ @container.hook(:around, :foo, :do_something, {
35
+ :before => :all,
36
+ :after => [:do_something_else, :snooze]
37
+ }, &block)
38
+
39
+ h = @container.hooks[:work][0]
40
+ assert_equal :after, h.type
41
+ assert_equal :start_revolution, h.name
42
+ assert_equal({
43
+ :before => [:utopia],
44
+ :after => []
45
+ }, h.relations)
46
+ assert h.respond_to?(:call)
47
+ assert h.respond_to?(:container=)
48
+
49
+ h = @container.hooks[:foo][0]
50
+ assert_equal :around, h.type
51
+ assert_equal :do_something, h.name
52
+ assert_equal({
53
+ :before => :all,
54
+ :after => [:do_something_else, :snooze]
55
+ }, h.relations)
56
+ end
57
+
58
+ def test_has_shorthand_methods_for_before_around_and_after
59
+ args = [:foo, :bar, {:before => :all}]
60
+ block = proc {}
61
+
62
+ @container.expects(:hook).once.with(:before, *args)
63
+ @container.before(*args, &block)
64
+
65
+ @container.expects(:hook).once.with(:around, *args)
66
+ @container.around(*args, &block)
67
+
68
+ @container.expects(:hook).once.with(:after, *args)
69
+ @container.after(*args, &block)
70
+ end
71
+ end
@@ -0,0 +1,176 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + "/helper.rb"
2
+
3
+ class ControllerTest < Test::Unit::TestCase
4
+ def setup
5
+ @containers = [
6
+ Class.new do
7
+ include Hooked::Container
8
+ before :foo, :do_something do |*args|; end
9
+ end,
10
+ Class.new do
11
+ include Hooked::Container
12
+ around :foo, :do_something_else do |h, *args|
13
+ h.call(*args)
14
+ end
15
+ end,
16
+ Class.new do
17
+ include Hooked::Container
18
+ hookable :foo do |*args|; end
19
+ end
20
+ ].map {|c| c.new }
21
+ end
22
+
23
+ def test_has_a_name
24
+ name = :foo
25
+ controller = Hooked::Controller.new(name)
26
+
27
+ assert_equal name, controller.name
28
+ end
29
+
30
+ def test_has_containers
31
+ controller = Hooked::Controller.new(:foo, @containers[0])
32
+ controller.add(*@containers[1..2])
33
+
34
+ assert_equal @containers, controller.containers
35
+ end
36
+
37
+ def test_collects_hookables_and_hooks_from_containers
38
+ hookable = @containers[2].class.hookables[0]
39
+ hooks = [
40
+ @containers[0].class.hooks[:foo][0],
41
+ @containers[1].class.hooks[:foo][0]
42
+ ]
43
+ controller = Hooked::Controller.new(:baz, *@containers)
44
+
45
+ assert_equal hookable, controller.hookables[hookable.name]
46
+ assert_equal hooks, controller.hooks[:foo]
47
+ end
48
+
49
+ def test_sorts_hooks
50
+ container = Class.new do
51
+ include(Hooked::Container)
52
+ before(:foo, :do_something) {}
53
+ before(:foo, :do_dishes, :after => :all) {}
54
+ around(:foo, :do_something_more, :before => :do_something) {}
55
+ after(:foo, :do_something_else, :after => :do_something_more, :before => :do_something) {}
56
+ around(:foo, :do_laundry, :before => :all) {}
57
+ end
58
+ order = [:do_laundry, :do_something_more, :do_something_else, :do_something, :do_dishes]
59
+
60
+ controller = Hooked::Controller.new(:baz, container.new)
61
+ assert_equal order, controller.hooks[:foo].map {|h| h.name }
62
+
63
+ controller = Hooked::Controller.new(:baz)
64
+ controller.add(container.new)
65
+ assert_not_equal order, controller.hooks[:foo].map {|h| h.name }
66
+
67
+ controller.hooks[:foo].shuffle!
68
+ controller.refresh
69
+ assert_equal order, controller.hooks[:foo].map {|h| h.name }
70
+ end
71
+
72
+ def test_sets_the_container_on_hookables_and_hooks
73
+ controller = Hooked::Controller.new(:foo, *@containers[1..2])
74
+ assert_equal @containers[1], controller.hooks[:foo][0].container
75
+ assert_equal @containers[2], controller.hookables[:foo].container
76
+ end
77
+
78
+ def test_invokes_hooks_in_their_containers_scope
79
+ scope = nil
80
+ container = Class.new do
81
+ include(Hooked::Container)
82
+ hookable(:something) {}
83
+ before(:something, :do_something_else) { scope = self }
84
+ end.new
85
+
86
+ controller = Hooked::Controller.new(:foo, container)
87
+ controller.invoke(:something)
88
+
89
+ assert_equal(container, scope)
90
+ end
91
+
92
+ def test_invokes_hookables_in_their_containers_scope
93
+ scope = nil
94
+ container = Class.new do
95
+ include(Hooked::Container)
96
+ hookable(:something) { scope = self }
97
+ end.new
98
+
99
+ controller = Hooked::Controller.new(:foo, container)
100
+ controller.invoke(:something)
101
+
102
+ assert_equal(container, scope)
103
+ end
104
+
105
+ def test_invokes_dynamic_hookables_in_their_original_scope
106
+ controller = Hooked::Controller.new(:foo)
107
+
108
+ scope = nil
109
+ controller.invoke(:something) { scope = self }
110
+
111
+ assert_equal(self, scope)
112
+ end
113
+
114
+ def test_hookables_and_hooks_can_use_next
115
+ pend
116
+
117
+ called = []
118
+ container = Class.new do
119
+ include(Hooked::Container)
120
+ hookable(:something) { called << :something }
121
+ before(:something, :do_something_more) { called << :do_something_more }
122
+ before(:something, :do_something_else) { next; called << :do_something_else }
123
+ end
124
+
125
+ controller = Hooked::Controller.new(:foo, container.new)
126
+ controller.invoke(:something)
127
+ assert_equal [:do_something_more, :something], called
128
+ end
129
+
130
+ def test_hookables_and_hooks_can_use_return
131
+ pend
132
+
133
+ called = []
134
+ returned_arg = nil
135
+ container = Class.new do
136
+ include(Hooked::Container)
137
+ hookable(:something) { called << :something }
138
+ before(:something, :do_something_more) {|arg| return arg + 1; called << :do_something_more }
139
+ before(:something, :do_something_else) {|arg| returned_arg = arg; return; called << :do_something_else }
140
+ end
141
+
142
+ controller = Hooked::Controller.new(:foo, container.new)
143
+ fail("Doesn't reach the code after controller.invoke()")
144
+ controller.invoke(:something, 1)
145
+ assert_equal [:do_something_more, :asd], called
146
+ assert_equal 3, returned_arg
147
+ end
148
+
149
+ def test_hookables_and_hooks_can_use_break
150
+ pend
151
+
152
+ called = []
153
+ container = Class.new do
154
+ include(Hooked::Container)
155
+ hookable(:something) { called << :something }
156
+ before(:something, :do_something_more) { called << :do_something_more }
157
+ before(:something, :do_something_else) { called << :do_something_else; break }
158
+ end
159
+
160
+ controller = Hooked::Controller.new(:foo, container.new)
161
+ controller.invoke(:something)
162
+ assert_equal [:do_something_more, :do_something_else], called
163
+ end
164
+
165
+ def test_arguments_and_return_values_are_passed_in_and_out
166
+ container = Class.new do
167
+ include(Hooked::Container)
168
+ hookable(:something) {|arg| arg += 1; arg }
169
+ before(:something, :do_something_more) {|arg| arg += 1; [arg] }
170
+ after(:something, :do_something_else) {|arg| arg += 1; arg }
171
+ end
172
+
173
+ controller = Hooked::Controller.new(:foo, container.new)
174
+ assert_equal 4, controller.invoke(:something, 1)
175
+ end
176
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup(:default, :development)
4
+
5
+ require "test/unit"
6
+ require "mocha"
7
+ require "awesome_print"
8
+
9
+ require "hooked"
data/test/hook_test.rb ADDED
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + "/helper.rb"
2
+
3
+ class HookTest < Test::Unit::TestCase
4
+ def test_has_a_name
5
+ name = :foo
6
+ hook = Hooked::Hook.new(:before, name) {}
7
+
8
+ assert_equal name, hook.name
9
+ end
10
+
11
+ def test_has_a_type
12
+ build_hook = proc do |type|
13
+ Hooked::Hook.new(type, :foo) {}
14
+ end
15
+
16
+ hook = build_hook.call(:before)
17
+ assert_equal :before, hook.type
18
+
19
+ assert hook.before?
20
+ assert build_hook.call(:after).after?
21
+ assert build_hook.call(:around).around?
22
+
23
+ assert_raise(ArgumentError) do
24
+ build_hook.call(:asdas)
25
+ end
26
+ end
27
+
28
+ def test_has_relations
29
+ relations = {
30
+ :before => 123
31
+ }
32
+ hook = Hooked::Hook.new(:before, :foo, relations) {}
33
+ assert_equal(123, hook.relations[:before])
34
+
35
+ hook.relations[:before] = 456
36
+ assert_equal(456, hook.relations[:before])
37
+
38
+ hook.relations[:after] = "asd"
39
+ assert_equal("asd", hook.relations[:after])
40
+ end
41
+
42
+ def test_has_a_container
43
+ container = stub("container")
44
+ hook = Hooked::Hook.new(:before, :foo, {}, container) {}
45
+ assert_equal container, hook.container
46
+
47
+ container2 = stub("container2")
48
+ hook.container = container2
49
+ assert_equal container2, hook.container
50
+ end
51
+
52
+ def test_expects_a_block
53
+ assert_nothing_raised do
54
+ Hooked::Hook.new(:before, :foo) {}
55
+ end
56
+
57
+ assert_raise(ArgumentError) do
58
+ Hooked::Hook.new(:before, :foo)
59
+ end
60
+ end
61
+
62
+ def test_executes_block_in_the_containers_scope
63
+ scope = nil
64
+ hook = Hooked::Hook.new(:before, :foo) do
65
+ scope = self
66
+ end
67
+
68
+ assert_raise(RuntimeError) { hook.call }
69
+
70
+ container = stub("container")
71
+ hook.container = container
72
+ hook.call
73
+ assert_equal(container, scope)
74
+ end
75
+
76
+ def test_passes_arguments_to_the_block
77
+ args = [123, "asd"]
78
+ passed_args = nil
79
+ hook = Hooked::Hook.new(:before, :foo, {}, stub("container")) do |*args|
80
+ passed_args = args
81
+ end
82
+
83
+ hook.call(args)
84
+ assert_equal(args, passed_args)
85
+ end
86
+
87
+ def test_passes_blocks_return_to_the_caller
88
+ ret = 123
89
+ hook = Hooked::Hook.new(:before, :foo, {}, stub("container")) do
90
+ ret
91
+ end
92
+
93
+ assert_equal(ret, hook.call)
94
+ end
95
+ end
@@ -0,0 +1,71 @@
1
+ require File.dirname(__FILE__) + "/helper.rb"
2
+
3
+ class HookableTest < Test::Unit::TestCase
4
+ def test_has_a_name
5
+ name = :foo
6
+ hookable = Hooked::Hookable.new(name) {}
7
+
8
+ assert_equal name, hookable.name
9
+ end
10
+
11
+ def test_can_have_a_container
12
+ container = Object.new
13
+ hookable = Hooked::Hookable.new(:foo, container) {}
14
+
15
+ assert_equal container, hookable.container
16
+
17
+ assert_nil Hooked::Hookable.new(:foo) {}.container
18
+ end
19
+
20
+ def test_expects_a_block
21
+ assert_nothing_raised do
22
+ Hooked::Hookable.new(:foo) {}
23
+ end
24
+
25
+ assert_raise(ArgumentError) do
26
+ Hooked::Hookable.new(:foo)
27
+ end
28
+ end
29
+
30
+ def test_executes_block_in_the_containers_scope
31
+ container = Object.new
32
+
33
+ scope = nil
34
+ hookable = Hooked::Hookable.new(:foo, container) do
35
+ scope = self
36
+ end
37
+
38
+ hookable.call
39
+ assert_equal container, scope
40
+ end
41
+
42
+ def test_executes_block_in_its_original_scope_if_no_container_given
43
+ scope = nil
44
+ hookable = Hooked::Hookable.new(:foo) do
45
+ scope = self
46
+ end
47
+
48
+ hookable.call
49
+ assert_equal self, scope
50
+ end
51
+
52
+ def test_passes_arguments_to_the_block
53
+ args = [123, "asd"]
54
+ passed_args = nil
55
+ hookable = Hooked::Hookable.new(:foo) do |*args|
56
+ passed_args = args
57
+ end
58
+
59
+ hookable.call(args)
60
+ assert_equal(args, passed_args)
61
+ end
62
+
63
+ def test_passes_block_return_to_the_caller
64
+ ret = 123
65
+ hookable = Hooked::Hookable.new(:foo) do
66
+ ret
67
+ end
68
+
69
+ assert_equal(ret, hookable.call)
70
+ end
71
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hooked
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Lars Gierth
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-25 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: depression
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: test-unit
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: mocha
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ description: |-
64
+ hooked makes AOP a breeze. It lets you define and invoke
65
+ code that other gems or parts of your application can hook
66
+ onto. Supported hooks are before, after and around.
67
+ email:
68
+ - lars.gierth@gmail.com
69
+ executables: []
70
+
71
+ extensions: []
72
+
73
+ extra_rdoc_files: []
74
+
75
+ files:
76
+ - Gemfile
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - hooked.gemspec
81
+ - lib/hooked.rb
82
+ - lib/hooked/container.rb
83
+ - lib/hooked/controller.rb
84
+ - lib/hooked/hook.rb
85
+ - lib/hooked/hookable.rb
86
+ - lib/hooked/version.rb
87
+ - test/container_test.rb
88
+ - test/controller_test.rb
89
+ - test/helper.rb
90
+ - test/hook_test.rb
91
+ - test/hookable_test.rb
92
+ has_rdoc: true
93
+ homepage: http://rubygems.org/gems/hooked
94
+ licenses: []
95
+
96
+ post_install_message:
97
+ rdoc_options: []
98
+
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ requirements: []
120
+
121
+ rubyforge_project:
122
+ rubygems_version: 1.3.7
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Ruby library for Aspect Oriented Programming
126
+ test_files: []
127
+