Skip to content

Instantly share code, notes, and snippets.

@porty
Last active November 1, 2016 00:29
Show Gist options
  • Save porty/e4e87d0d7138aa99bf7f to your computer and use it in GitHub Desktop.
Save porty/e4e87d0d7138aa99bf7f to your computer and use it in GitHub Desktop.
Ruby method call display

Ruby Method Call Display Thing

Displays what methods are getting called, with what arguments, and their return values or exceptions thrown.

You just have to include Hax in the class you want to look at

This will probably break if your method is expecting a block

$ ruby example.rb
Patching Hello::hello
Patching Hello::hello_times
>> Calling Hello::hello with args []
Hello!
>> Returning nil
>> Calling Hello::hello_times with args [2]
>>>> Calling Hello::hello with args []
Hello!
>>>> Returning nil
>>>> Calling Hello::hello with args []
Hello!
>>>> Returning nil
>> Returning 1..2
>> Calling Hello::hello_times with args []
>> Threw exception ArgumentError - wrong number of arguments (0 for 1)
/Users/robertmcneil/Projects/99designs/roflcopter/hax.rb:41:in `throw': uncaught throw #<ArgumentError: wrong number of arguments (0 for 1)> (ArgumentError)
	from /Users/porty/hax/hax.rb:41:in `rescue in block (2 levels) in included'
	from /Users/porty/hax/hax.rb:30:in `block (2 levels) in included'
	from example.rb:21:in `<main>'
require './hax.rb'
class Hello
def hello
puts "Hello!"
end
def hello_times(times)
(1..times).each { hello }
end
include Hax
end
h = Hello.new
# basic example
h.hello
# call within a call
h.hello_times 2
# this will throw an argument exception
h.hello_times
module Hax
def self.increment_block
@block_count ||= 0
@block_count += 1
end
def self.decrement_block
@block_count -= 1
end
def self.print_message(str)
indent = '>>' * @block_count
str.gsub!("\n", "\n#{indent}+ ")
puts "#{indent} #{str}"
end
def self.included(klass)
klass.public_instance_methods(false).each do |m|
puts "Patching #{klass.name}::#{m.to_s}"
sym = m.to_sym
real_method_sym = "hax_#{m.to_s}".to_sym
klass.send(:alias_method, real_method_sym, sym)
klass.send(:define_method, sym) do |*args|
#puts ">> Calling #{klass.to_s}::#{sym.to_s} with args #{args.inspect}"
Hax.increment_block
Hax.print_message("Calling #{klass.to_s}::#{sym.to_s} with args #{args.inspect}")
begin
ret = send(real_method_sym, *args)
Hax.print_message("Returning #{ret.inspect}")
Hax.decrement_block
ret
rescue StandardError => e
Hax.print_message("Threw exception #{e.class.name} - #{e.message}")
if e.respond_to? :error_message
Hax.print_message("+ #{e.error_message}")
end
Hax.decrement_block
raise
end
end
end
end
end
<?php
class Porty_Superlog
{
public static function logArray($a) {
self::sendArray($a);
}
public static function logException($e, $metadata = array()) {
$a = array(
'class' => get_class($e),
'message' => $e->getMessage(),
'location' => $e->getFile() . ':' . $e->getLine(),
'backtrace' => array_slice($e->getTrace(), 0, 10),
'metadata' => $metadata
);
self::sendArray($a);
}
private static function sendArray($a) {
self::sendString(json_encode($a));
}
private static function sendString($s) {
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if ($sock === FALSE) {
error_log('Failed to create socket for Superlog: ' . socket_strerror(socket_last_error()));
return;
}
$s = 'mysystem ' . $s;
for ($i = 0; $i < 3; ++$i) {
if (socket_sendto($sock, $s, strlen($s), 0, '1.2.3.4', 4445) === FALSE) {
error_log('Failed to send packet for Superlog: ' . socket_strerror(socket_last_error($sock)));
}
usleep(100000); // 0.1s
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment