local_eval 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -38,32 +38,48 @@ block:
38
38
  example: capture
39
39
  --------------------
40
40
 
41
- `gen_extend` lets us mix objects into objects:
42
-
43
- o = Object.new
44
- class << o
45
- def bye
46
- :bye
41
+ Since `local_eval` does not alter the `self` inside a block,
42
+ all methods with an implied receiver will be invoked with respect to
43
+ this self. This means that all mutator methods defined on the receiver
44
+ will modify state on the block's self rather than on the receiver's
45
+ self. This is unlikely to be the desired behaviour; and so
46
+ using the `capture` method we can redirect the method lookup to
47
+ the actual receiver. All code captured by the `capture` block
48
+ will be `instance_eval`'d against the actual receiver of the method.
49
+
50
+ class C
51
+ class << self
52
+ attr_reader :hello
53
+ def self.capture_test
54
+
55
+ # this code will be run against C
56
+ capture { @hello = :captured }
57
+
58
+ # this code will be run against the block context
59
+ @goodbye = :goobye
60
+ end
47
61
  end
48
62
  end
49
-
50
- n = Object.new
51
- n.gen_extend o
52
- n.bye #=> :bye
53
63
 
64
+ C.local_eval { capture_test }
65
+
66
+ C.hello #=> :captured
67
+ @goodbye #=> :goodbye
68
+
54
69
  How it works
55
70
  --------------
56
71
 
57
- Object2module simply removes the check for `T_MODULE` from `rb_include_module()`
72
+ Makes use of companion libraries: Remix and Object2module
58
73
 
59
74
  Companion Libraries
60
75
  --------------------
61
76
 
62
- Remix is one of a series of experimental libraries that mess with
77
+ LocalEval is one of a series of experimental libraries that mess with
63
78
  the internals of Ruby to bring new and interesting functionality to
64
79
  the language, see also:
65
80
 
66
81
  * [Remix](http://github.com/banister/remix) - Makes ancestor chains read/write
82
+ * [Object2module](http://github.com/banister/object2module) - Enables you to include/extend Object/Classes.
67
83
  * [Include Complete](http://github.com/banister/include_complete) - Brings in
68
84
  module singleton classes during an include. No more ugly ClassMethods and included() hook hacks.
69
85
  * [Prepend](http://github.com/banister/prepend) - Prepends modules in front of a class; so method lookup starts with the module
data/Rakefile CHANGED
@@ -18,8 +18,8 @@ def apply_spec_defaults(s)
18
18
  s.email = 'jrmair@gmail.com'
19
19
  s.description = s.summary
20
20
  s.require_path = 'lib'
21
- s.add_dependency("remix",">=0.4.8")
22
- s.add_dependency("object2module",">=0.4.3")
21
+ s.add_dependency("remix",">=0.4.9")
22
+ s.add_dependency("object2module",">=0.4.5")
23
23
  s.homepage = "http://banisterfiend.wordpress.com"
24
24
  s.has_rdoc = 'yard'
25
25
  s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
@@ -1,3 +1,3 @@
1
1
  module LocalEval
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.2"
3
3
  end
data/lib/local_eval.rb CHANGED
@@ -5,25 +5,25 @@ require 'remix'
5
5
  require 'object2module'
6
6
 
7
7
  module LocalEval
8
-
9
- # Thread-local name for the hidden self used by `capture`
10
- # @return [String] The name of the hidden self used by `capture`
11
- def self.context_self_name
12
- "@__self__#{Thread.current.object_id}"
13
- end
14
-
15
- module ClassExtensions
16
-
17
- # Find the instance associated with the singleton class
18
- # @return [Object] Instance associated with the singleton class
19
- def __attached__
20
- ObjectSpace.each_object(self).first
21
- end
22
- end
23
8
 
24
9
  module ObjectExtensions
25
10
 
26
- def local_eval(*objs, &block)
11
+ # A more general version of `local_eval`.
12
+ # `local_eval_with` allows you to inject arbitrary functionality
13
+ # from any number of objects into the block.
14
+ # @param [Array] objs The objects to provide functionality to the block
15
+ # @return The value of the block
16
+ # @example
17
+ # class A; def self.a; puts "a"; end; end
18
+ # class B; def self.b; puts "b"; end; end
19
+ # class C; def self.c; puts "c"; end; end
20
+ # local_eval_with(A, B, C) { a; b; c }
21
+ # #=> "a"
22
+ # #=> "b"
23
+ # #=> "c"
24
+ def local_eval_with(*objs, &block)
25
+ raise "need a block" if !block_given?
26
+
27
27
  objs = Array(self) if objs.empty?
28
28
  context = eval('self', block.binding)
29
29
 
@@ -40,11 +40,58 @@ module LocalEval
40
40
  # mix the anonymous module into the block context
41
41
  context.temp_extend functionality, &block
42
42
  end
43
- alias_method :local_eval_with, :local_eval
44
-
45
- # This form is meant to be called without a receiver
46
43
  private :local_eval_with
47
44
 
45
+ # Performs a `local_eval` on the block with respect to the
46
+ # receiver.
47
+ # `local_eval` has some advantages over `instance_eval` in that it
48
+ # does not change `self`. Instead, the functionality in the block
49
+ # context is supplemented by the functionality in the
50
+ # receiver.
51
+ # @return The return value of the block
52
+ # @yield The block to `local_eval`
53
+ # @example local ivars can be looked up
54
+ # class C
55
+ # def hello(name)
56
+ # "hello #{name}!"
57
+ # end
58
+ # end
59
+ #
60
+ # o = C.new
61
+ #
62
+ # @name = "John"
63
+ # o.local_eval { hello(@name) } #=> "hello John!"
64
+ def local_eval(&block)
65
+ local_eval_with(&block)
66
+ end
67
+
68
+ # Since `local_eval` does not alter the `self` inside a block,
69
+ # all methods with an implied receiver will be invoked with respect to
70
+ # this self. This means that all mutator methods defined on the receiver
71
+ # will modify state on the block's self rather than on the receiver's
72
+ # self. This is unlikely to be the desired behaviour; and so
73
+ # using the `capture` method we can redirect the method lookup to
74
+ # the actual receiver. All code captured by the `capture` block
75
+ # will be `instance_eval`'d against the actual receiver of the
76
+ # method.
77
+ # @return The return value of the block.
78
+ # @yield The block to be evaluated in the receiver's context.
79
+ # @example
80
+ # class C
81
+ # def self.hello() @hello end
82
+ # def self.capture_test
83
+ #
84
+ # # this code will be run against C
85
+ # capture { @hello = :captured }
86
+ #
87
+ # # this code will be run against the block context
88
+ # @goodbye = :goobye
89
+ # end
90
+ # end
91
+ #
92
+ # C.local_eval { capture_test }
93
+ # C.hello #=> :captured
94
+ # @goodbye #=> :goodbye
48
95
  def capture(&block)
49
96
 
50
97
  # 1. Get name of enclosing method (method that invoked
@@ -59,13 +106,11 @@ module LocalEval
59
106
  attached_object = method_owner.__attached__
60
107
  attached_object.instance_eval &block
61
108
  end
109
+ alias_method :__capture__, :capture
110
+
62
111
  end
63
112
  end
64
113
 
65
- class Class
66
- include LocalEval::ClassExtensions
67
- end
68
-
69
114
  class Object
70
115
  include LocalEval::ObjectExtensions
71
116
  end
@@ -0,0 +1,133 @@
1
+ direc = File.dirname(__FILE__)
2
+
3
+ require "#{direc}/local_eval/version"
4
+ require 'remix'
5
+ require 'object2module'
6
+
7
+ module LocalEval
8
+ module ClassExtensions
9
+
10
+ # Find the instance associated with the singleton class
11
+ # @return [Object] Instance associated with the singleton class
12
+ def __attached__
13
+ ObjectSpace.each_object(self).first
14
+ end
15
+ end
16
+
17
+ module ObjectExtensions
18
+
19
+ # A more general version of `local_eval`.
20
+ # `local_eval_with` allows you to inject arbitrary functionality
21
+ # from any number of objects into the block. Methods that use a
22
+ # `capture` block are invoked on the object that defines the
23
+ # method (and not the local context).
24
+ # @param [Array] objs The objects to provide functionality to the block
25
+ # @return The value of the block
26
+ # @example
27
+ # class A; def self.a; puts "a"; end; end
28
+ # class B; def self.b; puts "b"; end; end
29
+ # class C; def self.c; puts "c"; end; end
30
+ # local_eval_with(A, B, C) { a; b; c }
31
+ # #=> "a"
32
+ # #=> "b"
33
+ # #=> "c"
34
+ def local_eval_with(*objs, &block)
35
+ raise "need a block" if !block_given?
36
+
37
+ objs = Array(self) if objs.empty?
38
+ context = eval('self', block.binding)
39
+
40
+ # if the receiver is the same as the block context then don't
41
+ # mix in anything, as functionality is already present.
42
+ if objs.include?(context)
43
+ objs.delete(context)
44
+ return yield if objs.empty?
45
+ end
46
+
47
+ # add functionality to anonymous module to ease mixing and unmixing
48
+ functionality = Module.new.gen_include *objs.map { |o| o.is_a?(Module) ? o.singleton_class : o }
49
+
50
+ # mix the anonymous module into the block context
51
+ context.temp_extend functionality, &block
52
+ end
53
+ private :local_eval_with
54
+
55
+ # Performs a `local_eval` on the block with respect to the
56
+ # receiver.
57
+ # `local_eval` has some advantages over `instance_eval` in that it
58
+ # does not change `self`. Instead, the functionality in the local
59
+ # context is supplemented by the functionality in the
60
+ # receiver. Further, if receiver methods utilize a `capture` block
61
+ # then the receiver of that `local_eval` becomes the receiver of that
62
+ # method call (rather than the local context).
63
+ # @return The return value of the block
64
+ # @yield The block to `local_eval`
65
+ # @example local ivars can be looked up
66
+ # class C
67
+ # def hello(name)
68
+ # "hello #{name}!"
69
+ # end
70
+ # end
71
+ #
72
+ # o = C.new
73
+ #
74
+ # @name = "John"
75
+ # o.local_eval { hello(@name) } #=> "hello John!"
76
+ def local_eval(&block)
77
+ local_eval_with(&block)
78
+ end
79
+
80
+ # Since `local_eval` does not alter the `self` inside a block,
81
+ # all methods with an implied receiver will be invoked with respect to
82
+ # this self. This means that all mutator methods defined on the receiver
83
+ # will modify state on the block's self rather than on the receiver's
84
+ # self. This is unlikely to be the desired behaviour; and so
85
+ # using the `capture` method we can redirect the method lookup to
86
+ # the actual receiver. All code captured by the `capture` block
87
+ # will be `instance_eval`'d against the actual receiver of the
88
+ # method.
89
+ # @return The return value of the block.
90
+ # @yield The block to be evaluated in the receiver's context.
91
+ # @example
92
+ # class C
93
+ # attr_reader :hello
94
+ # def self.capture_test
95
+ #
96
+ # # this code will be run against C
97
+ # capture { @hello = :captured }
98
+ #
99
+ # # this code will be run against the block context
100
+ # @goodbye = :goobye
101
+ # end
102
+ # end
103
+ #
104
+ # C.local_eval { capture_test }
105
+ # C.hello #=> :captured
106
+ # @goodbye #=> :goodbye
107
+ def capture(&block)
108
+
109
+ # 1. Get name of enclosing method (method that invoked
110
+ # `capture ` block)
111
+ # 2. Find owner of enclosing method (owner is guaranteed to be
112
+ # a singleton class)
113
+ # 4. Find associated object (attached object) of the singleton class
114
+ # 5. This object will be the receiver of the method call, so
115
+ # instance_eval on it.
116
+ method_name = eval('__method__', block.binding)
117
+
118
+ method_owner = method(method_name).owner
119
+ attached_object = method_owner.__attached__
120
+ attached_object.instance_eval &block
121
+ end
122
+ alias_method :__capture__, :capture
123
+
124
+ end
125
+ end
126
+
127
+ class Class
128
+ include LocalEval::ClassExtensions
129
+ end
130
+
131
+ class Object
132
+ include LocalEval::ObjectExtensions
133
+ end
data/test/helper1.rb CHANGED
@@ -5,7 +5,7 @@ end
5
5
  Reset = proc do
6
6
  O = Object.new
7
7
  O2 = Object.new
8
-
8
+ O3 = Object.new
9
9
  class A
10
10
  def self.a
11
11
  :a
@@ -23,7 +23,7 @@ Reset = proc do
23
23
  :o
24
24
  end
25
25
 
26
- def ivar_set(var, val)
26
+ def ivar_set1(var, val)
27
27
  instance_variable_set(var, val)
28
28
  end
29
29
 
@@ -43,6 +43,16 @@ Reset = proc do
43
43
  end
44
44
  end
45
45
 
46
+ class << O3
47
+ def receiver_ivar_set3
48
+ capture {
49
+ @receiver_ivar3 = :receiver3
50
+ }
51
+ @ivar3 = :ivar3
52
+ end
53
+ end
54
+
55
+
46
56
  class C
47
57
  def self.build_proc
48
58
  proc { love }
@@ -0,0 +1,83 @@
1
+ class Module
2
+ public :remove_const, :include, :remove_method
3
+ end
4
+
5
+ Reset = proc do
6
+ O = Object.new
7
+ O2 = Object.new
8
+ O3 = Object.new
9
+ class A
10
+ def self.a
11
+ :a
12
+ end
13
+ end
14
+
15
+ class B
16
+ def self.b
17
+ :b
18
+ end
19
+ end
20
+
21
+ class << O
22
+ def hello
23
+ :o
24
+ end
25
+
26
+ def ivar_set1(var, val)
27
+ instance_variable_set(var, val)
28
+ end
29
+
30
+ def receiver_ivar_set
31
+ capture {
32
+ @receiver_ivar = :receiver
33
+ }
34
+ end
35
+
36
+ end
37
+
38
+ class << O2
39
+ def receiver_ivar_set2
40
+ capture {
41
+ @receiver_ivar2 = :receiver2
42
+ }
43
+ end
44
+ end
45
+
46
+ class << O3
47
+ def receiver_ivar_set3
48
+ capture {
49
+ @receiver_ivar3 = :receiver3
50
+ }
51
+ @ivar3 = :ivar3
52
+ end
53
+ end
54
+
55
+
56
+ class C
57
+ def self.build_proc
58
+ proc { love }
59
+ end
60
+
61
+ def self.hello
62
+ :c
63
+ end
64
+
65
+ def self.c
66
+ :c
67
+ end
68
+
69
+ def self.ivar(v)
70
+ v
71
+ end
72
+ end
73
+
74
+ module M
75
+ def self.hello
76
+ :m
77
+ end
78
+
79
+ def m
80
+ :m
81
+ end
82
+ end
83
+ end
data/test/test.rb CHANGED
@@ -14,7 +14,7 @@ describe LocalEval do
14
14
  end
15
15
 
16
16
  after do
17
- [:A, :B, :C, :M, :O, :O2].each do |c|
17
+ [:A, :B, :C, :M, :O, :O2, :O3].each do |c|
18
18
  Object.remove_const(c)
19
19
  end
20
20
  end
@@ -77,9 +77,9 @@ describe LocalEval do
77
77
 
78
78
  it 'should make the method set a local ivar' do
79
79
  instance_variable_defined?(:@v).should == false
80
- lambda { ivar_set }.should.raise NameError
81
- O.local_eval { ivar_set(:@v, 10) }
82
- lambda { ivar_set }.should.raise NameError
80
+ lambda { ivar_set1 }.should.raise NameError
81
+ O.local_eval { ivar_set1(:@v, 10) }
82
+ lambda { ivar_set1 }.should.raise NameError
83
83
  @v.should == 10
84
84
  end
85
85
 
@@ -130,6 +130,24 @@ describe LocalEval do
130
130
  O2.instance_variable_get(:@receiver_ivar2).should == :receiver2
131
131
  O.instance_variable_get(:@receiver_ivar).should == :receiver
132
132
  end
133
+
134
+ it 'should separate the two different selves in a method when using capture' do
135
+ O3.instance_variable_defined?(:@receiver_ivar).should == false
136
+ instance_variable_defined?(:@ivar3).should == false
137
+ O3.local_eval { receiver_ivar_set3 }
138
+ O3.instance_variable_get(:@receiver_ivar3).should == :receiver3
139
+ instance_variable_get(:@ivar3).should == :ivar3
140
+ remove_instance_variable(:@ivar3)
141
+ end
142
+
143
+ it 'should work in an instance_eval' do
144
+ o = Object.new
145
+ o.instance_eval do
146
+ O3.local_eval { receiver_ivar_set3 }
147
+ O3.instance_variable_get(:@receiver_ivar3).should == :receiver3
148
+ instance_variable_get(:@ivar3).should == :ivar3
149
+ end
150
+ end
133
151
  end
134
152
 
135
153
  describe 'mixing in a module' do
@@ -0,0 +1,152 @@
1
+ direc = File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require "#{direc}/../lib/local_eval"
5
+ require "#{direc}/helper1"
6
+
7
+ puts "Testing LocalEval version #{LocalEval::VERSION}..."
8
+ puts "With Remix version #{Remix::VERSION} and Object2module version #{Object2module::VERSION}"
9
+ puts "Ruby version #{RUBY_VERSION}"
10
+
11
+ describe LocalEval do
12
+ before do
13
+ Reset.call
14
+ end
15
+
16
+ after do
17
+ [:A, :B, :C, :M, :O, :O2, :O3].each do |c|
18
+ Object.remove_const(c)
19
+ end
20
+ end
21
+
22
+ describe 'mixing in an object' do
23
+ it 'should mix in and mixout the object and make functionality available to block' do
24
+ lambda { hello }.should.raise NameError
25
+ O.local_eval { hello }.should == :o
26
+ lambda { hello }.should.raise NameError
27
+ end
28
+
29
+ it 'should not error when receiver is the same as block context' do
30
+ lambda { local_eval { :hello } }.should.not.raise ArgumentError
31
+ local_eval { :hello }.should == :hello
32
+ end
33
+
34
+ it 'should mix implicit self into context of block' do
35
+ def self.love; :love; end
36
+ local_eval(&C.build_proc).should == :love
37
+ self.singleton_class.remove_method(:love)
38
+ end
39
+ end
40
+
41
+ describe 'local_eval_with' do
42
+ it 'should mix in multiple objects and make functionality available to the block' do
43
+ lambda { a }.should.raise NameError
44
+ lambda { b }.should.raise NameError
45
+ lambda { local_eval_with(A, B) { a; b; } }.should.not.raise NameError
46
+ lambda { a }.should.raise NameError
47
+ lambda { b }.should.raise NameError
48
+ end
49
+
50
+ it 'should not error when mixing in multiple objects that include the context of the block' do
51
+ lambda { local_eval_with(self, A, B) { a; b } }.should.not.raise NameError
52
+ end
53
+ end
54
+
55
+ describe 'mixing in a class' do
56
+ it 'should mix in and mixout the class' do
57
+ lambda { hello }.should.raise NameError
58
+ C.local_eval { c }.should == :c
59
+ lambda { hello }.should.raise NameError
60
+ end
61
+
62
+ it 'should mixin and mixout a class/module chain' do
63
+ C.extend M
64
+ lambda { c }.should.raise NameError
65
+ lambda { m }.should.raise NameError
66
+ C.local_eval { c.should == :c; m.should == :m }
67
+ lambda { c }.should.raise NameError
68
+ lambda { m }.should.raise NameError
69
+ end
70
+ end
71
+
72
+ describe 'ivars in the block' do
73
+ it 'should make ivars accessible to, and modifiable by, block' do
74
+ O.local_eval { @x = 5 }
75
+ @x.should == 5
76
+ end
77
+
78
+ it 'should make the method set a local ivar' do
79
+ instance_variable_defined?(:@v).should == false
80
+ lambda { ivar_set }.should.raise NameError
81
+ O.local_eval { ivar_set(:@v, 10) }
82
+ lambda { ivar_set }.should.raise NameError
83
+ @v.should == 10
84
+ end
85
+
86
+ it 'should make local ivars accessible to mixed in methods' do
87
+ @y = 10
88
+ lambda { ivar(@y) }.should.raise NameError
89
+ C.local_eval { ivar(@y) }.should == 10
90
+ @y.should == 10
91
+ lambda { ivar(@y) }.should.raise NameError
92
+ end
93
+ end
94
+
95
+ describe 'capture block' do
96
+ it 'should make capture evaluate the method in receiver context' do
97
+ instance_variable_defined?(:@receiver_ivar).should == false
98
+ lambda { receiver_ivar_set }.should.raise NameError
99
+ O.local_eval { receiver_ivar_set }
100
+ instance_variable_defined?(:@receiver_ivar).should == false
101
+ O.instance_variable_get(:@receiver_ivar).should == :receiver
102
+ end
103
+
104
+ it 'should redirect methods to appropriate receivers' do
105
+ O.instance_variable_defined?(:@receiver_ivar2).should == false
106
+ O2.instance_variable_defined?(:@receiver_ivar2).should == false
107
+ instance_variable_defined?(:@receiver_ivar).should == false
108
+ instance_variable_defined?(:@receiver_ivar2).should == false
109
+ lambda { receiver_ivar_set; receiver_ivar_set2 }.should.raise NameError
110
+ local_eval_with(O, O2) { receiver_ivar_set; receiver_ivar_set2 }
111
+ instance_variable_defined?(:@receiver_ivar).should == false
112
+ instance_variable_defined?(:@receiver_ivar2).should == false
113
+ O.instance_variable_get(:@receiver_ivar).should == :receiver
114
+ O2.instance_variable_get(:@receiver_ivar2).should == :receiver2
115
+ end
116
+
117
+ it 'should not prevent method lookup on capture-methods on objects that are not involved in the local_eval' do
118
+ O2.instance_variable_defined?(:@receiver_ivar2).should == false
119
+ O.local_eval { O2.receiver_ivar_set2.should == :receiver2 }
120
+ O2.instance_variable_get(:@receiver_ivar2).should == :receiver2
121
+ end
122
+
123
+ it 'should work properly with nested local_evals' do
124
+ O.local_eval do
125
+ O2.local_eval { receiver_ivar_set2 }
126
+ lambda { receiver_ivar_set2 }.should.raise NameError
127
+ receiver_ivar_set
128
+ end
129
+
130
+ O2.instance_variable_get(:@receiver_ivar2).should == :receiver2
131
+ O.instance_variable_get(:@receiver_ivar).should == :receiver
132
+ end
133
+
134
+ it 'should separate the two different selves in a method when using capture' do
135
+ O3.instance_variable_defined?(:@receiver_ivar).should == false
136
+ instance_variable_defined?(:@ivar3).should == false
137
+ O3.local_eval { receiver_ivar_set3 }
138
+ O3.instance_variable_get(:@receiver_ivar3).should == :receiver3
139
+ instance_variable_get(:@ivar3).should == :ivar3
140
+ remove_instance_variable(:@ivar3)
141
+ end
142
+
143
+ end
144
+
145
+ describe 'mixing in a module' do
146
+ it 'should mix in and mixout the module' do
147
+ lambda { hello }.should.raise NameError
148
+ M.local_eval { hello }.should == :m
149
+ lambda { hello }.should.raise NameError
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,26 @@
1
+ direc = File.dirname(__FILE__)
2
+ require "rubygems"
3
+ require "#{direc}/../lib/local_eval"
4
+ require 'mult'
5
+
6
+ C = Object.new
7
+ class << C
8
+ def hello
9
+ capture { @hello = :captures
10
+ }
11
+ @goodbye = :captured
12
+ end
13
+ end
14
+
15
+ # C.local_eval { hello }
16
+ # C.hello
17
+ # puts @goodbye
18
+
19
+ o = Object.new
20
+ o.instance_eval {
21
+ C.local_eval { hello }
22
+ puts @goodbye
23
+ puts C.instance_variable_get(:@hello)
24
+ # puts @hello
25
+ puts self.object_id
26
+ }
@@ -0,0 +1,8 @@
1
+ require 'remix'
2
+ require 'mult'
3
+ require 'object2module'
4
+
5
+ o = Object.new
6
+ o.gen_extend Module.new.singleton_class
7
+ puts o.singleton_class.ancestors
8
+ o.singleton_class.ready_remix
@@ -0,0 +1,25 @@
1
+ direc = File.dirname(__FILE__)
2
+ require "rubygems"
3
+ require "#{direc}/../lib/local_eval"
4
+ require 'mult'
5
+
6
+ class C
7
+ attr_reader :hello
8
+ def self.hello
9
+ capture { @hello = :captures }
10
+ @goodbye = :captured
11
+ end
12
+ end
13
+
14
+ C.local_eval { hello }
15
+ @goodbye
16
+ C.hello
17
+ m = Module.new
18
+ m.gen_include Module.new.singleton_class
19
+
20
+ o = Object.new
21
+ o.instance_eval {
22
+ # o.actual_class = C
23
+ self.temp_extend(m) { puts self
24
+ # C.local_eval { puts self }
25
+ }
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 0
9
- version: 0.2.0
8
+ - 2
9
+ version: 0.2.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - John Mair (banisterfiend)
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-15 00:00:00 +13:00
17
+ date: 2010-11-16 00:00:00 +13:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -28,8 +28,8 @@ dependencies:
28
28
  segments:
29
29
  - 0
30
30
  - 4
31
- - 8
32
- version: 0.4.8
31
+ - 9
32
+ version: 0.4.9
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  - !ruby/object:Gem::Dependency
@@ -43,8 +43,8 @@ dependencies:
43
43
  segments:
44
44
  - 0
45
45
  - 4
46
- - 3
47
- version: 0.4.3
46
+ - 5
47
+ version: 0.4.5
48
48
  type: :runtime
49
49
  version_requirements: *id002
50
50
  description: instance_eval without changing self
@@ -59,12 +59,18 @@ files:
59
59
  - lib/local_eval/version.rb
60
60
  - lib/local_eval/version_flymake.rb
61
61
  - lib/local_eval.rb
62
+ - lib/local_eval_flymake.rb
62
63
  - test/helper1.rb
64
+ - test/helper1_flymake.rb
63
65
  - test/test.rb
66
+ - test/test_flymake.rb
67
+ - test/test_segfault.rb
68
+ - test/test_segfault2.rb
69
+ - test/test_segfault_flymake.rb
64
70
  - CHANGELOG
65
71
  - README.markdown
66
72
  - Rakefile
67
- has_rdoc: yard
73
+ has_rdoc: true
68
74
  homepage: http://banisterfiend.wordpress.com
69
75
  licenses: []
70
76