interface_semantics 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/interface_semantics.rb +69 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 95b3a830815d0b322775037d097efcfc6b88a0e78c0f66d4ae223ed140c30471
4
+ data.tar.gz: 8e4c3a7225ac3b214b5393717b1d3a3620817dd5a83aace7f8d08f4208c7839d
5
+ SHA512:
6
+ metadata.gz: fd70fb133aad72d43898e3c7dc518d12ef0f7a98bdf4231f4188a17a7463741be21c46a69b186a64dfe2152f540c473459cee3cd9cd6e390715b08db311c5998
7
+ data.tar.gz: cdb37d5f48672cef4eb58372ba66279a1e7f9eb06009aaa497ddfa670c972e0793731167f878112814337ff07767853502b615b344e8fbece136892964321667
@@ -0,0 +1,69 @@
1
+ Class.class_eval do
2
+ def implements(mod)
3
+ prepend mod
4
+ end
5
+ end
6
+
7
+ Attribute = Struct.new(:name, :argument_types, :return_type)
8
+
9
+ def interface(&block)
10
+ Interface.for_messages(&block)
11
+ end
12
+
13
+ module Interface
14
+ DoesNotImplementError = Class.new(StandardError)
15
+ IncorrectReturnType = Class.new(StandardError)
16
+ IncorrectArgumentsError = Class.new(StandardError)
17
+
18
+ def self.for_messages(&block)
19
+ attributes = DSL.run(&block)
20
+
21
+ Module.new do
22
+ attributes_string = attributes.map { |a| "Attribute.new(:#{a.name}, #{a.argument_types}, #{a.return_type})" }.join(",")
23
+ init = <<-RUBY
24
+ def initialize(*)
25
+ @__attributes = [#{attributes_string}]
26
+ super
27
+ after_initialize
28
+ end
29
+ RUBY
30
+
31
+ attributes.each do |a|
32
+ argument_checks = a.argument_types.each_with_index.map do |at, i|
33
+ "raise IncorrectArgumentsError unless args[#{i}].class == #{at.name};"
34
+ end.join(" ")
35
+
36
+ method_wrapper = "def #{a.name}(*args); #{argument_checks} super.tap do |return_val| raise IncorrectReturnType unless return_val.class == #{a.return_type}; end; end"
37
+
38
+ module_eval(method_wrapper)
39
+ end
40
+
41
+ module_eval(init)
42
+
43
+ module_eval("def run_checks; " + attributes.map { |a| "raise DoesNotImplementError, :#{a.name} if self.method(:#{a.name}).super_method.nil?;" }.join("") + "end")
44
+
45
+ def after_initialize
46
+ run_checks
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+
53
+ class DSL
54
+ attr_reader :attributes
55
+
56
+ def self.run(&block)
57
+ dsl = new
58
+ dsl.instance_eval(&block)
59
+ dsl.attributes
60
+ end
61
+
62
+ def initialize
63
+ @attributes = []
64
+ end
65
+
66
+ def method_missing(name, *args, **kwargs)
67
+ attributes << Attribute.new(name, args[0..-2], args.last)
68
+ end
69
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: interface_semantics
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Brauns II
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-04-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem for making interfaces
14
+ email: braunsie@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/interface_semantics.rb
20
+ homepage: https://rubygems.org/gems/interface_semantics
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubygems_version: 3.2.3
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: A gem for making interfaces
43
+ test_files: []