ragot 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/ragot/version.rb +3 -0
  3. data/lib/ragot.rb +121 -0
  4. metadata +74 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c216474c3222f72271de2c6018be7b6b2332ca07
4
+ data.tar.gz: 6a429decec07ff3889b96d80769a14a90c23c1e0
5
+ SHA512:
6
+ metadata.gz: 7ce756577cd34a40b6be973a80323043c79be8cf57b7869d191385a59213bc63e1beb6ec3b0d670d074dfa2d14a0c6b1bb197c32430fbaa769ccd725c73c0d18
7
+ data.tar.gz: 7bbe3ff6aeed846184820acf7ebca8c8da956b422224ea200189ea3caa981a05562e132629f5464cd3b0823999012936376cb887e05ff09bb09db0fd8bc28489
@@ -0,0 +1,3 @@
1
+ module Ragot
2
+ VERSION = "0.1.0"
3
+ end
data/lib/ragot.rb ADDED
@@ -0,0 +1,121 @@
1
+ module Ragot
2
+
3
+ def self.included(klass)
4
+ klass.extend RagotInside
5
+ end
6
+
7
+ def env
8
+ @env ||= 'development'
9
+ end
10
+
11
+ def env=(env)
12
+ @env = env.to_s
13
+ end
14
+
15
+ def about(klass, *_, &block)
16
+ Declaration.for(klass).send (_.empty? ? :instance_exec : :ragot), *_, &block
17
+ end
18
+
19
+ module_function :about, :env, :env=
20
+
21
+ module RagotInside
22
+
23
+ def self.extended(klass)
24
+ unless klass.respond_to?(:after, true) || klass.respond_to?(:before, true)
25
+ klass.singleton_class.send :alias_method, :before, :declare_ragot
26
+ klass.singleton_class.send :alias_method, :after, :declare_ragot
27
+ end
28
+ end
29
+
30
+ def singleton_method_added(meth)
31
+ if method(meth).owner != Ragot::RagotInside && %i|before after|.include?(meth)
32
+ singleton_class.send :remove_method, (%i|before after| - [meth]).first
33
+ end
34
+ end
35
+
36
+ def method_added(meth)
37
+ Declaration.for(self).trigger meth
38
+ end
39
+
40
+ def declare_ragot(meth, options={}, &block)
41
+ hook = __callee__.to_s.split('_').last.to_sym
42
+ Declaration.for(self).ragot meth, options.merge(hook: hook), &block
43
+ end
44
+
45
+ alias_method :ragot_after, :declare_ragot
46
+ alias_method :ragot_before, :declare_ragot
47
+ private :declare_ragot
48
+
49
+ end
50
+
51
+ class Declaration
52
+
53
+ def self.for(klass)
54
+ (@collection ||= {})[klass] ||= new klass
55
+ end
56
+
57
+ def initialize(klass)
58
+ @klass, @ragots, @i = klass, {}, { klass => {}, klass.singleton_class => {} }
59
+ end
60
+
61
+ def trigger(meth)
62
+ @ragots[meth] && @ragots[meth].shift(@ragots[meth].size).each do |r|
63
+ __incept_ragot *r
64
+ end
65
+ end
66
+
67
+ def ragot(meth, options={}, &block)
68
+ __incept_ragot(meth.to_sym, block, options) ||
69
+ (@ragots[meth.to_sym] ||= []).push([meth.to_sym, block, options])
70
+ end
71
+
72
+ private
73
+
74
+ FAILSAFE = { 'demo' => true, 'production' => true }
75
+
76
+ def self.exec_hook(ragotee, failsafe, code, *result_and_params)
77
+ ragotee.instance_exec *result_and_params, &code
78
+ rescue => e
79
+ failsafe ? nil : raise(e)
80
+ end
81
+
82
+ def __incept_ragot(meth, blk, options)
83
+ o = { hook: :after, failsafe: FAILSAFE[Ragot.env], env: Ragot.env }.merge(options)
84
+ k = o[:class] ? @klass.singleton_class : @klass
85
+ @i[k][meth] ||= { before: [], after: [], stamp: [] }
86
+
87
+ return unless Array(o[:env]).map(&:to_s).include? Ragot.env
88
+ return unless (k.instance_methods + k.private_instance_methods).include? meth.to_sym
89
+
90
+ @i[k][meth][ :stamp ] << [ o[:failsafe], default_hook(meth, :before) ] if o[:stamp]
91
+ @i[k][meth][o[:hook]] << [ o[:failsafe], blk || default_hook(meth, o[:hook]) ]
92
+ @i[k][meth][:alias] ||= redefine k, meth, @i[k][meth]
93
+ end
94
+
95
+ def redefine(klass, meth, i)
96
+ klass.send :alias_method, "__ragot_inception_#{meth}", meth
97
+ klass.send :define_method, meth, ->(*_, &b) {
98
+ (i[:stamp] + i[:before]).each { |exe| Declaration.exec_hook self, *exe, *_ }
99
+ r = send "__ragot_inception_#{meth}", *_, &b
100
+ i[:after].each { |exe| Declaration.exec_hook self, *exe, r, *_ }
101
+ r
102
+ }
103
+ end
104
+
105
+ MESSAGE = { before: "Entered %s, with params %s,%s at %s .%s",
106
+ after: "`%s` called, with params : %s. Got '%s' as result, at %s .%s"
107
+ }
108
+
109
+ DEFAULT_HOOK = ->(hook, meth, result, *_) {
110
+ def ragot_talk(*_); puts *_; end unless respond_to? :ragot_talk, true
111
+ time = [Time.now].tap { |t| t << t.first.to_f.to_s.split('.').last }
112
+ ragot_talk MESSAGE[hook] % [meth, _.to_s, result, *time]
113
+ }
114
+
115
+ def default_hook(meth, hook)
116
+ ->(*_) { instance_exec hook, meth, _.shift, *_, &DEFAULT_HOOK }
117
+ end
118
+
119
+ end
120
+
121
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ragot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - lacravate
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.5.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 3.5.0
41
+ description: A gem to tell on methods and what they do, behind their backs. A hack
42
+ to create hooks around methods.
43
+ email:
44
+ - lacravate@lacravate.fr
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - lib/ragot.rb
50
+ - lib/ragot/version.rb
51
+ homepage: https://github.com/lacravate/ragot
52
+ licenses: []
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 2.4.5
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: A hack to create hooks around methods.
74
+ test_files: []