Rallhook is a project mainly written in C and RUBY, based on the GPL-3.0 license.
Allow hooking of all method invocations transparently to control and / or monitor the behavior of a ruby program
= rallhook - An ruby absolute method hooker
This package contains rallhook, a ruby C extension to intercept ruby methods calls at interpreter level in a transparent way from ruby itself.
== Installation
=== Prerequisites
=== Installation
sudo gem install rallhook
OR
sudo gem install rallhook-X.X.X.gem
== Usage
=== Basic Example
test.rb:
require "rubygems"
require "rallhook"
include RallHook
class MethodHandler < HookHandler
def handle_method (klass,self_,m, method_id)
# print to the standar output details about the method called
print "method call #{m}:#{method_id} over #{self_}:#{self_.class}
"
nil # do nothing
end
end
MethodHandler.hook do
# all ruby calls in this block are intercepted by hook_recv::call
[1,2,3].each do |x|
print x,"
"
end
end
standard output:
method call each:4001 over 123:Array
method call print:7697 over main:Object
method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call to_s:3137 over 1:Fixnum
1method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call print:7697 over main:Object
method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call to_s:3137 over 2:Fixnum
2method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call print:7697 over main:Object
method call write:7649 over #<IO:0x7fb15e54fad0>:IO
method call to_s:3137 over 3:Fixnum
3method call write:7649 over #<IO:0x7fb15e54fad0>:IO
=== Redirecting calls
require "rubygems"
require "rallhook"
include RallHook
class MethodHandler < HookHandler
include RallHook::Helper
def handle_method (klass,recv,m,method_id)
if m == :foo
# redirects the calls of method foo to method bar on the same object
return redirect_call(klass,recv, :bar)
end
if m == :bar
# redirects the calls of method bar to method bar on the method_handler
return redirect_call(self.class,self, :bar)
end
nil # do nothing
end
def bar
print "bar in MethodHandler
"
end
end
class X
def foo
print "foo in X
"
end
def bar
print "bar in X
"
end
end
print "WITHOUT HOOK:
"
x = X.new
x.foo
x.bar
print "WITH HOOK:
"
MethodHandler.hook do
# all ruby calls in this block are intercepted by hook_recv::call
x = X.new
x.foo # redirected to X#bar
x.bar # redirected to MethodHandler#bar
end
=== Wrap Calls require "rubygems" require "rallhook"
include RallHook
class MethodHandler < HookHandler
include RallHook::Helper
class FooMethodWrapper < MethodWrapper
def call(*x)
# call with reyield if block_given
if block_given?
original_call(*x) do |*a|
yield(*a)
end
# add "�bar?"
yield("bar?")
else
original_call(*x)
end
end
end
def handle_method (klass,recv,m,method_id)
if m == :each
return FooMethodWrapper.redirect_handler(klass,recv,m,method_id)
end
nil # do nothing
end
end
print "calling Array#each without hook
"
[1,2,3,4].each do |x|
print x.inspect, " "
end
print "
"
print "calling Array#each WITH hook
"
MethodHandler.hook do
# 1 2 3 4 "bar?"
[1,2,3,4].each do |x|
print x.inspect," "
end
print "
"
end
=== Method Instrospection new features example
source1.rb
class X
def foo
end
end
source2.rb
class Y < X
def foo
end
end
main.rb
require "rallhook"
require "source1.rb"
require "source2.rb"
x = X.new
y = Y.new
print x.method(:foo).body.file,"
" # source1.rb
print y.method(:foo).body.file,"
" # source2.rb
print y.method(X,:foo).body.file,"
" # source1.rb
print y.method(Y,:foo).body.file,"
" # source2.rb
== Copying
Copyright (c) 2010 Dario Seminara, released under the GPL License (see LICENSE)