rhook - Easily drive AOP & hacking existing library with Ruby¶ ↑
-
Homepage & Source – github.com/kaorukobo/rhook
-
Download – rubygems.org/gems/rhook
-
API Documentation (RDoc) – rubydoc.info/github/kaorukobo/rhook/master/frames
Summary¶ ↑
-
You can provide hook point in your code,
-
and can customize its behavior from outside.
-
-
Also you can ‘hack’ (== injecting hook point from outside) any methods in existing code.
Install¶ ↑
gem install rhook
Basic Usage¶ ↑
step. Example code¶ ↑
class TargetBasic def greeting my_name = "Mike" your_name = "Dan" hello(your_name) + "I am #{my_name}." end def hello(name) "Hello, #{name}. " end end #/TargetBasic
that behaves as:¶ ↑
t = TargetBasic.new t.greeting.should == "Hello, Dan. I am Mike."
step. Insert hook point in TargetBasic¶ ↑
require "rhook" # <== load library. class TargetBasic def greeting my_name = _rhook.does(:my_name) { "Mike"; } # <== my_name = "Mike" your_name = "Dan" _rhook.to.hello(your_name) + "I am #{my_name}." # <== hello(your_name) + "I am #{my_name}." end def hello(name) "Hello, #{name}. " end end #/TargetBasic
step. Add hook from outside, and change behavior.¶ ↑
t = TargetBasic.new t._rhook.bind(:hello) { |inv| inv.args[0] = "Jenkins" # change first argument. inv.call } t._rhook.bind(:my_name) { |inv| "Katherine" # change return value. }
that behaves as:¶ ↑
t.greeting.should == "Hello, Jenkins. I am Katherine." ~~~~~~~ ~~~~~~~~~
More Basic TIPs¶ ↑
about ‘_rhook’¶ ↑
Once you require ‘rhook’, any objects has ‘_rhook’ method to access any rhook services. (that returns {RHook::RHookService} object.)
any_object = Object.new any_object._rhook.RHOOK_METHOD
See rubydoc.info/github/kaorukobo/rhook/master/RHook/RHookService
What is ‘inv’ ?¶ ↑
{RHook::Invocation} object, that contains:
-
call() method to proceed method invocation.
-
receiver, arguments/blcoks passed to method, and the other informations. See {RHook::Invocation}.
See rubydoc.info/github/kaorukobo/rhook/master/RHook/Invocation
If you want ‘bind’ to not only an object, but any instances of class:¶ ↑
TargetBasic._rhook.bind(:hello) { |inv| ...
If you want to HACK exisitng methods, use ‘_rhook.hack’:¶ ↑
for the paticular instance:
t = Time.now t._rhook.hack(:to_s) do |inv| "haha! I hacked to_s." end t.to_s.should == "haha! I hacked."
for entire class:
Time._rhook.hack(:to_s) do |inv| "haha! I hacked to_s." end (Time.now).to_s.should == "haha! I hacked to_s."
for class method:
Time._rhook.hack(:now) do |inv| "haha! you cannot get time." end Time.now.should == "haha! you cannot get time."
More Usage …¶ ↑
Please see spec: github.com/kaorukobo/rhook/blob/master/spec/rhook_spec.rb
Practical Examples¶ ↑
1. Log Buffer¶ ↑
Log Buffer allows you to capture any messages written to Logger and keep in buffer.
For example, you can examine the target program’s log messages in testing code.
github.com/kaorukobo/rhook/blob/master/spec/examples/log_buffer_example_spec.rb
…¶ ↑
Note on Patches/Pull Requests¶ ↑
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
Copyright¶ ↑
Copyright © 2010 Kaoru Kobo. See LICENSE for details.