boc 0.3.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 +16 -0
- data/MANIFEST +14 -0
- data/README.rdoc +119 -0
- data/Rakefile +13 -0
- data/devel/levitate.rb +958 -0
- data/ext/boc/boc.c +142 -0
- data/ext/boc/extconf.rb +2 -0
- data/lib/boc/binding_of_caller.rb +11 -0
- data/lib/boc/version.rb +3 -0
- data/lib/boc.rb +88 -0
- data/lib/boc.so +0 -0
- data/test/basic_test.rb +160 -0
- data/test/main.rb +56 -0
- data/test/readme_test.rb +5 -0
- data/test/shim_test.rb +26 -0
- metadata +87 -0
data/ext/boc/boc.c
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
VALUE
|
4
|
+
rb_funcall_passing_block(VALUE recv, ID mid, int argc, const VALUE *argv) ;
|
5
|
+
|
6
|
+
static VALUE cBoc ;
|
7
|
+
|
8
|
+
static VALUE basic_object_method_sym ;
|
9
|
+
|
10
|
+
struct dispatch_args
|
11
|
+
{
|
12
|
+
int argc ;
|
13
|
+
VALUE* argv ;
|
14
|
+
VALUE self ;
|
15
|
+
ID method_id ;
|
16
|
+
} ;
|
17
|
+
|
18
|
+
static
|
19
|
+
VALUE
|
20
|
+
begin_section( VALUE data )
|
21
|
+
{
|
22
|
+
struct dispatch_args* dargs = (struct dispatch_args*)data ;
|
23
|
+
|
24
|
+
return rb_funcall_passing_block(
|
25
|
+
dargs->self,
|
26
|
+
dargs->method_id,
|
27
|
+
dargs->argc,
|
28
|
+
dargs->argv) ;
|
29
|
+
}
|
30
|
+
|
31
|
+
static
|
32
|
+
VALUE
|
33
|
+
ensure_section( VALUE unused )
|
34
|
+
{
|
35
|
+
rb_ary_pop(
|
36
|
+
rb_funcall(
|
37
|
+
cBoc,
|
38
|
+
rb_intern("stack"),
|
39
|
+
0)) ;
|
40
|
+
|
41
|
+
return Qnil ;
|
42
|
+
}
|
43
|
+
|
44
|
+
static VALUE
|
45
|
+
dispatch_common( VALUE method_sym, int argc, VALUE *argv, VALUE self )
|
46
|
+
{
|
47
|
+
struct dispatch_args dargs ;
|
48
|
+
|
49
|
+
dargs.argc = argc ;
|
50
|
+
dargs.argv = argv ;
|
51
|
+
dargs.self = self ;
|
52
|
+
|
53
|
+
dargs.method_id =
|
54
|
+
rb_to_id(
|
55
|
+
rb_str_plus(
|
56
|
+
rb_sym_to_s(method_sym),
|
57
|
+
rb_str_new2("__impl"))) ;
|
58
|
+
|
59
|
+
rb_ary_push(
|
60
|
+
rb_funcall(
|
61
|
+
cBoc,
|
62
|
+
rb_intern("stack"),
|
63
|
+
0),
|
64
|
+
rb_binding_new()) ;
|
65
|
+
|
66
|
+
return rb_ensure(
|
67
|
+
begin_section,
|
68
|
+
(VALUE)&dargs,
|
69
|
+
ensure_section,
|
70
|
+
Qnil) ;
|
71
|
+
}
|
72
|
+
|
73
|
+
static
|
74
|
+
VALUE
|
75
|
+
dispatch_normal( int argc, VALUE *argv, VALUE self )
|
76
|
+
{
|
77
|
+
return dispatch_common(
|
78
|
+
rb_funcall(
|
79
|
+
self,
|
80
|
+
rb_intern("__method__"),
|
81
|
+
0),
|
82
|
+
argc,
|
83
|
+
argv,
|
84
|
+
self) ;
|
85
|
+
}
|
86
|
+
|
87
|
+
static
|
88
|
+
VALUE
|
89
|
+
dispatch_basic_object(int argc, VALUE *argv, VALUE self)
|
90
|
+
{
|
91
|
+
return dispatch_common(
|
92
|
+
basic_object_method_sym,
|
93
|
+
argc,
|
94
|
+
argv,
|
95
|
+
self) ;
|
96
|
+
}
|
97
|
+
|
98
|
+
static
|
99
|
+
VALUE
|
100
|
+
enable_ext( VALUE self, VALUE klass, VALUE method_sym )
|
101
|
+
{
|
102
|
+
rb_define_method(
|
103
|
+
klass,
|
104
|
+
RSTRING_PTR(rb_sym_to_s(method_sym)),
|
105
|
+
dispatch_normal,
|
106
|
+
-1) ;
|
107
|
+
|
108
|
+
return Qnil ;
|
109
|
+
}
|
110
|
+
|
111
|
+
static
|
112
|
+
VALUE
|
113
|
+
enable_basic_object_ext( VALUE self, VALUE klass, VALUE method_sym )
|
114
|
+
{
|
115
|
+
basic_object_method_sym = method_sym ;
|
116
|
+
|
117
|
+
rb_define_method(
|
118
|
+
klass,
|
119
|
+
RSTRING_PTR(rb_sym_to_s(method_sym)),
|
120
|
+
dispatch_basic_object,
|
121
|
+
-1) ;
|
122
|
+
|
123
|
+
return Qnil ;
|
124
|
+
}
|
125
|
+
|
126
|
+
void
|
127
|
+
Init_boc()
|
128
|
+
{
|
129
|
+
cBoc = rb_define_module("Boc") ;
|
130
|
+
|
131
|
+
rb_define_singleton_method(
|
132
|
+
cBoc,
|
133
|
+
"enable_ext",
|
134
|
+
enable_ext,
|
135
|
+
2) ;
|
136
|
+
|
137
|
+
rb_define_singleton_method(
|
138
|
+
cBoc,
|
139
|
+
"enable_basic_object_ext",
|
140
|
+
enable_basic_object_ext,
|
141
|
+
2) ;
|
142
|
+
}
|
data/ext/boc/extconf.rb
ADDED
data/lib/boc/version.rb
ADDED
data/lib/boc.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
|
2
|
+
require 'boc.so'
|
3
|
+
|
4
|
+
module Boc
|
5
|
+
class << self
|
6
|
+
#
|
7
|
+
# enable_basic_object is provided so that live_ast may replace
|
8
|
+
# instance_eval. It may have no other legitimate use.
|
9
|
+
#
|
10
|
+
[:enable, :enable_basic_object].each do |def_method|
|
11
|
+
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
|
+
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
|
25
|
+
|
26
|
+
impl = "#{method_name}__impl"
|
27
|
+
alias_method impl, method_name
|
28
|
+
Boc.send "#{def_method}_ext", klass, method_name
|
29
|
+
|
30
|
+
send visibility, method_name
|
31
|
+
public impl # needs to work with rb_funcall_passing_block
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Returns the binding of the caller. May only be used within an
|
38
|
+
# <code>enable</code>d method.
|
39
|
+
#
|
40
|
+
def value
|
41
|
+
raise NotEnabledError if stack.empty?
|
42
|
+
stack.last
|
43
|
+
end
|
44
|
+
|
45
|
+
def stack #:nodoc:
|
46
|
+
Thread.current[:_boc_stack] ||= []
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Boc.value was called outside of an <code>enable</code>d method.
|
52
|
+
#
|
53
|
+
class NotEnabledError < StandardError
|
54
|
+
def message #:nodoc:
|
55
|
+
"Boc.value was called outside of an enabled method"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# module_eval is saved so that live_ast may replace it.
|
61
|
+
# Boc does not touch module_eval.
|
62
|
+
#
|
63
|
+
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
|
+
end
|
data/lib/boc.so
ADDED
Binary file
|
data/test/basic_test.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require_relative 'main'
|
2
|
+
|
3
|
+
class BasicTest < BocTest
|
4
|
+
MEMO = {}
|
5
|
+
|
6
|
+
def setup
|
7
|
+
MEMO.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
class A
|
11
|
+
def f(y, z)
|
12
|
+
MEMO[:x] = eval("x", Boc.value)
|
13
|
+
MEMO[:y] = y
|
14
|
+
MEMO[:z] = z
|
15
|
+
66
|
16
|
+
end
|
17
|
+
|
18
|
+
def g
|
19
|
+
x = 33
|
20
|
+
f(44, 55)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_basic
|
25
|
+
assert_raises Boc::NotEnabledError do
|
26
|
+
Boc.value
|
27
|
+
end
|
28
|
+
|
29
|
+
Boc.enable A, :f
|
30
|
+
|
31
|
+
assert_nil MEMO[:x]
|
32
|
+
assert_nil MEMO[:y]
|
33
|
+
assert_nil MEMO[:z]
|
34
|
+
|
35
|
+
assert_equal 66, A.new.g
|
36
|
+
|
37
|
+
assert_equal 33, MEMO[:x]
|
38
|
+
assert_equal 44, MEMO[:y]
|
39
|
+
assert_equal 55, MEMO[:z]
|
40
|
+
|
41
|
+
assert_raises Boc::NotEnabledError do
|
42
|
+
Boc.value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class B
|
47
|
+
def foo(*args, &block)
|
48
|
+
MEMO[:args] = args
|
49
|
+
MEMO[:block] = block
|
50
|
+
eval("u", Boc.value) ;
|
51
|
+
end
|
52
|
+
|
53
|
+
def bar
|
54
|
+
u = 66
|
55
|
+
foo(77, 88) { |s| s + "zzz" }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_explicit_block
|
60
|
+
Boc.enable B, :foo
|
61
|
+
|
62
|
+
assert_nil MEMO[:args]
|
63
|
+
assert_nil MEMO[:block]
|
64
|
+
|
65
|
+
assert_equal 66, B.new.bar
|
66
|
+
assert_equal [77, 88], MEMO[:args]
|
67
|
+
assert_equal "zoozzz", MEMO[:block].call("zoo")
|
68
|
+
end
|
69
|
+
|
70
|
+
class C
|
71
|
+
def foo(*args)
|
72
|
+
MEMO[:args] = args
|
73
|
+
MEMO[:yield_result] = yield "moo"
|
74
|
+
eval("u", Boc.value) ;
|
75
|
+
end
|
76
|
+
|
77
|
+
def bar
|
78
|
+
u = 66
|
79
|
+
foo(77, 88) { |s| s + "zzz" }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_implicit_block
|
84
|
+
Boc.enable C, :foo
|
85
|
+
|
86
|
+
assert_nil MEMO[:args]
|
87
|
+
assert_nil MEMO[:yield_result]
|
88
|
+
|
89
|
+
assert_equal 66, C.new.bar
|
90
|
+
assert_equal [77, 88], MEMO[:args]
|
91
|
+
assert_equal "moozzz", MEMO[:yield_result]
|
92
|
+
end
|
93
|
+
|
94
|
+
module R
|
95
|
+
def self.factorial_of_x
|
96
|
+
x = eval("x", Boc.value) - if caller.grep(/#{__method__}/).size == 1
|
97
|
+
0
|
98
|
+
else
|
99
|
+
1
|
100
|
+
end
|
101
|
+
if x == 0
|
102
|
+
1
|
103
|
+
else
|
104
|
+
x*factorial_of_x
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_recursive
|
110
|
+
Boc.enable R.singleton_class, :factorial_of_x
|
111
|
+
|
112
|
+
x = 5
|
113
|
+
assert_equal 120, R.factorial_of_x
|
114
|
+
x = 4
|
115
|
+
assert_equal 24, R.factorial_of_x
|
116
|
+
x = 1
|
117
|
+
assert_equal 1, R.factorial_of_x
|
118
|
+
x = 0
|
119
|
+
assert_equal 1, R.factorial_of_x
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_basic_object
|
123
|
+
begin
|
124
|
+
BasicObject.module_eval do
|
125
|
+
def edc4739da630326a8
|
126
|
+
::Kernel.eval("z", ::Boc.value)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
Boc.enable_basic_object BasicObject, :edc4739da630326a8
|
131
|
+
z = 77
|
132
|
+
assert_equal 77, BasicObject.new.edc4739da630326a8
|
133
|
+
ensure
|
134
|
+
BasicObject.module_eval do
|
135
|
+
remove_method :edc4739da630326a8
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class D
|
141
|
+
public
|
142
|
+
def f ; end
|
143
|
+
|
144
|
+
protected
|
145
|
+
def g ; end
|
146
|
+
|
147
|
+
private
|
148
|
+
def h ; end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_visibility
|
152
|
+
Boc.enable D, :f
|
153
|
+
Boc.enable D, :g
|
154
|
+
Boc.enable D, :h
|
155
|
+
|
156
|
+
assert D.public_instance_methods.include?(:f)
|
157
|
+
assert D.protected_instance_methods.include?(:g)
|
158
|
+
assert D.private_instance_methods.include?(:h)
|
159
|
+
end
|
160
|
+
end
|
data/test/main.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'minitest/unit'
|
4
|
+
require 'minitest/autorun' unless defined? Rake
|
5
|
+
|
6
|
+
require 'pp'
|
7
|
+
require 'boc'
|
8
|
+
|
9
|
+
class JLMiniTest < MiniTest::Unit::TestCase
|
10
|
+
def self.test_methods
|
11
|
+
default = super
|
12
|
+
onlies = default.select { |m| m =~ %r!__only\Z! }
|
13
|
+
if onlies.empty?
|
14
|
+
default
|
15
|
+
else
|
16
|
+
puts "\nNOTE: running ONLY *__only tests for #{self}"
|
17
|
+
onlies
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def delim(char)
|
22
|
+
"\n" << (char*72) << "\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
def mu_pp(obj)
|
26
|
+
delim("_") <<
|
27
|
+
obj.pretty_inspect.chomp <<
|
28
|
+
delim("=")
|
29
|
+
end
|
30
|
+
|
31
|
+
def unfixable
|
32
|
+
begin
|
33
|
+
yield
|
34
|
+
raise "claimed to be unfixable, but assertion succeeded"
|
35
|
+
rescue MiniTest::Assertion
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_nothing_raised
|
40
|
+
yield
|
41
|
+
assert_nil nil
|
42
|
+
rescue => ex
|
43
|
+
raise MiniTest::Assertion,
|
44
|
+
exception_details(ex, "Expected nothing raised, but got:")
|
45
|
+
end
|
46
|
+
|
47
|
+
%w[
|
48
|
+
empty equal in_delta in_epsilon includes instance_of
|
49
|
+
kind_of match nil operator respond_to same
|
50
|
+
].each { |name|
|
51
|
+
alias_method "assert_not_#{name}", "refute_#{name}"
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
BocTest = JLMiniTest
|
56
|
+
|
data/test/readme_test.rb
ADDED
data/test/shim_test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'main'
|
2
|
+
|
3
|
+
class ShimTest < BocTest
|
4
|
+
def initialize(*args)
|
5
|
+
super
|
6
|
+
require 'boc/binding_of_caller'
|
7
|
+
end
|
8
|
+
|
9
|
+
class A
|
10
|
+
def f
|
11
|
+
Binding.of_caller do |bind|
|
12
|
+
eval("x", bind) + 11
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def g
|
17
|
+
x = 33
|
18
|
+
f
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_old_style
|
23
|
+
Boc.enable A, :f
|
24
|
+
assert_equal 44, A.new.g
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: boc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.3.2
|
6
|
+
platform: x86-mswin32
|
7
|
+
authors:
|
8
|
+
- James M. Lawrence
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-03-16 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rake-compiler
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.7.6
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
description: "Binding of caller: obtain a caller's binding."
|
28
|
+
email:
|
29
|
+
- quixoticsycophant@gmail.com
|
30
|
+
executables: []
|
31
|
+
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files:
|
35
|
+
- README.rdoc
|
36
|
+
- CHANGES.rdoc
|
37
|
+
files:
|
38
|
+
- CHANGES.rdoc
|
39
|
+
- README.rdoc
|
40
|
+
- Rakefile
|
41
|
+
- devel/levitate.rb
|
42
|
+
- ext/boc/boc.c
|
43
|
+
- ext/boc/extconf.rb
|
44
|
+
- lib/boc.rb
|
45
|
+
- lib/boc/binding_of_caller.rb
|
46
|
+
- lib/boc/version.rb
|
47
|
+
- test/basic_test.rb
|
48
|
+
- test/main.rb
|
49
|
+
- test/readme_test.rb
|
50
|
+
- test/shim_test.rb
|
51
|
+
- MANIFEST
|
52
|
+
- lib/boc.so
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://quix.github.com/boc
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message: U got dat binary versionation of this gemination!
|
58
|
+
rdoc_options:
|
59
|
+
- --main
|
60
|
+
- README.rdoc
|
61
|
+
- --title
|
62
|
+
- "boc: Binding of caller"
|
63
|
+
- --exclude
|
64
|
+
- lib/boc/binding_of_caller.rb
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.9.2
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.6.2
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: Binding of caller.
|
86
|
+
test_files: []
|
87
|
+
|