anchor 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+
@@ -0,0 +1,2 @@
1
+ require 'hooks/hooked'
2
+ require 'kernel'
@@ -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
@@ -0,0 +1,9 @@
1
+ module Kernel
2
+ def hook(opts, &block)
3
+ hook_to = opts[:to]
4
+ hook_to.module_eval do
5
+ extend Anchor::Hooked
6
+ module_eval &block
7
+ end
8
+ end
9
+ end
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
+