ruby_interface 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|