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/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
+ }
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile('boc')
@@ -0,0 +1,11 @@
1
+ #
2
+ # compatibility with the old-style Binding.of_caller from 1.8
3
+ #
4
+
5
+ require 'boc'
6
+
7
+ class Binding
8
+ def self.of_caller
9
+ yield Boc.value
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Boc
2
+ VERSION = "0.3.2"
3
+ end
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
@@ -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
+
@@ -0,0 +1,5 @@
1
+ require_relative 'main'
2
+ require_relative '../devel/levitate'
3
+ Levitate.doc_to_test("README.rdoc",
4
+ "Synopsis",
5
+ "<code>Binding.of_caller</code>")
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
+