Object Proxy
object-proxy provides proxy objects intended for intercepting calls to instance methods. It's aimed as tool for instant adapting the complex objects without complete deriving and extending whole classes in cases, where isn't possible to derive them as homogenic functional units or where it's simply impractical to derive them. Provides four base proxy types.
In all examples, object instance proxying is used, but both class objects and object instances proxying are supported. Simply give object instance instead of class object to the constructor. Wrapped object instance will be returned.
Standard Proxy
Works as intermediate layer between caller and called. Allows to invoke an handler both before method call and adjust its arguments and after call and post-proccess result.
See some slightly stupid example:
require "object-proxy"
s = OP::proxy("1 2 3 4")
s.before_split do |args|
args = [" "]
end
s.after_split do |result|
result.map { |i| i.to_i + 1 }
end
# This argument will be replaced in handler
out = s.split(",")
p out
Will print out [2, 3, 4, 5]
.
Fake Proxy
Simply fakes interface of an class, but with empty methods. Necessary methods can be individually overwritten by custom callbacks. It's equivalent to manual deriving class and reseting all its methods to nothing.
See some slightly stupid example:
pr = OP::fake(String, [:kind_of?]) do # we will use #kind_of? below,
# so we need say, we don't want to reset it
define_method :to_s do # let's say, '#to_s' will return
"alfa beta" # fixed value
end
end
pr.to_s == "alfa beta" # '#to_s' returns fixed value
pr.inspect.nil? # '#inspect' and all others are reset
# and return nil
pr.kind_of? String # but object still seems to be String :-)
Tracking Proxy
It's similar to standard proxy, but points all callbacks to single callback set (single for before call callbacks and single for after call callbacks). Also doesn't allow to modify arguments and postprocess results.
See some slightly stupid example:
calls = [ ]
s = OP::track("a,b,c,d")
s.before_call do |name| # sets 'before_call' handler
# track call names to array
calls << name
end
s << ",1,2,3"
s.gsub!(",", " ")
s.split(" ")
p calls
Will print out [:<<, :gsub!, :split]
.
Catching Proxy
Catches all method calls and forwards them to the #method_call
handler which
calls wrapped object by default, but can be overriden, so calls can be
fully controlled.
See some slightly stupid example:
s = OP::catch("foo")
s.method_call do |name, args, block|
if name == :to_s
s.wrapped.send(name, *args, &block)
else
:nothing
end
end
p s.replace("beta") # will print ":nothing" out
s.to_s # will print "foo" out
But object still seems to be String
.
Contributing
- Fork it.
- Create a branch (
git checkout -b 20101220-my-change
). - Commit your changes (
git commit -am "Added something"
). - Push to the branch (
git push origin 20101220-my-change
). - Create an Issue with a link to your branch.
- Enjoy a refreshing Diet Coke and wait.
Copyright
Copyright © 2011 Martin Kozák. See LICENSE.txt
for
further details.