interception 0.1.pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .rbx
2
+ ext/Makefile
3
+ *.class
4
+ *.o
5
+ *.so
6
+ *.gem
data/ext/extconf.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'rbconfig'
2
+
3
+ if RbConfig::CONFIG['ruby_install_name'] == 'jruby'
4
+
5
+ File.open("Makefile", "w") do |f|
6
+ f.write "install:\n\tjrubyc --javac org/pryrepl/InterceptionEventHook.java\n"
7
+ end
8
+
9
+ elsif RbConfig::CONFIG['ruby_install_name'] == 'ruby'
10
+
11
+ require 'mkmf'
12
+ $CFLAGS += " -DRUBY_19" if RUBY_VERSION =~ /^1.9/
13
+ extension_name = "interception"
14
+ dir_config(extension_name)
15
+ create_makefile(extension_name)
16
+
17
+ else
18
+
19
+ File.open("Makefile", "w") do |f|
20
+ f.write "install:\n\t:\n"
21
+ end
22
+
23
+ end
@@ -0,0 +1,52 @@
1
+ #include "ruby.h"
2
+
3
+ static VALUE rb_mInterception;
4
+
5
+ #ifdef RUBY_19
6
+
7
+ void
8
+ interception_hook(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass)
9
+ {
10
+ VALUE binding = rb_funcall(rb_mKernel, rb_intern("binding"), 0, NULL);
11
+ rb_funcall(rb_mInterception, rb_intern("rescue"), 2, rb_errinfo(), binding);
12
+ }
13
+
14
+ VALUE
15
+ interception_start(VALUE self)
16
+ {
17
+ rb_add_event_hook(interception_hook, RUBY_EVENT_RAISE, rb_mInterception);
18
+ }
19
+
20
+ #else
21
+
22
+ #include "node.h"
23
+
24
+ void
25
+ interception_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
26
+ {
27
+ VALUE binding = rb_funcall(rb_mKernel, rb_intern("binding"), 0, NULL);
28
+ rb_funcall(rb_mInterception, rb_intern("rescue"), 2, ruby_errinfo, binding);
29
+ }
30
+
31
+ VALUE
32
+ interception_start(VALUE self)
33
+ {
34
+ rb_add_event_hook(interception_hook, RUBY_EVENT_RAISE);
35
+ }
36
+
37
+ #endif
38
+
39
+ VALUE
40
+ interception_stop(VALUE self)
41
+ {
42
+ rb_remove_event_hook(interception_hook);
43
+ return Qnil;
44
+ }
45
+
46
+ void
47
+ Init_interception()
48
+ {
49
+ rb_mInterception = rb_define_module("Interception");
50
+ rb_define_singleton_method(rb_mInterception, "start", interception_start, 0);
51
+ rb_define_singleton_method(rb_mInterception, "stop", interception_start, 0);
52
+ }
@@ -0,0 +1,29 @@
1
+ package org.pryrepl;
2
+
3
+ import org.jruby.runtime.builtin.IRubyObject;
4
+ import org.jruby.runtime.EventHook;
5
+ import org.jruby.runtime.RubyEvent;
6
+ import org.jruby.runtime.ThreadContext;
7
+ import org.jruby.RubyException;
8
+ import org.jruby.RubyBinding;
9
+ import org.jruby.RubyProc;
10
+
11
+ public class InterceptionEventHook extends EventHook {
12
+
13
+ private RubyProc proc;
14
+
15
+ public InterceptionEventHook(RubyProc proc) {
16
+ super();
17
+ this.proc = proc;
18
+ }
19
+
20
+ public boolean isInterestedInEvent(RubyEvent event) {
21
+ return event.getName().equals(RubyEvent.RAISE.getName());
22
+ }
23
+
24
+ public void eventHandler(ThreadContext context, String eventName, String file, int line, String name, IRubyObject type) {
25
+ RubyBinding binding = RubyBinding.newBinding(context.runtime, context.currentBinding());
26
+ RubyException exception = (RubyException)context.runtime.getGlobalVariables().get("$!");
27
+ proc.call(context, new IRubyObject[] {exception, binding});
28
+ }
29
+ }
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "interception"
3
+ s.version = "0.1.pre.1"
4
+ s.author = "Conrad Irwin"
5
+ s.email = "conrad.irwin@gmail.com"
6
+ s.homepage = "http://github.com/ConradIrwin/interception"
7
+ s.summary = "Intercept exceptions as they are being raised"
8
+ s.description = "Provides a cross-platform ability to intercept all exceptions as they are raised."
9
+
10
+ s.files = `git ls-files`.split("\n")
11
+ s.extensions = "ext/extconf.rb"
12
+ s.require_path = "lib"
13
+
14
+ s.add_development_dependency 'rake'
15
+ end
@@ -0,0 +1,84 @@
1
+ require 'thread'
2
+
3
+ module Interception
4
+
5
+ class << self
6
+ attr_accessor :mutex, :listeners
7
+ end
8
+
9
+ self.mutex = Mutex.new
10
+ self.listeners = []
11
+
12
+ def self.listen(for_block=nil, &listen_block)
13
+ raise "no block given" unless listen_block || for_block
14
+ mutex.synchronize{
15
+ listeners << listen_block || for_block
16
+ start
17
+ }
18
+
19
+ if listen_block && for_block
20
+ begin
21
+ for_block.call
22
+ ensure
23
+ unlisten listen_block
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.unlisten(listen_block)
29
+ mutex.synchronize{
30
+ listeners.delete listen_block
31
+ stop if listeners.empty?
32
+ }
33
+ end
34
+
35
+ def self.rescue(e, binding)
36
+ listeners.each do |l|
37
+ l.call(e, binding)
38
+ end
39
+ end
40
+
41
+ if defined? Rubinius
42
+ def self.start
43
+ class << Rubinius
44
+ alias raise_with_no_interception raise_exception
45
+
46
+ def raise_exception(exc)
47
+ bt = Rubinius::VM.backtrace(1, true).drop_while do |x|
48
+ x.variables.method.file.to_s.start_with?("kernel/")
49
+ end.first
50
+ b = Binding.setup(bt.variables, bt.variables.method, bt.constant_scope, bt.variables.self, bt)
51
+
52
+ Interception.rescue(exc, b)
53
+ raise_with_no_interception(exc)
54
+ end
55
+ end
56
+ end
57
+
58
+ def self.stop
59
+ class << Rubinius
60
+ alias raise_exception raise_with_no_interception
61
+ end
62
+ end
63
+ elsif defined?(JRuby)
64
+ $CLASSPATH << File.expand_path('../../ext/', __FILE__)
65
+ java_import org.pryrepl.InterceptionEventHook
66
+
67
+ def self.start
68
+ JRuby.runtime.add_event_hook(hook)
69
+ end
70
+
71
+ def self.stop
72
+ JRuby.runtime.remove_event_hook(hook)
73
+ end
74
+
75
+ def self.hook
76
+ @hook ||= InterceptionEventHook.new(proc do |e, b|
77
+ self.rescue(e, b)
78
+ end)
79
+ end
80
+
81
+ else
82
+ require File.expand_path('../../ext/interception.so', __FILE__)
83
+ end
84
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: interception
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: 4
5
+ version: 0.1.pre.1
6
+ platform: ruby
7
+ authors:
8
+ - Conrad Irwin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-11 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ version_requirements: &2056 !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ none: false
22
+ requirement: *2056
23
+ prerelease: false
24
+ type: :development
25
+ description: Provides a cross-platform ability to intercept all exceptions as they are raised.
26
+ email: conrad.irwin@gmail.com
27
+ executables: []
28
+ extensions:
29
+ - ext/extconf.rb
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - ext/extconf.rb
34
+ - ext/interception.c
35
+ - ext/org/pryrepl/InterceptionEventHook.java
36
+ - interception.gemspec
37
+ - lib/interception.rb
38
+ homepage: http://github.com/ConradIrwin/interception
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ none: false
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>'
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.1
55
+ none: false
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 1.8.15
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Intercept exceptions as they are being raised
62
+ test_files: []
63
+ ...