anchor 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|