rallhook

Allow hooking of all method invocations transparently to control and / or monitor the behavior of a ruby program


License
GPL-3.0
Install
gem install rallhook -v 0.8.0

Documentation

= 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

* ruby-cymbol >= 0.1.0 (found at http://github.com/tario/ruby-cymbol)
* ruby debug info ( apt-get install libruby1.8-dbg or libruby1.9-dbg on debian based systems)
* ruby development package ( apt-get install ruby1.8-dev or ruby1.9-dev on debian based systems)
* objdump

=== Installation

* run in your system

sudo gem install rallhook

OR

* Download the last version of the gem from http://github.com/tario/ruby-cpp/downloads
* Install the gem with the following;

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} \n"
			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,"\n"
		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\n"
		end
	end

	class X
		def foo
			print "foo in X\n"
		end
		def bar
			print "bar in X\n"
		end
	end

	print "WITHOUT HOOK:\n"

	x = X.new
	x.foo
	x.bar

	print "WITH HOOK:\n"

	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\n"
	[1,2,3,4].each do |x|
		print x.inspect, " "
	end
	print "\n"

	print "calling Array#each WITH hook\n"
	MethodHandler.hook do

		# 1 2 3 4 "bar?"
		[1,2,3,4].each do |x|
			print x.inspect," "
		end
		print "\n"

	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,"\n" # source1.rb
	print y.method(:foo).body.file,"\n" # source2.rb

	print y.method(X,:foo).body.file,"\n" # source1.rb
	print y.method(Y,:foo).body.file,"\n" # source2.rb


== Copying

Copyright (c) 2010 Dario Seminara, released under the GPL License (see LICENSE)