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.
@@ -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
+