Class: CheapAdvice
- Inherits:
-
Object
- Object
- CheapAdvice
- Includes:
- Options
- Defined in:
- lib/cheap_advice.rb,
lib/cheap_advice/trace.rb,
lib/cheap_advice/configuration.rb
Overview
Provides cheap advice mechanism for Ruby. See: github.com/kstephens/cheap_advice
Defined Under Namespace
Modules: Options, Trace Classes: ActivationRecord, Advised, Configuration, Error
Constant Summary collapse
- EMPTY_Hash =
{ }.freeze
- EMPTY_Array =
[ ].freeze
- EMPTY_String =
''.freeze
- NULL_PROC =
lambda { | ar | }
- NULL_AROUND_PROC =
lambda { | ar, body | body.call }
Instance Attribute Summary collapse
-
#advised ⇒ Object
Collection of Advised method bindings.
-
#advised_extend ⇒ Object
Module or Array of Modules to extend new Advised objects with.
-
#after ⇒ Object
Procs called before, after, and around the original method.
-
#around ⇒ Object
Procs called before, after, and around the original method.
-
#before ⇒ Object
Procs called before, after, and around the original method.
Attributes included from Options
Instance Method Summary collapse
-
#advise!(mod, method, *opts) ⇒ Object
Apply advice a method on a Module (or Class).
-
#advised_for(mod, meth, kind, opts) ⇒ Object
Returns the existing Advised binding or creates a new one.
- #advised_select(mod, meth, kind) ⇒ Object
-
#construct_advised_for(mod, meth, kind) ⇒ Object
Constructs an Advised binding from this Advice.
-
#disable! ⇒ Object
(also: #unadvise!)
Disables all currently Advised methods.
-
#enable! ⇒ Object
(also: #readvise!)
Enables all currently Advised methods.
-
#enabled! ⇒ Object
Called once the first time this advice is enabled.
-
#initialize(*opts, &blk) ⇒ CheapAdvice
constructor
options: :before :after :around.
Methods included from Options
Constructor Details
#initialize(*opts, &blk) ⇒ CheapAdvice
options:
:before
:after
:around
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/cheap_advice.rb', line 51 def initialize *opts, &blk super() @advised = [ ] @advised_for = { } opts_hash = Hash === opts[-1] ? opts.pop : { } opts_key = opts.shift @options = opts_hash @before = (opts_key == :before ? blk : opts_hash[:before]) || NULL_PROC @after = (opts_key == :after ? blk : opts_hash[:after]) || NULL_PROC @around = (opts_key == :around ? blk : opts_hash[:around]) || NULL_AROUND_PROC @blk = blk end |
Instance Attribute Details
#advised ⇒ Object
Collection of Advised method bindings.
39 40 41 |
# File 'lib/cheap_advice.rb', line 39 def advised @advised end |
#advised_extend ⇒ Object
Module or Array of Modules to extend new Advised objects with.
42 43 44 |
# File 'lib/cheap_advice.rb', line 42 def advised_extend @advised_extend end |
#after ⇒ Object
Procs called before, after, and around the original method.
36 37 38 |
# File 'lib/cheap_advice.rb', line 36 def after @after end |
#around ⇒ Object
Procs called before, after, and around the original method.
36 37 38 |
# File 'lib/cheap_advice.rb', line 36 def around @around end |
#before ⇒ Object
Procs called before, after, and around the original method.
36 37 38 |
# File 'lib/cheap_advice.rb', line 36 def before @before end |
Instance Method Details
#advise!(mod, method, *opts) ⇒ Object
Apply advice a method on a Module (or Class).
The advised method is enabled immediately (this may change in a future release).
Returns an Advised object that describes what method was advised.
mod can be a String, a Module or an Array of either. method can be a String, a Symbol or an Array of either. if either are Arrays the result will be an Array of Advised objects.
The type of method scope can be specified by:
-
:instance (default)
-
:class
-
:module
Any additional Hash options are propagated to the Advised binding object, which can be accessed from the ActivationRecord passed to the Advice block(s).
Examples:
advice = CheapAdvice(:around) { | ar, body | ...; body.call; ... }
advice.advise! MyClass, :instance_method, options_hash
advice.advise! MyClass, :class_method, :class
Each Advised object is extended with #advised_extend. The #advised Array lists all Advised object.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/cheap_advice.rb', line 98 def advise! mod, method, *opts return mod.map { | x | advise! x, method, *opts } if Array === mod return method.map { | x | advise! mod, x, *opts } if Array === method opts_hash = Hash === opts[-1] ? opts.pop : { } kind = opts.shift kind ||= :instance method = method.to_sym @mutex.synchronize do unless @enabled_once self.enabled! @enabled_once = true end advised = advised_for mod, method, kind, opts_hash advised.enable! # Should this really be automatically enabled?? advised end end |
#advised_for(mod, meth, kind, opts) ⇒ Object
Returns the existing Advised binding or creates a new one.
139 140 141 142 |
# File 'lib/cheap_advice.rb', line 139 def advised_for mod, meth, kind, opts (@advised_for[[ mod, meth, kind ]] ||= construct_advised_for(mod, meth, kind)).(opts) end |
#advised_select(mod, meth, kind) ⇒ Object
130 131 132 133 134 135 136 |
# File 'lib/cheap_advice.rb', line 130 def advised_select mod, meth, kind @advised.select do | ad | (mod ? mod == ad.mod : true) && (meth ? meth == ad.meth : true) && (kind ? kind == ad.kind : true) end end |
#construct_advised_for(mod, meth, kind) ⇒ Object
Constructs an Advised binding from this Advice.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/cheap_advice.rb', line 145 def construct_advised_for mod, meth, kind advice = self advised = Advised.new(advice, mod, meth, kind) case @advised_extend when nil when Module advised.extend(@advised_extend) when Array @advised_extend.each { | m | advised.extend(m) } else raise TypeError, "advised_extend: expected nil, Module or Array of Modules, given #{@advised_extend.class}" end advised.register_advice_methods! advised.define_new_method! @advised << advised advised end |
#disable! ⇒ Object Also known as: unadvise!
Disables all currently Advised methods.
171 172 173 174 175 176 |
# File 'lib/cheap_advice.rb', line 171 def disable! @mutex.synchronize do @advised.each { | x | x.disable! } end self end |
#enable! ⇒ Object Also known as: readvise!
Enables all currently Advised methods.
181 182 183 184 185 186 |
# File 'lib/cheap_advice.rb', line 181 def enable! @mutex.synchronize do @advised.each { | x | x.enable! } end self end |
#enabled! ⇒ Object
Called once the first time this advice is enabled. Instances can override this method.
126 127 128 |
# File 'lib/cheap_advice.rb', line 126 def enabled! self end |