Module: ObjectProxy

Defined in:
lib/object-proxy.rb

Overview

Main ObjectProxy class.

Class Method Summary collapse

Class Method Details

.[](object) ⇒ Object, Class

Alias for ObjectProxy::proxy.

Parameters:

  • object (Object, Class)

Returns:

  • (Object, Class)

Since:

  • 0.2.0



111
112
113
# File 'lib/object-proxy.rb', line 111

def self.[](object)
    self::proxy(object)
end

.catch(object, &block) ⇒ Object, Class

Creates “catching object”. It means, it catches all method calls and forwards them to #method_call handler which calls wrapped object by default, but can be overriden, so calls can be controlled.

Parameters:

  • object (Object, Class)

    proxied object or class

  • block (Proc)

    default #method_call handler for whole class

Returns:

  • (Object, Class)

    anonymous proxy instance or class

Since:

  • 0.2.0



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/object-proxy.rb', line 260

def self.catch(object, &block)
    
    ### Takes class object
    
    _class = object
    if not _class.kind_of? Class
        _class = object.class
    end
    
    ### Defines class
    
    cls = Class::new(_class)
    cls.class_eval do

        # Eviscerates instances methods and replace them by 
        # +#handle_call+ invoker
        
        public_instance_methods.each do |method|
            if not method.in? [:object_id, :__send__, :class]
                define_method method do |*args, &block|
                    self.method_call.call(method, args, block)
                end
            end
        end
        
        # Adds constructor

        if not object.kind_of? Class
            define_method :initialize do |&block|
                @wrapped = object
                
                if not block.nil?
                   @method_call = block 
                else
                   @method_call = cls.class_variable_get(:@@method_call)
                end
                
                if @method_call.nil?
                    @method_call = Proc::new do |method, args, block|
                        @wrapped.send(method, *args, &block)
                    end
                end
            end
        else
            define_method :initialize do |*args, &block|
                @wrapped = _class::new(*args, &block)
                
                ic = cls.class_variable_get(:@@instance_created)
                if not ic.nil?
                    ic.call(self)
                end
            end                
        end
         
        # Defines handler assigners
        
        class_variable_set(:@@method_call, nil)
        define_singleton_method :method_call do |&block| 
            cls.class_variable_set(:@@method_call, block)
        end
        
        class_variable_set(:@@instance_created, nil)
        define_singleton_method :instance_created do |&block| 
            cls.class_variable_set(:@@instance_created, block)
        end
        
        # Sets up accessors and default handler            
        attr_accessor :wrapped

        define_method :method_call do |&block|
            if not block.nil?   # set
                @method_call = block
            else                # get
                result = @method_call
                
                if result.nil?
                    result = Proc::new do |method, args, block|
                        @wrapped.send(method, *args, &block)
                    end
                end                    
                
                return result
            end
        end
        
        attr_writer :method_call
                    
    end
    
    if object.kind_of? Class
        result = cls
    else
        result = cls::new
    end
    
    return result
    
end

.create(object) ⇒ Object, Class

Alias for ObjectProxy::proxy.

Parameters:

  • object (Object, Class)

Returns:

  • (Object, Class)

Since:

  • 0.1.0



123
124
125
# File 'lib/object-proxy.rb', line 123

def self.create(object)
    self::proxy(object)
end

.fake(cls, omit = [ ], &block) ⇒ Class

Creates fake object. “Fake object” means, all methods are replaced by empty functions or defined bodies.

Original class public instance functions are aliased to form: native_<name of function>.

Parameters:

  • cls (Class)

    class for fake

  • block (Proc)

    block with definitions of custom methods which will be run in private context of the faked class

Returns:

  • (Class)

    anonymous class faked object

Since:

  • 0.2.0



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/object-proxy.rb', line 141

def self.fake(cls, omit = [ ], &block)
    cls = Class::new(cls)
    cls.instance_eval do
        omit.concat([:object_id, :__send__])
        
        # Eviscerates instances methods and replace them by
        #   before and after handlers invoker
        public_instance_methods.each do |method|
            if not method.in? omit
                alias_method method.prepend("native_"), method
                define_method method do |*args, &block| end
            end
        end
    end
    
    if not block.nil?
        cls.instance_eval(&block)
    end
    
    return cls
end

.proxy(object) ⇒ Object, Class

Creates proxy object. “Proxy object” means, it calls handler if defined before and after each method call.

Parameters:

  • object (Object, Class)

    proxied object or class

Returns:

  • (Object, Class)

    anonymous proxy instance or class with before and after handlers functionality

Since:

  • 0.2.0



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/object-proxy.rb', line 23

def self.proxy(object)
    
    ### Takes class object
    
    _class = object
    if not _class.kind_of? Class
        _class = object.class
    end
    
    ### Defines class
    
    cls = Class::new(_class)
    cls.instance_eval do
    
        # Eviscerates instances methods and replace them by
        #   before and after handlers invoker
        public_instance_methods.each do |method|
            if not method.in? [:object_id, :__send__]
                define_method method do |*args, &block|
                    before = method.prepend("before_")
                    after = method.prepend("after_")
                    
                    # before handler
                    if @handlers.include? before
                        args, block = @handlers[before].call(args, block)
                    end
                    
                    # call
                    result = @wrapped.send(method, *args, &block)
                    
                    # after handler
                    if @handlers.include? after
                        result = @handlers[after].call(result)
                    end
                    
                    return result
                end
            end
        end
        
        # Adds constructor
        if object.kind_of? Class
            define_method :initialize do |*args, &block|
                @handlers = { }
                @wrapped = _class::new(*args, &block)
            end
        else
            define_method :initialize do |*args, &block|
                @handlers = { }
                @wrapped = object
            end            
        end
        
        # Event handlers assigning interceptor
        define_method :method_missing do |name, *args, &block|
            if name.start_with? "before_", "after_"
                self.register_handler(name, &block)
            end
        end
        
        # Assigns event handler
        define_method :register_handler do |name, &block|
            @handlers[name] = block
        end
        
        # Wrapped accessor
        
        attr_accessor :wrapped

    end
    
    if object.kind_of? Class
        result = cls
    else
        result = cls::new
    end
    
    return result
end

.track(object) ⇒ Object, Class

Creates “tracker object”. Works by similar way as standard proxy objects, but rather than invoking individual handlers for each method call invokes single handler before and single after call which receives except arguments or result the method name.

Also doesn’t support customizing the arguments or result.

Parameters:

  • object (Object, Class)

    proxied object or class

Returns:

  • (Object, Class)

    anonymous proxy instance or class with before and after handlers functionality

Since:

  • 0.2.0



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/object-proxy.rb', line 177

def self.track(object)
    
    ### Takes class object
    
    _class = object
    if not _class.kind_of? Class
        _class = object.class
    end
    
    ### Defines class
    
    cls = Class::new(_class)
    cls.class_eval do
    
        # Eviscerates instances methods and replace them by 
        # +#on_method+ invoker
        
        public_instance_methods.each do |method|
            if not method.in? [:object_id, :__send__, :class]
                define_method method do |*args, &block| 
                    if not @before_call.nil?
                        @before_call.call(method, args, block)
                    end
                    
                    result = @wrapped.send(method, *args, &block)
                    
                    if not @after_call.nil?
                        @after_call.call(method, result)
                    end
                    
                    return result
                end
            end
        end
        
        # Adds constructor
        
        if object.kind_of? Class
            define_method :initialize do |*args, &block|
                @wrapped = _class::new(*args, &block)
            end                
        else
            define_method :initialize do |*args, &block|
                @wrapped = object
            end                
        end
        
        # Defines handler assigners
        
        define_method :before_call do |&block|
            @before_call = block
        end
        
        define_method :after_call do |&block|
            @after_call = block
        end
        
        # Wrapped accessor
        
        attr_accessor :wrapped
                                
    end
    
    if object.kind_of? Class
        result = cls
    else
        result = cls::new
    end
    
    return result
end