sig 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4715821434d81f8b6d4473888baf83db09dea536
4
- data.tar.gz: f99a5268d57adfac1a8acce982998c7c317ab430
3
+ metadata.gz: ceb274fbcf05f2de021879342171b1e4a522b8b0
4
+ data.tar.gz: 9b88c7e2d0582a6d4a10dec22f32c1a953d9110a
5
5
  SHA512:
6
- metadata.gz: ab71526170db48fed397b21f07a8905c7cdab0d2faaec363d2d58d2516a9253a3b7345cc2212d757db5cb51d44d7e9331a81a66886cdaa27f95b0e3a3b5f7f42
7
- data.tar.gz: 91e5c513bb67eba3f0a17d1fb549091608fb003062f76e18b2607716c8a003dc876ab9f8ae4654f91e80a33fdaba9dde04db04b411762664e123d9795266f310
6
+ metadata.gz: 2d8cfeb62529002f4eab8fd19fe0754963388101d2381b6861770996f70655fd30d1508923612d3a75c208061cf38906cdc9486367002e8103fd14d7b14f02be
7
+ data.tar.gz: 5d2aad0d692f818689acfa4e8fe4c51baec3d4fcb6348838fad6ff3fe56118d13dba8e4b830bd7da4f8755b4e4f985d00178af41fc7e86461a88c26ad00f85d6
Binary file
Binary file
@@ -7,6 +7,7 @@ rvm:
7
7
  - 2.2
8
8
  - 2.1
9
9
  - rbx-2
10
+ - ruby-head
10
11
  - jruby-9000
11
12
 
12
13
  cache:
@@ -14,4 +15,5 @@ cache:
14
15
 
15
16
  matrix:
16
17
  allow_failures:
18
+ - rvm: ruby-head
17
19
  - rvm: jruby-9000
@@ -1,5 +1,9 @@
1
1
  ## CHANGELOG
2
2
 
3
+ ### 1.0.1
4
+
5
+ * Improve keyword argument code, which also improves performance
6
+
3
7
  ### 1.0.0
4
8
 
5
9
  * Inital release
data/README.md CHANGED
@@ -20,6 +20,7 @@ class A
20
20
  a * b
21
21
  end
22
22
  end
23
+
23
24
  A.new.mul(4,"3")
24
25
  # Sig::ArgumentTypeError:
25
26
  # - Expected "3" to be a Numeric, but is a String
@@ -32,6 +33,7 @@ class B
32
33
  object.reverse
33
34
  end
34
35
  end
36
+
35
37
  B.rev 42
36
38
  # Sig::ArgumentTypeError:
37
39
  # - Expected 42 to respond to :reverse
@@ -96,13 +98,38 @@ sig [Numeric, nil, Numeric], # first and third argument must be numeric, d
96
98
 
97
99
  See source(https://github.com/janlelis/sig/blob/master/lib/sig.rb) or specs(https://github.com/janlelis/sig/blob/master/spec/sig_spec.rb) for more features.
98
100
 
99
- ## Deactivate all signature checking
101
+ ## Benchmark (Take with a Grain of Salt)
102
+
103
+ ```
104
+ ruby version: 2.2.2
105
+ sig version: 1.0.1
106
+ rubype version: 0.2.5
107
+ contracts version: 0.8
108
+ Calculating -------------------------------------
109
+ pure 59.389k i/100ms
110
+ sig 9.386k i/100ms
111
+ rubype 8.343k i/100ms
112
+ contracts 5.011k i/100ms
113
+ -------------------------------------------------
114
+ pure 4.660M (± 0.6%) i/s - 23.340M
115
+ sig 136.535k (± 0.7%) i/s - 685.178k
116
+ rubype 112.444k (± 0.4%) i/s - 567.324k
117
+ contracts 60.699k (± 0.4%) i/s - 305.671k
118
+
119
+ Comparison:
120
+ pure: 4660112.0 i/s
121
+ sig: 136535.0 i/s - 34.13x slower
122
+ rubype: 112443.6 i/s - 41.44x slower
123
+ contracts: 60698.9 i/s - 76.77x slower
124
+ ```
125
+
126
+ ## Deactivate All Signature Checking
100
127
 
101
128
  ```ruby
102
129
  require 'sig/none' # instead of require 'sig'
103
130
  ```
104
131
 
105
- ## Alternatives for type checking and more
132
+ ## Alternatives for Type Checking and More
106
133
 
107
134
  - https://github.com/gogotanaka/Rubype
108
135
  - https://github.com/egonSchiele/contracts.ruby
data/Rakefile CHANGED
@@ -29,6 +29,7 @@ task :irb do
29
29
  sh "irb -I ./lib -r #{gemspec.name.gsub '-','/'}"
30
30
  end
31
31
 
32
+
32
33
  # # #
33
34
  # Benchmark: Take with a grain of salt
34
35
 
@@ -63,7 +64,7 @@ task :benchmark do
63
64
  x + y
64
65
  end
65
66
 
66
- sig [Numeric, Numeric], Numeric,
67
+ sig [:to_i, :to_i], Numeric,
67
68
  def mul(x, y)
68
69
  x * y
69
70
  end
@@ -82,7 +83,7 @@ task :benchmark do
82
83
  def mul(x, y)
83
84
  x * y
84
85
  end
85
- typesig :mul, [Numeric, Numeric] => Numeric
86
+ typesig :mul, [:to_i, :to_i] => Numeric
86
87
  end
87
88
  rubype_instance = RubypeSum.new
88
89
  puts "rubype version: #{Rubype::VERSION}"
@@ -97,7 +98,7 @@ task :benchmark do
97
98
  x + y
98
99
  end
99
100
 
100
- Contract Num, Num => Num
101
+ Contract RespondTo[:to_i], RespondTo[:to_i] => Num
101
102
  def mul(x, y)
102
103
  x * y
103
104
  end
@@ -106,32 +107,50 @@ task :benchmark do
106
107
  puts "contracts version: #{Contracts::VERSION}"
107
108
 
108
109
  Benchmark.ips do |x|
109
- x.report("pure"){
110
- pure_instance.sum(1, 2)
111
- pure_instance.mul(1, 2)
110
+ x.report("pure"){ |times|
111
+ i = 0
112
+ while i < times
113
+ pure_instance.sum(1, 2)
114
+ pure_instance.mul(1, 2)
115
+ i += 1
116
+ end
112
117
  }
113
118
 
114
- x.report("sig"){
115
- sig_instance.sum(1, 2)
116
- sig_instance.mul(1, 2)
119
+ x.report("sig"){ |times|
120
+ i = 0
121
+ while i < times
122
+ sig_instance.sum(1, 2)
123
+ sig_instance.mul(1, 2)
124
+ i += 1
125
+ end
117
126
  }
118
127
 
119
- x.report("rubype"){
120
- rubype_instance.sum(1, 2)
121
- rubype_instance.mul(1, 2)
128
+ x.report("rubype"){ |times|
129
+ i = 0
130
+ while i < times
131
+ rubype_instance.sum(1, 2)
132
+ rubype_instance.mul(1, 2)
133
+ i += 1
134
+ end
122
135
  }
123
136
 
124
- x.report("contracts"){
125
- contracts_instance.sum(1, 2)
126
- contracts_instance.mul(1, 2)
137
+ x.report("contracts"){ |times|
138
+ i = 0
139
+ while i < times
140
+ contracts_instance.sum(1, 2)
141
+ contracts_instance.mul(1, 2)
142
+ i += 1
143
+ end
127
144
  }
128
- x.warmup = 10
145
+
129
146
  x.compare!
130
147
  end
131
148
  end
132
149
 
150
+
133
151
  # # #
134
152
  # Specs
153
+
135
154
  desc "Run specs"
136
155
  task :spec do
137
156
  ruby "spec/sig_spec.rb"
data/lib/sig.rb CHANGED
@@ -9,13 +9,22 @@ module Sig
9
9
  end
10
10
 
11
11
  def self.define(object, expected_arguments, expected_result = nil, method_name)
12
+ expected_arguments = Array(expected_arguments)
13
+ if expected_arguments.last.is_a?(Hash)
14
+ expected_keyword_arguments = expected_arguments.delete_at(-1)
15
+ else
16
+ expected_keyword_arguments = nil
17
+ end
18
+
12
19
  method_visibility = get_method_visibility_or_raise(object, method_name)
13
20
  signature_checker = get_or_create_signature_checker(object)
14
21
  signature_checker.send :define_method, method_name do |*arguments, **keyword_arguments|
15
- ::Sig.check_arguments(expected_arguments, arguments, keyword_arguments)
16
22
  if keyword_arguments.empty?
23
+ ::Sig.check_arguments(expected_arguments, arguments)
17
24
  result = super(*arguments)
18
25
  else
26
+ ::Sig.check_arguments_with_keywords(expected_arguments, arguments,
27
+ expected_keyword_arguments, keyword_arguments)
19
28
  result = super(*arguments, **keyword_arguments)
20
29
  end
21
30
  ::Sig.check_result(expected_result, result)
@@ -50,29 +59,38 @@ module Sig
50
59
  checker
51
60
  end
52
61
 
53
- def self.check_arguments(expected_arguments, arguments, keyword_arguments)
62
+ def self.check_arguments(expected_arguments, arguments)
54
63
  errors = ""
55
64
 
56
- normalized_expected_arguments = Array(expected_arguments).dup
57
- if normalized_expected_arguments.last.is_a?(Hash)
58
- expected_keyword_arguments = normalized_expected_arguments.delete_at(-1)
59
- elsif keyword_arguments
60
- expected_keyword_arguments = {}
61
- arguments += [keyword_arguments] unless keyword_arguments.empty?
65
+ arguments.each_with_index{ |argument, index|
66
+ if error = valid_or_formatted_error(expected_arguments[index], argument)
67
+ errors << error
68
+ end
69
+ }
70
+
71
+ unless errors.empty?
72
+ raise ArgumentTypeError, errors
62
73
  end
74
+ end
75
+
76
+ def self.check_arguments_with_keywords(expected_arguments, arguments,
77
+ expected_keyword_arguments, keyword_arguments)
78
+ errors = ""
63
79
 
64
80
  arguments.each_with_index{ |argument, index|
65
- if error = valid_or_formatted_error(normalized_expected_arguments[index], argument)
81
+ if error = valid_or_formatted_error(expected_arguments[index], argument)
66
82
  errors << error
67
83
  end
68
84
  }
69
85
 
70
- unless expected_keyword_arguments.empty?
71
- keyword_arguments.each{ |key, argument|
72
- if error = valid_or_formatted_error(expected_keyword_arguments[key], argument)
86
+ if expected_keyword_arguments
87
+ keyword_arguments.each{ |key, keyword_argument|
88
+ if error = valid_or_formatted_error(expected_keyword_arguments[key], keyword_argument)
73
89
  errors << error
74
90
  end
75
91
  }
92
+ elsif error = valid_or_formatted_error(expected_arguments[arguments.size], keyword_arguments)
93
+ errors << error
76
94
  end
77
95
 
78
96
  unless errors.empty?
@@ -1,4 +1,4 @@
1
1
  module Sig
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.0.1".freeze
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sig
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Lelis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-14 00:00:00.000000000 Z
11
+ date: 2015-04-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Optional Type Assertions for Ruby methods.
14
14
  email: mail@janlelis.de
@@ -16,9 +16,10 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - ".CHANGELOG.md.swp"
20
+ - ".Rakefile.swp"
19
21
  - ".gitignore"
20
22
  - ".travis.yml"
21
- - B.rev
22
23
  - CHANGELOG.md
23
24
  - Gemfile
24
25
  - Gemfile.lock
@@ -60,4 +61,3 @@ summary: Optional Type Assertions for Ruby.
60
61
  test_files:
61
62
  - spec/.sig_spec.rb.swp
62
63
  - spec/sig_spec.rb
63
- has_rdoc:
data/B.rev DELETED
File without changes