ruby_interface 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/Gemfile.lock +1 -1
- data/README.md +11 -9
- data/lib/class.rb +11 -0
- data/lib/ruby_interface/version.rb +1 -1
- data/lib/ruby_interface.rb +37 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f41f6e65467a433d39952f9717be64151a61308e
|
4
|
+
data.tar.gz: 5e8512ab821859645be604fed1f62e7752d8e492
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6ac29d101b8044e60b3ed0b90198a364d7b4de02629e7747eb0ec225ac01d3f8cc00ba8c9d0436e1dd89ca424b084d95e4f28e3f4d73f02f0a9fc8f20ec377c
|
7
|
+
data.tar.gz: 445d05ccd6176873ef5a14e7cb6271800d1844e79db1d85da22d10671bf267ad65002ba61191585fabd66c639070235919e39cb964864e9f72221d4feea0227d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 0.3.0
|
2
|
+
- Since https://bugs.ruby-lang.org/issues/12696 was resolved with a doc change:
|
3
|
+
- Enabled checks whenever anonymous classes are defined with a block by
|
4
|
+
- Instrumenting `Class::new` with a `anonymous_class_defined` hook
|
5
|
+
- Made sure `class_eval` could still be used if block was not used
|
6
|
+
- Added better backtrace to see where the failing class is (instead of library code)
|
7
|
+
|
1
8
|
# 0.2.0
|
2
9
|
- Update handling for anonymous classes:
|
3
10
|
- Fix tracepoint never being disabled
|
@@ -5,4 +12,4 @@
|
|
5
12
|
- Make sure that any existing inherited hooks don't get overriden.
|
6
13
|
|
7
14
|
# 0.1.0
|
8
|
-
- Initial release
|
15
|
+
- Initial release
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
When a class is interpreted and does not have the required methods, it throws an error.
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
Since classes in ruby are never closed, the check for required methods will run
|
6
|
+
*only* on the *first* definition of the class body.
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
@@ -35,9 +35,7 @@ end
|
|
35
35
|
class Enterprise < SpaceShip
|
36
36
|
end
|
37
37
|
# => NotImplementedError, 'Expected Enterprise to define #engine, #computer'
|
38
|
-
```
|
39
|
-
|
40
|
-
If a class is redefined, the presence of required methods will not be checked.
|
38
|
+
```
|
41
39
|
|
42
40
|
### Anonymous classes
|
43
41
|
|
@@ -48,15 +46,19 @@ class SpaceShip
|
|
48
46
|
defines :engine, :computer
|
49
47
|
end
|
50
48
|
|
49
|
+
# If the block is passed in to Class::new
|
50
|
+
space_ship = Class.new(SpaceShip) { }
|
51
|
+
# => NotImplementedError, 'Expected Enterprise to define #engine, #computer'
|
52
|
+
|
53
|
+
# If the block is not passed in to Class::new
|
51
54
|
space_ship = Class.new(SpaceShip)
|
52
55
|
space_ship.class_eval { }
|
56
|
+
|
53
57
|
# => NotImplementedError, 'Expected Enterprise to define #engine, #computer'
|
58
|
+
# NOTE: After the first `class_eval`, the rest of the calls to it will not check whether methods are defined.
|
59
|
+
# NOTE: `class_exec` may also be used instead of `class_eval`
|
54
60
|
```
|
55
61
|
|
56
|
-
After the first `class_eval`, the rest of the calls to it will not check whether methods are defined.
|
57
|
-
Unfortunately, right now, `class_eval` has to be called to check whether the methods are defined,
|
58
|
-
pending resolution of https://bugs.ruby-lang.org/issues/12696.
|
59
|
-
|
60
62
|
## Development
|
61
63
|
|
62
64
|
After checking out the repo, run `bin/setup` to install dependencies.
|
data/lib/class.rb
ADDED
data/lib/ruby_interface.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ruby_interface/version'
|
2
|
+
require 'class'
|
2
3
|
require 'awesome_print'
|
3
4
|
|
4
5
|
module RubyInterface
|
@@ -26,15 +27,41 @@ module RubyInterface
|
|
26
27
|
|
27
28
|
return if missing_methods.empty?
|
28
29
|
|
30
|
+
raise_class_definition_error child, missing_methods
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def raise_class_definition_error(child, missing_methods)
|
29
36
|
message = "Expected #{child.name || 'anonymous class'} to define "
|
30
37
|
message << missing_methods.map { |method| "##{method}" }.join(', ')
|
38
|
+
|
31
39
|
raise NotImplementedError, message
|
40
|
+
rescue NotImplementedError => exception
|
41
|
+
directory = File.dirname(__FILE__)
|
42
|
+
better_backtrace = exception.backtrace.drop_while do |element|
|
43
|
+
element.include? directory
|
44
|
+
end
|
45
|
+
exception.set_backtrace better_backtrace
|
46
|
+
raise exception
|
32
47
|
end
|
33
48
|
|
34
|
-
private
|
35
|
-
|
36
49
|
def anonymous_class_definition(child)
|
50
|
+
define_class_hook child
|
51
|
+
redefine_eval_and_exec child
|
52
|
+
end
|
53
|
+
|
54
|
+
def define_class_hook(child)
|
37
55
|
klass = self
|
56
|
+
child.define_singleton_method :anonymous_class_defined do
|
57
|
+
klass.track_required_methods(child)
|
58
|
+
revert_eval_and_exec
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def redefine_eval_and_exec(child)
|
63
|
+
klass = self
|
64
|
+
|
38
65
|
[:class_exec, :class_eval].each do |method|
|
39
66
|
old_method = "_old_#{method}".to_sym
|
40
67
|
child.singleton_class.send(:alias_method, old_method, method)
|
@@ -42,11 +69,18 @@ module RubyInterface
|
|
42
69
|
child.define_singleton_method method do |*args, &block|
|
43
70
|
send old_method, *args, &block
|
44
71
|
klass.track_required_methods(child)
|
45
|
-
|
72
|
+
revert_eval_and_exec
|
46
73
|
end
|
47
74
|
end
|
48
75
|
end
|
49
76
|
|
77
|
+
def revert_eval_and_exec
|
78
|
+
[:class_exec, :class_eval].each do |method|
|
79
|
+
old_method = "_old_#{method}".to_sym
|
80
|
+
singleton_class.send(:alias_method, method, old_method)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
50
84
|
def named_class_definition(child)
|
51
85
|
trace = TracePoint.new(:end) do |point|
|
52
86
|
next unless point.self == child
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_interface
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kirill Klimuk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- Rakefile
|
87
87
|
- bin/console
|
88
88
|
- bin/setup
|
89
|
+
- lib/class.rb
|
89
90
|
- lib/ruby_interface.rb
|
90
91
|
- lib/ruby_interface/version.rb
|
91
92
|
- ruby_interface.gemspec
|