ruby_interface 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba848be8e36fb2a53a4c0a80f692d15cacb22771
4
- data.tar.gz: 7ab704e3372b468c2303149c02ae46acd66a8809
3
+ metadata.gz: d9b8ffa291917e451bb903aef5276f566b7294f1
4
+ data.tar.gz: 87b777bdd6a33288a62a1e15675ea6e816fdf3f9
5
5
  SHA512:
6
- metadata.gz: 815bf8051224c890dbf1b54a24746456eff1289a2b5107b44dadd8cfe33193740ab979b31497686f7f4416a34e6318ac4b486ed4dcc7d81de920cd88b57302c5
7
- data.tar.gz: 10392958eaa591e652479e6684672b724f9e25328eefd14553e96afc4f178216c1aaa90b41933344e7d93353b16fb8c18bbc30a149320bdcbfdb48e786dc4da4
6
+ metadata.gz: 1ea17d4036a0ebd057ec6d9d632f8dbcc8f568e94db4ce5cbb152e0bb36ea4626a3cb2e597c260ee48489f99ed34370046b686a5bee762afac3611ff625cfdc7
7
+ data.tar.gz: 1ffdcb7225e371e5cf7300ef7b1e7e88ba50929962a8cfdca61ecde77f6b0be13489cca1dee61c3c7885556443d6ad9550be33ae454fc7fe032c762ab4d52f5e
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # 0.2.0
2
+ - Update handling for anonymous classes:
3
+ - Fix tracepoint never being disabled
4
+ - Create an implementation that uses `class_eval`
5
+ - Make sure that any existing inherited hooks don't get overriden.
6
+
7
+ # 0.1.0
8
+ - Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_interface (0.1.0)
4
+ ruby_interface (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  When a class is interpreted and does not have the required methods, it throws an error.
4
4
 
5
5
  Caveats:
6
- - creating anonymous classes will not work with this gem as they use an alternate mechanism.
6
+ - Creating anonymous classes requires the user to use `class_eval` to define methods.
7
7
 
8
8
  ## Installation
9
9
 
@@ -23,6 +23,8 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
+ ### Named Classes
27
+
26
28
  ```ruby
27
29
  class SpaceShip
28
30
  include RubyInterface
@@ -35,15 +37,31 @@ end
35
37
  # => NotImplementedError, 'Expected Enterprise to define #engine, #computer'
36
38
  ```
37
39
 
40
+ If a class is redefined, the presence of required methods will not be checked.
41
+
42
+ ### Anonymous classes
43
+
44
+ ```ruby
45
+ class SpaceShip
46
+ include RubyInterface
47
+
48
+ defines :engine, :computer
49
+ end
50
+
51
+ space_ship = Class.new(SpaceShip)
52
+ space_ship.class_eval { }
53
+ # => NotImplementedError, 'Expected Enterprise to define #engine, #computer'
54
+ ```
55
+
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
+
38
60
  ## Development
39
61
 
40
62
  After checking out the repo, run `bin/setup` to install dependencies.
41
63
  You can also run `bin/console` for an interactive prompt that will allow you to experiment.
42
64
 
43
- To install this gem onto your local machine, run `bundle exec rake install`.
44
- To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
45
- which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
46
-
47
65
  ## Contributing
48
66
 
49
67
  Bug reports and pull requests are welcome on GitHub at https://github.com/kklimuk/ruby_interface.
@@ -1,3 +1,3 @@
1
1
  module RubyInterface
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -4,6 +4,15 @@ require 'awesome_print'
4
4
  module RubyInterface
5
5
  def self.included(klass)
6
6
  klass.extend ClassMethods
7
+
8
+ klass.class_eval do
9
+ singleton_class.send(:alias_method, :_old_inherited, :inherited) if respond_to?(:inherited)
10
+ end
11
+
12
+ def klass.inherited(child)
13
+ child.name.nil? ? anonymous_class_definition(child) : named_class_definition(child)
14
+ _old_inherited(child) if respond_to?(:_old_inherited)
15
+ end
7
16
  end
8
17
 
9
18
  module ClassMethods
@@ -12,17 +21,37 @@ module RubyInterface
12
21
  @methods_to_define += args
13
22
  end
14
23
 
15
- def inherited(klass)
16
- trace = TracePoint.new(:end) do |point|
17
- next unless point.self == klass
18
- missing_methods = @methods_to_define - klass.instance_methods(false)
19
- trace.disable
24
+ def track_required_methods(child)
25
+ missing_methods = @methods_to_define - child.instance_methods(false)
20
26
 
21
- next if missing_methods.empty?
27
+ return if missing_methods.empty?
28
+
29
+ message = "Expected #{child.name || 'anonymous class'} to define "
30
+ message << missing_methods.map { |method| "##{method}" }.join(', ')
31
+ raise NotImplementedError, message
32
+ end
22
33
 
23
- message = "Expected #{klass.name} to define "
24
- message << missing_methods.map { |method| "##{method}" }.join(', ')
25
- raise NotImplementedError, message
34
+ private
35
+
36
+ def anonymous_class_definition(child)
37
+ klass = self
38
+ [:class_exec, :class_eval].each do |method|
39
+ old_method = "_old_#{method}".to_sym
40
+ child.singleton_class.send(:alias_method, old_method, method)
41
+
42
+ child.define_singleton_method method do |*args, &block|
43
+ send old_method, *args, &block
44
+ klass.track_required_methods(child)
45
+ child.singleton_class.send(:alias_method, method, old_method)
46
+ end
47
+ end
48
+ end
49
+
50
+ def named_class_definition(child)
51
+ trace = TracePoint.new(:end) do |point|
52
+ next unless point.self == child
53
+ trace.disable
54
+ track_required_methods child
26
55
  end
27
56
  trace.enable
28
57
  end
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.1.0
4
+ version: 0.2.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-21 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -78,6 +78,7 @@ files:
78
78
  - ".ruby-gemset"
79
79
  - ".ruby-version"
80
80
  - ".travis.yml"
81
+ - CHANGELOG.md
81
82
  - Gemfile
82
83
  - Gemfile.lock
83
84
  - LICENSE.txt