Skip to content
This repository
Browse code

Added YARD document.

  • Loading branch information...
commit 380aa9b93a48e525ccbcde47d93e089c785a422c 1 parent a0dc635
authored November 24, 2010
2  .gitignore
@@ -17,5 +17,7 @@ tmtags
17 17
 coverage
18 18
 rdoc
19 19
 pkg
  20
+doc
  21
+.yardoc
20 22
 
21 23
 ## PROJECT::SPECIFIC
2  .yardopts
... ...
@@ -0,0 +1,2 @@
  1
+--no-private
  2
+--title "rhook"
9  Rakefile
@@ -43,3 +43,12 @@ Rake::RDocTask.new do |rdoc|
43 43
   rdoc.rdoc_files.include('README*')
44 44
   rdoc.rdoc_files.include('lib/**/*.rb')
45 45
 end
  46
+
  47
+begin
  48
+  gem "yard"
  49
+  require "yard"
  50
+  YARD::Rake::YardocTask.new do |t|
  51
+  end
  52
+rescue Gem::LoadError
  53
+  
  54
+end
138  lib/rhook.rb
... ...
@@ -1,4 +1,7 @@
1 1
 module RHook
  2
+  # @private
  3
+  # The registry contains information globally shared. (like cache)
  4
+  # You don't need to use this class.
2 5
   class Registry
3 6
     attr_reader :class_cached_flag_map
4 7
     def initialize
@@ -6,19 +9,42 @@ def initialize
6 9
     end
7 10
   end
8 11
   
  12
+  # @private
  13
+  # Get global +Registry+ object.
9 14
   def self.registry
10 15
     @registry ||= Registry.new
11 16
   end
12 17
   
  18
+  # Most important class on rhook.
  19
+  # 
  20
+  # If you call obj._rhook, it returns a RHookService object bound to +obj+. 
13 21
   class RHookService
  22
+    # @private
14 23
     attr_reader :hooks_map
15 24
     
  25
+    # @private
16 26
     def initialize(obj)
17 27
       @obj = obj
18 28
       @hooks_map = {}
19 29
       @class_cached_hooks_map = {} if Class === @obj
20 30
     end
21 31
     
  32
+    # Returns the object bound to this RHookService.
  33
+    # ( +obj+ of +obj._rhook+ ) 
  34
+    def bound_object
  35
+      @obj
  36
+    end
  37
+    
  38
+    # @group Methods for hook-side(outside)
  39
+    # 
  40
+    # Add hook to the {#bound_object}. If it is a kind of Class, the hook is affected to all instance & subclasses of the class.
  41
+    # 
  42
+    # @param [Symbol] name hook-point's name (commonly equals to method name)
  43
+    # @option opt [true] :disable Create hook but make disabled. (by default, automatically enabled.)
  44
+    # @yield [inv] The hook block.
  45
+    # @yieldparam [Invocation] inv
  46
+    # @yieldreturn The result value. (Returned value of called method.)
  47
+    # @return [Hook] Created hook.
22 48
     def bind(name, opt = {}, &block)
23 49
       hook = Hook.new
24 50
       hook.hook_proc = block
@@ -29,6 +55,15 @@ def bind(name, opt = {}, &block)
29 55
       hook
30 56
     end
31 57
     
  58
+    # @group Methods for hook-side(outside)
  59
+    # 
  60
+    # Injects hook-point (hack) to the paticular method in {#bound_object}, and add hook same as {#bind}.
  61
+    #
  62
+    # The hook-point injection is done by 'alias' method.
  63
+    # If the hook-point is already injected, this just does {#bind}.
  64
+    #
  65
+    # @param [Symbol] name    The name of method to hack.
  66
+    # @see #bind See #bind for other param/return.
32 67
     def hack(name, opt = {}, &block)
33 68
       success = false
34 69
       if Class === @obj
@@ -44,13 +79,15 @@ def hack(name, opt = {}, &block)
44 79
       bind(name, opt, &block)
45 80
     end
46 81
     
  82
+    # @group Methods for hook-side(outside)
  83
+    # 
  84
+    # Unbind all hooks bound to {#bound_object}.
47 85
     def unbind_all
48 86
       @hooks_map.clear
49 87
       @class_cached_hooks_map.clear
50 88
     end
51 89
     
52  
-    # nodoc:
53  
-    # Proxy class for 'to'
  90
+    # @private
54 91
     class Caller
55 92
       def initialize(rhook, opt)
56 93
         @rhook = rhook
@@ -62,13 +99,20 @@ def method_missing(name, *args, &block)
62 99
       end
63 100
     end #/Caller
64 101
     
65  
-    # ================================================================
66  
-    # Target-side methods:
67  
-    
  102
+    # @group Methods for target-side (ex. providing hook-point)
  103
+    # 
  104
+    # Wraps {#bound_object}'s method call to be hookable.
  105
+    #
  106
+    # @example 
  107
+    #   _rhook.to.method_name(arg1, arg2)
  108
+    #
  109
+    # @option opt [Hash] :hint Hint values used through {Invocation#hint}.
  110
+    # @return Proxy to call method.
68 111
     def to(opt = {})
69 112
       Caller.new(self, opt)
70 113
     end
71 114
     
  115
+    # @private
72 116
     def call_method(name, method_name, args, block, opt = {})
73 117
       hooks = concat_hooks([], name)
74 118
       hooks.empty? and return @obj.__send__(method_name, *args, &block)
@@ -84,6 +128,17 @@ def call_method(name, method_name, args, block, opt = {})
84 128
       inv.proceed()
85 129
     end
86 130
     
  131
+    # @group Methods for target-side (ex. providing hook-point)
  132
+    # 
  133
+    # Wraps the code block to be hookable.
  134
+    #
  135
+    # @example
  136
+    #   _rhook.does(:hook_name) { do_something; }
  137
+    #
  138
+    # @param [Symbol] name The hook-point's name specified on {#bind}.
  139
+    # @option opt [Hash] :hint Hint values used through {Invocation#hint}.
  140
+    # @yield The code block to be hooked.
  141
+    # @return The result of code block. (Replaced if it is changed by hook.)
87 142
     def does(name, opt = {}, &block)
88 143
       hooks = concat_hooks([], name)
89 144
       hooks.empty? and return yield
@@ -99,6 +154,21 @@ def does(name, opt = {}, &block)
99 154
       inv.proceed()
100 155
     end
101 156
     
  157
+    # @group Methods for target-side (ex. providing hook-point)
  158
+    # 
  159
+    # Wraps the defined method to be hookable.
  160
+    # 
  161
+    # If possible, using {#to} is recommended than {#on_method}, because if the subclass override the hookable method, the subclasse's code become out of hook target.
  162
+    #
  163
+    # @example
  164
+    #   on_method :method_name
  165
+    #
  166
+    # @overload on_method(name1, name2, ..., opt = {})
  167
+    # @param [String] name The method name. (can specify multiple.)
  168
+    # @param _and_opt [Hash] Options
  169
+    #     * :ifdef => true - Don't raise error whenever the method is not defined.
  170
+    # @raise [NameError] If the method is not defined.
  171
+    # @return [Boolean] When :ifdef => true, returns sucess or not, otherwise always true.
102 172
     def on_method(*names_and_opt)
103 173
       success = true
104 174
       
@@ -122,9 +192,7 @@ def on_method(*names_and_opt)
122 192
       success
123 193
     end
124 194
     
125  
-    # ================================================================
126  
-    # Internal methods:
127  
-    
  195
+    # @private
128 196
     def concat_hooks(dest, name)
129 197
       if Class === @obj
130 198
         concat_class_hooks(dest, name)
@@ -135,6 +203,7 @@ def concat_hooks(dest, name)
135 203
       dest
136 204
     end
137 205
     
  206
+    # @private
138 207
     def concat_class_hooks(dest, name)
139 208
       # use cached one if available
140 209
       if RHook.registry.class_cached_flag_map[name]
@@ -145,7 +214,7 @@ def concat_class_hooks(dest, name)
145 214
       end
146 215
       
147 216
       hooks = []
148  
-
  217
+      
149 218
       # collect hooks including ancestor classes
150 219
       begin
151 220
         concat_hooks_internal(hooks, name)
@@ -168,17 +237,31 @@ def concat_class_hooks(dest, name)
168 237
       dest.concat(hooks)
169 238
     end
170 239
     
  240
+    # @private
171 241
     def concat_hooks_internal(dest, name)
172 242
       hooks = @hooks_map[name]
173 243
       hooks and dest.concat(hooks)
174 244
     end
175 245
   end #/RHookService
176 246
   
  247
+  # The object contains the invocation information.
  248
+  #
  249
+  # @attr [Object] target The target object that the hook is applied. (Usually same to {#receiver})
  250
+  # @attr [Object] receiver The receiver object of this method invocation.
  251
+  # @attr [Array<Object>] args The arguments given to the method invocation. 
  252
+  # @attr [Object] block The block given to the method invocation
  253
+  # @attr [Object] returned The returned value by the method invocation. (Don't set this. To change it, just return by the alternative value from the hook procedure.) 
  254
+  # @attr [Array<Hook>] hooks (Internally used) The applied hooks on this invocation.
  255
+  # @attr [Proc] target_proc (Internally used) The procedure to execute the target method/procedure.
  256
+  # @attr [Hash] hint Hint data given by {RHookService#does} / {RHookService#to}.
177 257
   class Invocation < Struct.new(:target, :receiver, :args, :block, :returned, :hooks, :target_proc, :hint)
  258
+    # @private
178 259
     def initialize
179 260
       @hook_index = 0
180 261
     end
181 262
     
  263
+    # Proceed to execute the next one on hooks-chain. If no more hooks, execute the target method/procedure.
  264
+    # @return The returned value from the target method/procedure. (may changed by hook)
182 265
     def proceed
183 266
       hook = hooks[@hook_index]
184 267
       # -- If no more hook was found, calls target procedure and return
@@ -195,15 +278,23 @@ def proceed
195 278
     alias call proceed
196 279
   end #/Invocation
197 280
   
  281
+  # The registered hook instance returned by #{RHookService#bind}.
198 282
   class Hook
  283
+    # Whether this hook is enabled.
199 284
     attr_accessor :enabled
  285
+    # The hook procedure.
200 286
     attr_accessor :hook_proc
201 287
     
  288
+    # @private
202 289
     def call(inv)
203 290
       @enabled or return inv.proceed()
204 291
       hook_proc.call(inv)
205 292
     end
206 293
     
  294
+    # Enable this hook.
  295
+    # @overload enable()
  296
+    # @overload enable(&block)
  297
+    # @yield If block was given, the hook is enabled only within the given code block. (Note: This is not thread-safe.)
207 298
     def enable(&block)
208 299
       @enabled = true
209 300
       if block_given?
@@ -216,31 +307,43 @@ def enable(&block)
216 307
       self
217 308
     end
218 309
     
  310
+    # Disable this hook.
219 311
     def disable
220 312
       @enabled = false
221 313
       self
222 314
     end
223 315
   end #/Hook
224 316
   
  317
+  # 
225 318
   class ::Object
  319
+    # Get {RHookService} object bound to this object.
226 320
     def _rhook
227 321
       @_rhook ||= RHook::RHookService.new(self)
228 322
     end
229 323
     
  324
+    # @private
230 325
     def _has_rhook?
231 326
       @_rhook ? true : false
232 327
     end
233 328
   end
234 329
   
  330
+  # Object to group the hooks for the certain purpose.
  331
+  # You can enable/disable the grouped hooks at once.
  332
+  #
  333
+  # Don't instantiate this class. Use {RHook.group} method.
235 334
   class HookGroup
  335
+    # @private
236 336
     def initialize
237 337
       @hooks = []
238 338
     end
239 339
     
  340
+    # Add a new hook to this group.
240 341
     def add(hook)
241 342
       @hooks << hook
242 343
     end
243 344
     
  345
+    # Add any hooks to this group that was registered by #{RHookService#bind} in the given block code.
  346
+    # @return [HookGroup] itself
244 347
     def wrap(&block)
245 348
       group_stack = (Thread.current["rhook_group"] ||= [])
246 349
       group_stack << self 
@@ -252,6 +355,8 @@ def wrap(&block)
252 355
       self
253 356
     end
254 357
     
  358
+    # Enable the hooks.
  359
+    # @see Hook#enable
255 360
     def enable(&block)
256 361
       @hooks.each do |h|
257 362
         h.enable
@@ -266,6 +371,8 @@ def enable(&block)
266 371
       self
267 372
     end
268 373
     
  374
+    # Disable the hooks.
  375
+    # @see Hook#disable
269 376
     def disable
270 377
       @hooks.each do |h|
271 378
         h.disable
@@ -273,13 +380,24 @@ def disable
273 380
       self
274 381
     end
275 382
     
  383
+    # @private
276 384
     def self.add_to_current_groups(hook)
277  
-      (Thread.current["rhook_group"] || []).each do |group|
  385
+     (Thread.current["rhook_group"] || []).each do |group|
278 386
         group.add(hook)
279 387
       end
280 388
     end
281 389
   end #/HookGroup
282 390
   
  391
+  # Create the {HookGroup}, and add any hooks to this group that was registered by #{RHookService#bind} in the given block code.
  392
+  # 
  393
+  # @example
  394
+  #   XXX_feature_for_library = RHook.group {
  395
+  #     Target._rhook.bind(...) {...}
  396
+  #     Target2._rhook.bind(...) {...}
  397
+  #   }
  398
+  #   XXX_feature_for_library.disable
  399
+  # 
  400
+  # @return [HookGroup]
283 401
   def self.group(&block)
284 402
     HookGroup.new.wrap(&block)
285 403
   end

0 notes on commit 380aa9b

Please sign in to comment.
Something went wrong with that request. Please try again.