anchor 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/README.rdoc +76 -0
- data/lib/anchor.rb +2 -0
- data/lib/anchor/hooked.rb +74 -0
- data/lib/kernel.rb +9 -0
- metadata +69 -0
data/README.rdoc
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
== Purpose
|
2
|
+
|
3
|
+
Alternative for AOP libaries providing simple syntax and containing less than 100 rows of code.
|
4
|
+
|
5
|
+
Containing only:
|
6
|
+
* before
|
7
|
+
* after
|
8
|
+
* around
|
9
|
+
|
10
|
+
|
11
|
+
== Installation
|
12
|
+
|
13
|
+
Add to your Gemfile:
|
14
|
+
gem 'anchor'
|
15
|
+
|
16
|
+
And run:
|
17
|
+
bundle install
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
== Naming recommendations
|
22
|
+
|
23
|
+
You can name things as you want, but it is recommended to it so:
|
24
|
+
|
25
|
+
=== Example A
|
26
|
+
|
27
|
+
Create app/hooks/model_name.rb
|
28
|
+
hook to: ModelName do
|
29
|
+
|
30
|
+
before :save do |opts|
|
31
|
+
puts opts[:method_name]
|
32
|
+
puts opts[:arguments]
|
33
|
+
puts opts[:proc]
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
after :save do |opts|
|
38
|
+
puts opts[:method_name]
|
39
|
+
puts opts[:arguments]
|
40
|
+
puts opts[:proc]
|
41
|
+
puts opts[:return_value]
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
around :save do |opts|
|
46
|
+
puts opts[:method_name]
|
47
|
+
puts opts[:arguments]
|
48
|
+
puts opts[:proc]
|
49
|
+
|
50
|
+
# TODO ...
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
=== Example B
|
57
|
+
|
58
|
+
Create app/hooks/model_name/what_for_hook_is_itended.rb
|
59
|
+
...
|
60
|
+
|
61
|
+
|
62
|
+
=== Example C
|
63
|
+
|
64
|
+
You can also do in app/models/your_model.rb
|
65
|
+
|
66
|
+
class YourModel
|
67
|
+
extend Anchor::Hooked
|
68
|
+
|
69
|
+
before :save do
|
70
|
+
puts "Saving #{self.inspect}"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
data/lib/anchor.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
module Anchor
|
3
|
+
# Something similar to AOP, but much more simplified, providing:
|
4
|
+
# * before
|
5
|
+
# * after
|
6
|
+
# * around
|
7
|
+
module Hooked
|
8
|
+
# Information about hooks is stored in @hooks
|
9
|
+
attr_reader :hooks
|
10
|
+
# Orginal methods are not aliased but stored in @orginal_methods as UnboundMethod
|
11
|
+
attr_reader :orginal_methods
|
12
|
+
|
13
|
+
def before(*methods, &block)
|
14
|
+
create_hook(:before, *methods, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def after(*methods, &block)
|
18
|
+
create_hook(:after, *methods, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def around(*methods, &block)
|
22
|
+
create_hook(:around, *methods, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_hook(type, *methods, &block)
|
26
|
+
@hooks ||= {}
|
27
|
+
@orginal_methods ||= {}
|
28
|
+
|
29
|
+
methods.each do |method|
|
30
|
+
method_scope = :instance
|
31
|
+
method_name = case method; when Hash; method_scope, name = method.flatten; name; when Symbol; method; end
|
32
|
+
|
33
|
+
# if hook on static, call new hook on self metaclass
|
34
|
+
return hook({to: class << self; self; end}, &block) if method_scope == :static
|
35
|
+
|
36
|
+
# register hook
|
37
|
+
@hooks[method_name] ||= {}
|
38
|
+
@hooks[method_name][type] ||= []
|
39
|
+
@hooks[method_name][type] << block
|
40
|
+
|
41
|
+
# store and replace orginal method
|
42
|
+
unless @orginal_methods[method_name]
|
43
|
+
# store orginal
|
44
|
+
@orginal_methods[method_name] = self.instance_method(method_name)
|
45
|
+
|
46
|
+
# replace orginal to call hooks and orginal
|
47
|
+
define_method method_name do
|
48
|
+
hooks = self.class.methods.include?(:hooks) ? self.class.hooks : class << self; self.hooks; end
|
49
|
+
orginal_methods = self.class.methods.include?(:orginal_methods) ? self.class.orginal_methods : class << self; self.orginal_methods; end
|
50
|
+
# Hooks. Before.
|
51
|
+
before_hooks = hooks[method_name][:before]
|
52
|
+
before_hooks.each do |proc|
|
53
|
+
proc.call
|
54
|
+
end if before_hooks
|
55
|
+
# bind method to self and call
|
56
|
+
retval = orginal_methods[method_name].bind(self).call
|
57
|
+
# Hooks. After.
|
58
|
+
after_hooks = hooks[method_name][:after]
|
59
|
+
after_hooks.each do |proc|
|
60
|
+
proc.call
|
61
|
+
end if after_hooks
|
62
|
+
# return value returned by orginal method
|
63
|
+
retval
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
protected :create_hook
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/lib/kernel.rb
ADDED
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: anchor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- "Margus P\xC3\xA4rt"
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-01-01 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Inspired from multiple AOP libaries, but its much more simplified.
|
22
|
+
email: margus@tione.eu
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- README.rdoc
|
31
|
+
- lib/anchor/hooked.rb
|
32
|
+
- lib/kernel.rb
|
33
|
+
- lib/anchor.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: https://github.com/tione/anchor
|
36
|
+
licenses: []
|
37
|
+
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
segments:
|
49
|
+
- 1
|
50
|
+
- 9
|
51
|
+
- 2
|
52
|
+
version: 1.9.2
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.7
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Before, after and around method calls.
|
68
|
+
test_files: []
|
69
|
+
|