boc 0.3.2-x86-mswin32 → 0.4.2-x86-mswin32
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/CHANGES.rdoc +5 -0
- data/README.rdoc +5 -5
- data/Rakefile +133 -7
- data/devel/levitate.rb +234 -340
- data/ext/boc/boc.c +6 -12
- data/jext/boc/BocService.java +111 -0
- data/lib/{boc.so → boc/boc.so} +0 -0
- data/lib/boc/version.rb +1 -1
- data/lib/boc.rb +80 -60
- data/test/basic_test.rb +58 -9
- data/test/jruby_trial.rb +20 -0
- data/test/readme_test.rb +7 -3
- metadata +6 -5
- data/MANIFEST +0 -14
data/ext/boc/boc.c
CHANGED
@@ -15,8 +15,7 @@ struct dispatch_args
|
|
15
15
|
ID method_id ;
|
16
16
|
} ;
|
17
17
|
|
18
|
-
static
|
19
|
-
VALUE
|
18
|
+
static VALUE
|
20
19
|
begin_section( VALUE data )
|
21
20
|
{
|
22
21
|
struct dispatch_args* dargs = (struct dispatch_args*)data ;
|
@@ -28,8 +27,7 @@ begin_section( VALUE data )
|
|
28
27
|
dargs->argv) ;
|
29
28
|
}
|
30
29
|
|
31
|
-
static
|
32
|
-
VALUE
|
30
|
+
static VALUE
|
33
31
|
ensure_section( VALUE unused )
|
34
32
|
{
|
35
33
|
rb_ary_pop(
|
@@ -70,8 +68,7 @@ dispatch_common( VALUE method_sym, int argc, VALUE *argv, VALUE self )
|
|
70
68
|
Qnil) ;
|
71
69
|
}
|
72
70
|
|
73
|
-
static
|
74
|
-
VALUE
|
71
|
+
static VALUE
|
75
72
|
dispatch_normal( int argc, VALUE *argv, VALUE self )
|
76
73
|
{
|
77
74
|
return dispatch_common(
|
@@ -84,8 +81,7 @@ dispatch_normal( int argc, VALUE *argv, VALUE self )
|
|
84
81
|
self) ;
|
85
82
|
}
|
86
83
|
|
87
|
-
static
|
88
|
-
VALUE
|
84
|
+
static VALUE
|
89
85
|
dispatch_basic_object(int argc, VALUE *argv, VALUE self)
|
90
86
|
{
|
91
87
|
return dispatch_common(
|
@@ -95,8 +91,7 @@ dispatch_basic_object(int argc, VALUE *argv, VALUE self)
|
|
95
91
|
self) ;
|
96
92
|
}
|
97
93
|
|
98
|
-
static
|
99
|
-
VALUE
|
94
|
+
static VALUE
|
100
95
|
enable_ext( VALUE self, VALUE klass, VALUE method_sym )
|
101
96
|
{
|
102
97
|
rb_define_method(
|
@@ -108,8 +103,7 @@ enable_ext( VALUE self, VALUE klass, VALUE method_sym )
|
|
108
103
|
return Qnil ;
|
109
104
|
}
|
110
105
|
|
111
|
-
static
|
112
|
-
VALUE
|
106
|
+
static VALUE
|
113
107
|
enable_basic_object_ext( VALUE self, VALUE klass, VALUE method_sym )
|
114
108
|
{
|
115
109
|
basic_object_method_sym = method_sym ;
|
@@ -0,0 +1,111 @@
|
|
1
|
+
package boc ;
|
2
|
+
|
3
|
+
import org.jruby.Ruby ;
|
4
|
+
import org.jruby.RubyModule ;
|
5
|
+
import org.jruby.RubyBinding ;
|
6
|
+
import org.jruby.RubySymbol ;
|
7
|
+
import org.jruby.RubyClass ;
|
8
|
+
import org.jruby.anno.JRubyMethod ;
|
9
|
+
import org.jruby.exceptions.RaiseException ;
|
10
|
+
import org.jruby.runtime.Arity ;
|
11
|
+
import org.jruby.runtime.Block ;
|
12
|
+
import org.jruby.runtime.ThreadContext ;
|
13
|
+
import org.jruby.runtime.callback.Callback ;
|
14
|
+
import org.jruby.runtime.builtin.IRubyObject ;
|
15
|
+
import org.jruby.runtime.load.BasicLibraryService ;
|
16
|
+
|
17
|
+
public class BocService implements BasicLibraryService
|
18
|
+
{
|
19
|
+
static RubyModule s_boc ;
|
20
|
+
static RubyClass s_removed_error ;
|
21
|
+
|
22
|
+
public boolean basicLoad( Ruby ruby )
|
23
|
+
{
|
24
|
+
s_boc = ruby.defineModule("Boc") ;
|
25
|
+
|
26
|
+
s_boc.getSingletonClass().
|
27
|
+
defineAnnotatedMethods(SingletonMethods.class) ;
|
28
|
+
|
29
|
+
s_removed_error = ruby.defineClassUnder(
|
30
|
+
"InformationRemovedError",
|
31
|
+
ruby.getException(),
|
32
|
+
ruby.getException().getAllocator(),
|
33
|
+
s_boc) ;
|
34
|
+
|
35
|
+
return true ;
|
36
|
+
}
|
37
|
+
|
38
|
+
public static class SingletonMethods
|
39
|
+
{
|
40
|
+
@JRubyMethod( name = "enable_ext", alias = {"enable_basic_object_ext"} )
|
41
|
+
public static IRubyObject
|
42
|
+
s_enable_ext( IRubyObject recv, IRubyObject klass, IRubyObject sym )
|
43
|
+
{
|
44
|
+
String method_name = ((RubySymbol)sym).toString() ;
|
45
|
+
|
46
|
+
((RubyModule)klass).defineMethod(
|
47
|
+
method_name,
|
48
|
+
new Dispatcher(method_name + "__impl")) ;
|
49
|
+
|
50
|
+
return recv.getRuntime().getNil() ;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
public static class Dispatcher implements Callback
|
55
|
+
{
|
56
|
+
String m_impl ;
|
57
|
+
|
58
|
+
public Dispatcher( String impl )
|
59
|
+
{
|
60
|
+
m_impl = impl ;
|
61
|
+
}
|
62
|
+
|
63
|
+
public IRubyObject
|
64
|
+
execute( IRubyObject recv, IRubyObject[] args, Block block )
|
65
|
+
{
|
66
|
+
Ruby ruby = recv.getRuntime() ;
|
67
|
+
ThreadContext context = ruby.getCurrentContext() ;
|
68
|
+
IRubyObject stack = s_boc.callMethod(context, "stack") ;
|
69
|
+
|
70
|
+
stack.callMethod(
|
71
|
+
context,
|
72
|
+
"push",
|
73
|
+
RubyBinding.newBinding(ruby, context.previousBinding())) ;
|
74
|
+
|
75
|
+
try
|
76
|
+
{
|
77
|
+
return recv.callMethod(context, m_impl, args, block) ;
|
78
|
+
}
|
79
|
+
catch( java.lang.NullPointerException e )
|
80
|
+
{
|
81
|
+
throw new RaiseException(
|
82
|
+
ruby, s_removed_error, s_error_msg, true) ;
|
83
|
+
}
|
84
|
+
finally
|
85
|
+
{
|
86
|
+
stack.callMethod(context, "pop") ;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
public Arity getArity()
|
91
|
+
{
|
92
|
+
return Arity.OPTIONAL ;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
static String s_error_msg = "\n" +
|
97
|
+
"\n" +
|
98
|
+
"__________________________________________________________________\n" +
|
99
|
+
"Boc (binding of caller) failed because JRuby removed the necessary\n" +
|
100
|
+
"information. To prevent this from happening, pass the following\n" +
|
101
|
+
"command-line flag to jruby:\n" +
|
102
|
+
"\n" +
|
103
|
+
" -J-Djruby.astInspector.enabled=false\n" +
|
104
|
+
"\n" +
|
105
|
+
"Alternatively, place a do-nothing block somewhere in the caller:\n" +
|
106
|
+
"\n" +
|
107
|
+
" p { }\n" +
|
108
|
+
" # ...your code...\n" +
|
109
|
+
"\n" +
|
110
|
+
"==================================================================\n" ;
|
111
|
+
}
|
data/lib/{boc.so → boc/boc.so}
RENAMED
Binary file
|
data/lib/boc/version.rb
CHANGED
data/lib/boc.rb
CHANGED
@@ -1,30 +1,65 @@
|
|
1
|
-
|
2
|
-
require 'boc.so'
|
1
|
+
require 'boc/boc'
|
3
2
|
|
4
3
|
module Boc
|
4
|
+
#
|
5
|
+
# :singleton-method: enable
|
6
|
+
# :call-seq: enable(klass, method_name)
|
7
|
+
#
|
8
|
+
# Enable <code>Boc.value</code> for the given instance method.
|
9
|
+
#
|
10
|
+
# class A
|
11
|
+
# def f
|
12
|
+
# p eval("x", Boc.value)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def self.g
|
16
|
+
# p eval("x", Boc.value)
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Boc.enable A, :f
|
21
|
+
# Boc.enable A.singleton_class, :g
|
22
|
+
#
|
23
|
+
# x = 33
|
24
|
+
# A.new.f # => 33
|
25
|
+
# A.g # => 33
|
26
|
+
#
|
27
|
+
|
28
|
+
#
|
29
|
+
# <code>Boc.value</code> was called outside of an
|
30
|
+
# <code>enable</code>d method.
|
31
|
+
#
|
32
|
+
class NotEnabledError < StandardError
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# The method given to <code>Boc.enable</code> appears to have been
|
37
|
+
# already enabled.
|
38
|
+
#
|
39
|
+
class AlreadyEnabledError < StandardError
|
40
|
+
end
|
41
|
+
|
5
42
|
class << self
|
6
43
|
#
|
7
|
-
#
|
8
|
-
#
|
44
|
+
# Returns the binding of the caller. May only be used within an
|
45
|
+
# <code>enable</code>d method.
|
9
46
|
#
|
47
|
+
def value
|
48
|
+
if stack.empty?
|
49
|
+
raise NotEnabledError, "Boc.value called outside of an enabled method"
|
50
|
+
end
|
51
|
+
stack.last
|
52
|
+
end
|
53
|
+
|
10
54
|
[:enable, :enable_basic_object].each do |def_method|
|
11
55
|
define_method def_method do |klass, method_name|
|
12
|
-
#
|
13
|
-
# module_eval is saved so that live_ast may replace it.
|
14
|
-
# Boc does not touch module_eval.
|
15
|
-
#
|
16
56
|
MODULE_EVAL.bind(klass).call do
|
17
|
-
visibility =
|
18
|
-
if public_instance_methods.include?(method_name)
|
19
|
-
:public
|
20
|
-
elsif protected_instance_methods.include?(method_name)
|
21
|
-
:protected
|
22
|
-
else
|
23
|
-
:private
|
24
|
-
end
|
57
|
+
visibility = Boc.visibility klass, method_name
|
25
58
|
|
26
59
|
impl = "#{method_name}__impl"
|
27
|
-
|
60
|
+
Boc.check_enabled klass, method_name, impl
|
61
|
+
|
62
|
+
Boc.no_warn { alias_method impl, method_name }
|
28
63
|
Boc.send "#{def_method}_ext", klass, method_name
|
29
64
|
|
30
65
|
send visibility, method_name
|
@@ -33,56 +68,41 @@ module Boc
|
|
33
68
|
end
|
34
69
|
end
|
35
70
|
|
71
|
+
def stack #:nodoc:
|
72
|
+
Thread.current[:_boc_stack] ||= []
|
73
|
+
end
|
74
|
+
|
36
75
|
#
|
37
|
-
#
|
38
|
-
# <code>enable</code>d method.
|
76
|
+
# squelch alias warnings
|
39
77
|
#
|
40
|
-
def
|
41
|
-
|
42
|
-
|
78
|
+
def no_warn #:nodoc:
|
79
|
+
prev = $VERBOSE
|
80
|
+
$VERBOSE = nil
|
81
|
+
begin
|
82
|
+
yield
|
83
|
+
ensure
|
84
|
+
$VERBOSE = prev
|
85
|
+
end
|
43
86
|
end
|
44
|
-
|
45
|
-
def
|
46
|
-
|
87
|
+
|
88
|
+
def visibility(klass, method_name) #:nodoc:
|
89
|
+
if klass.public_instance_methods.include?(method_name)
|
90
|
+
:public
|
91
|
+
elsif klass.protected_instance_methods.include?(method_name)
|
92
|
+
:protected
|
93
|
+
else
|
94
|
+
:private
|
95
|
+
end
|
47
96
|
end
|
48
|
-
end
|
49
97
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
98
|
+
def check_enabled(klass, method_name, impl) #:nodoc:
|
99
|
+
if klass.method_defined?(impl) or klass.private_method_defined?(impl)
|
100
|
+
raise AlreadyEnabledError,
|
101
|
+
"Boc.enable: refusing to overwrite `#{impl}' -- " <<
|
102
|
+
"method `#{method_name}' appears to be already enabled"
|
103
|
+
end
|
56
104
|
end
|
57
105
|
end
|
58
106
|
|
59
|
-
#
|
60
|
-
# module_eval is saved so that live_ast may replace it.
|
61
|
-
# Boc does not touch module_eval.
|
62
|
-
#
|
63
107
|
MODULE_EVAL = Module.instance_method(:module_eval) #:nodoc:
|
64
|
-
|
65
|
-
#
|
66
|
-
# :singleton-method: enable
|
67
|
-
# :call-seq: enable(klass, method_name)
|
68
|
-
#
|
69
|
-
# Enable <code>Boc.value</code> for the given instance method.
|
70
|
-
#
|
71
|
-
# class A
|
72
|
-
# def f
|
73
|
-
# p eval("x", Boc.value)
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# def self.g
|
77
|
-
# p eval("x", Boc.value)
|
78
|
-
# end
|
79
|
-
# end
|
80
|
-
#
|
81
|
-
# Boc.enable A, :f
|
82
|
-
# Boc.enable A.singleton_class, :g
|
83
|
-
#
|
84
|
-
# x = 33
|
85
|
-
# A.new.f # => 33
|
86
|
-
# A.g # => 33
|
87
|
-
#
|
88
108
|
end
|
data/test/basic_test.rb
CHANGED
@@ -93,11 +93,13 @@ class BasicTest < BocTest
|
|
93
93
|
|
94
94
|
module R
|
95
95
|
def self.factorial_of_x
|
96
|
-
x = eval("x", Boc.value) -
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
96
|
+
x = eval("x", Boc.value) -
|
97
|
+
if caller.grep(/#{__method__}/).size == (RUBY_ENGINE == "jruby" ? 0 : 1)
|
98
|
+
0
|
99
|
+
else
|
100
|
+
1
|
101
|
+
end
|
102
|
+
|
101
103
|
if x == 0
|
102
104
|
1
|
103
105
|
else
|
@@ -122,17 +124,17 @@ class BasicTest < BocTest
|
|
122
124
|
def test_basic_object
|
123
125
|
begin
|
124
126
|
BasicObject.module_eval do
|
125
|
-
def
|
127
|
+
def zoofoo
|
126
128
|
::Kernel.eval("z", ::Boc.value)
|
127
129
|
end
|
128
130
|
end
|
129
131
|
|
130
|
-
Boc.enable_basic_object BasicObject, :
|
132
|
+
Boc.enable_basic_object BasicObject, :zoofoo
|
131
133
|
z = 77
|
132
|
-
assert_equal 77, BasicObject.new.
|
134
|
+
assert_equal 77, BasicObject.new.zoofoo
|
133
135
|
ensure
|
134
136
|
BasicObject.module_eval do
|
135
|
-
remove_method :
|
137
|
+
remove_method :zoofoo
|
136
138
|
end
|
137
139
|
end
|
138
140
|
end
|
@@ -156,5 +158,52 @@ class BasicTest < BocTest
|
|
156
158
|
assert D.public_instance_methods.include?(:f)
|
157
159
|
assert D.protected_instance_methods.include?(:g)
|
158
160
|
assert D.private_instance_methods.include?(:h)
|
161
|
+
|
162
|
+
D.new.f
|
163
|
+
D.new.instance_eval { g }
|
164
|
+
D.new.instance_eval { h }
|
165
|
+
end
|
166
|
+
|
167
|
+
class K
|
168
|
+
def f(bind)
|
169
|
+
eval("self", bind)
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.g
|
173
|
+
self.new.f(binding)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_self_control
|
178
|
+
Boc.enable K, :f
|
179
|
+
assert_equal K, K.g
|
180
|
+
end
|
181
|
+
|
182
|
+
class L
|
183
|
+
def f
|
184
|
+
eval("self", Boc.value)
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.g
|
188
|
+
self.new.f
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_self
|
193
|
+
Boc.enable L, :f
|
194
|
+
assert_equal L, L.g
|
195
|
+
end
|
196
|
+
|
197
|
+
class K
|
198
|
+
def k
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_double_enable
|
203
|
+
Boc.enable K, :k
|
204
|
+
error = assert_raises Boc::AlreadyEnabledError do
|
205
|
+
Boc.enable K, :k
|
206
|
+
end
|
207
|
+
assert_match(/method `k'.*already/, error.message)
|
159
208
|
end
|
160
209
|
end
|
data/test/jruby_trial.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'main'
|
2
|
+
|
3
|
+
class JrubyTest < BocTest
|
4
|
+
require 'jruby'
|
5
|
+
prop = "jruby.astInspector.enabled"
|
6
|
+
puts("#{prop}: " + java.lang.System.get_properties[prop].inspect)
|
7
|
+
|
8
|
+
class A
|
9
|
+
def f
|
10
|
+
eval("x", Boc.value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_explosion
|
15
|
+
#p { }
|
16
|
+
Boc.enable A, :f
|
17
|
+
x = 33
|
18
|
+
assert_equal 33, A.new.f
|
19
|
+
end
|
20
|
+
end if RUBY_ENGINE == "jruby"
|
data/test/readme_test.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require_relative 'main'
|
2
2
|
require_relative '../devel/levitate'
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
if RUBY_ENGINE == "ruby"
|
5
|
+
Levitate.doc_to_test(
|
6
|
+
"README.rdoc",
|
7
|
+
"Synopsis",
|
8
|
+
"<code>Binding.of_caller</code>")
|
9
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: boc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.4.2
|
6
6
|
platform: x86-mswin32
|
7
7
|
authors:
|
8
8
|
- James M. Lawrence
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-21 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -41,20 +41,21 @@ files:
|
|
41
41
|
- devel/levitate.rb
|
42
42
|
- ext/boc/boc.c
|
43
43
|
- ext/boc/extconf.rb
|
44
|
+
- jext/boc/BocService.java
|
44
45
|
- lib/boc.rb
|
45
46
|
- lib/boc/binding_of_caller.rb
|
46
47
|
- lib/boc/version.rb
|
47
48
|
- test/basic_test.rb
|
49
|
+
- test/jruby_trial.rb
|
48
50
|
- test/main.rb
|
49
51
|
- test/readme_test.rb
|
50
52
|
- test/shim_test.rb
|
51
|
-
-
|
52
|
-
- lib/boc.so
|
53
|
+
- lib/boc/boc.so
|
53
54
|
has_rdoc: true
|
54
55
|
homepage: http://quix.github.com/boc
|
55
56
|
licenses: []
|
56
57
|
|
57
|
-
post_install_message:
|
58
|
+
post_install_message:
|
58
59
|
rdoc_options:
|
59
60
|
- --main
|
60
61
|
- README.rdoc
|
data/MANIFEST
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
CHANGES.rdoc
|
2
|
-
MANIFEST
|
3
|
-
README.rdoc
|
4
|
-
Rakefile
|
5
|
-
devel/levitate.rb
|
6
|
-
ext/boc/boc.c
|
7
|
-
ext/boc/extconf.rb
|
8
|
-
lib/boc.rb
|
9
|
-
lib/boc/binding_of_caller.rb
|
10
|
-
lib/boc/version.rb
|
11
|
-
test/basic_test.rb
|
12
|
-
test/main.rb
|
13
|
-
test/readme_test.rb
|
14
|
-
test/shim_test.rb
|