kwattr 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f3f52b74e112e1a8cd7ee56f91323339731eafd4
4
- data.tar.gz: a763e6223e15158fe8062a801b2cfe78309adb54
3
+ metadata.gz: 7a5f6547c53d33b561a7706e2f35f265cdfc47b9
4
+ data.tar.gz: 519b1520e6d69054a81c8de80529982a0bc3c066
5
5
  SHA512:
6
- metadata.gz: 2dc7f95df0dd1ef9dbe54f4d4900194ab11c85b6374811df4157c0a09aeb073a4a34409fcdf2ba4cfad48f373f916fb1cd608ab74ce4a157c0e276078b891251
7
- data.tar.gz: d63c3abdfc609d1441847176aac5ee6ee0f8169fe741b68de74c10f2489657602f29d794f2968179c5914a2435ffa4be2614630130c9a3cec714776d7510676a
6
+ metadata.gz: 1c81b0f64cb6875c4dd96582199348b8580e490d2e77524640ec1b4b6e1dea265bb660387ed9389dfc09be630c68cce22f3616c2cc0512d19c698e54ad09a26c
7
+ data.tar.gz: 34975ee6fac582fc340b9d937ca432e8f35ac8d1d88b1996bf432370f9e6e814a1b31a501177a82e018e88b4a4cc47f1071cbf63b2b58be1d18342368d92450e
data/README.md CHANGED
@@ -57,11 +57,15 @@ FooProtected.protected_instance_methods # => [:foo]
57
57
  ### subclass
58
58
 
59
59
  ```ruby
60
- class Bar < Foo
60
+ class Foo
61
+ kwattr :foo
62
+ end
63
+
64
+ class FooWithBar < Foo
61
65
  kwattr :bar
62
66
  end
63
67
 
64
- Bar.new(bar: 42) # => #<Bar @foo=42, @bar=42>
68
+ FooWithBar.new(foo: 42, bar: 21) # => #<FooWithBar @foo=42, @bar=21>
65
69
  ```
66
70
 
67
71
  ### include
data/Rakefile CHANGED
@@ -13,4 +13,8 @@ task :examples do
13
13
  ruby "test.rb"
14
14
  end
15
15
 
16
- task :default => [:examples, :spec]
16
+ task :benchmark do
17
+ ruby "benchmark.rb"
18
+ end
19
+
20
+ task :default => [:examples, :spec, :benchmark]
@@ -0,0 +1,124 @@
1
+ require 'benchmark/ips'
2
+ require 'kwattr'
3
+ require_relative 'spec/examples'
4
+
5
+ class ROneAttr
6
+ attr_reader :foo
7
+
8
+ def initialize(foo:)
9
+ @foo = foo
10
+ end
11
+ end
12
+
13
+ class ROneAttrDefault
14
+ DEFAULT_FOO = 42
15
+
16
+ attr_reader :foo
17
+
18
+ def initialize(foo: DEFAULT_FOO)
19
+ @foo = foo
20
+ end
21
+ end
22
+
23
+ class ROneAttrOnePositional
24
+ attr_reader :foo, :bar
25
+
26
+ def initialize(bar, foo:)
27
+ @foo = foo
28
+ @bar = bar
29
+ end
30
+ end
31
+
32
+ class RTwoAttrs
33
+ attr_reader :foo, :bar
34
+
35
+ def initialize(foo:, bar:)
36
+ @foo = foo
37
+ @bar = bar
38
+ end
39
+ end
40
+
41
+ class RTwoAttrsDefaults
42
+ DEFAULT_FOO = 42
43
+ DEFAULT_BAR = 21
44
+
45
+ attr_reader :foo, :bar
46
+
47
+ def initialize(foo: DEFAULT_FOO, bar: DEFAULT_BAR)
48
+ @foo = foo
49
+ @bar = bar
50
+ end
51
+ end
52
+
53
+ class RTwoAttrsOneDefault
54
+ DEFAULT_BAR = 21
55
+
56
+ attr_reader :foo, :bar
57
+
58
+ def initialize(foo:, bar: DEFAULT_BAR)
59
+ @foo = foo
60
+ @bar = bar
61
+ end
62
+ end
63
+
64
+ class RTwoAttrsOnePos
65
+ attr_reader :foo, :bar, :baz
66
+
67
+ def initialize(baz, foo:, bar:)
68
+ @foo = foo
69
+ @bar = bar
70
+ @baz = baz
71
+ end
72
+ end
73
+
74
+ class RTwoAttrsInheritsOneAttr < ROneAttr
75
+ attr_reader :bar
76
+
77
+ def initialize(foo:, bar:)
78
+ super(foo: foo)
79
+ @bar = bar
80
+ end
81
+ end
82
+
83
+ module ROneAttrModule
84
+ attr_reader :foo
85
+
86
+ def initialize(foo:)
87
+ @foo = foo
88
+ end
89
+ end
90
+
91
+ class ROneAttrViaModule
92
+ include ROneAttrModule
93
+ end
94
+
95
+ Benchmark.ips do |b|
96
+ b.warmup = 0.1
97
+ b.time = 1
98
+
99
+ b.report "KWAttr classes" do
100
+ OneAttr.new foo: 42
101
+ OneAttrDefault.new
102
+ OneAttrOnePositional.new 42, foo: 21
103
+ TwoAttrs.new foo: 42, bar: 21
104
+ TwoAttrsDefaults.new
105
+ TwoAttrsOneDefault.new foo: 42
106
+ TwoAttrsOnePos.new 42, foo: 21, bar: 14
107
+ TwoAttrsInheritsOneAttr.new foo: 42, bar: 21
108
+ OneAttrViaModule.new foo: 42
109
+ end
110
+
111
+ b.report "Plain classes" do
112
+ ROneAttr.new foo: 42
113
+ ROneAttrDefault.new
114
+ ROneAttrOnePositional.new 42, foo: 21
115
+ RTwoAttrs.new foo: 42, bar: 21
116
+ RTwoAttrsDefaults.new
117
+ RTwoAttrsOneDefault.new foo: 42
118
+ RTwoAttrsOnePos.new 42, foo: 21, bar: 14
119
+ RTwoAttrsInheritsOneAttr.new foo: 42, bar: 21
120
+ ROneAttrViaModule.new foo: 42
121
+ end
122
+
123
+ b.compare!
124
+ end
@@ -1,11 +1,9 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'kwattr/version'
2
+ require_relative 'lib/kwattr'
5
3
 
6
4
  Gem::Specification.new do |spec|
7
5
  spec.name = "kwattr"
8
- spec.version = KWattr::VERSION
6
+ spec.version = KWAttr::VERSION
9
7
  spec.authors = ["Étienne Barrié"]
10
8
  spec.email = ["etienne.barrie@gmail.com"]
11
9
 
@@ -19,4 +17,5 @@ Gem::Specification.new do |spec|
19
17
  spec.add_development_dependency "bundler", "~> 1.9"
20
18
  spec.add_development_dependency "rake", "~> 10.0"
21
19
  spec.add_development_dependency "rspec", "~> 3.2"
20
+ spec.add_development_dependency "benchmark-ips", "~> 2.2"
22
21
  end
@@ -1,57 +1,57 @@
1
- require "kwattr/version"
1
+ class KWAttr < Module
2
+ VERSION = "0.3.0"
2
3
 
3
- module KWAttr
4
+ attr_reader :required_attrs, :defaults
4
5
 
5
- def kwattr(*attrs, **opts)
6
- names = [*attrs, *opts.keys]
7
- attr_reader(*names)
8
- prepend Initializer
9
- extend Heritable
10
- required, defaults = kwattrs
11
- attrs.each { |attr| required << attr unless required.include?(attr) }
12
- defaults.merge!(opts)
13
- names
6
+ def initialize
7
+ @required_attrs = []
8
+ @defaults = {}
14
9
  end
15
10
 
16
- def kwattrs
17
- @kwattrs ||= [[], {}]
18
- end
19
-
20
- module Heritable
21
- def inherited(subclass)
22
- required, defaults = kwattrs
23
- subclass.kwattr(*required, **defaults)
24
- end
25
-
26
- alias_method :included, :inherited
27
- end
11
+ def initializer(attrs, opts)
12
+ required_attrs = self.required_attrs
13
+ defaults = self.defaults
14
+ required_attrs.concat(attrs).uniq!
15
+ defaults.merge!(opts)
28
16
 
29
- module Initializer
30
- def initialize(*args, **kwargs)
31
- required, defaults = self.class.kwattrs
32
- required = required.dup
17
+ $VERBOSE = false
18
+ define_method :initialize do |*args, **kwargs|
19
+ required = required_attrs.dup
33
20
  defaults.merge(kwargs).each_pair do |key, value|
34
21
  next unless required.delete(key) || defaults.key?(key)
35
22
  kwargs.delete(key)
36
23
  instance_variable_set "@#{key}", value
37
24
  end
25
+
38
26
  unless required.empty?
27
+ method(:initialize).super_method.parameters.each do |type, name|
28
+ required << name if type == :keyreq && !kwargs.key?(name)
29
+ end
39
30
  raise ArgumentError,
40
31
  "missing keyword#{'s' if required.size > 1}: #{required.join(', ')}"
41
32
  end
42
- if method(:initialize).super_method.arity == args.size && !kwargs.empty?
43
- raise ArgumentError,
44
- "unknown keyword#{'s' if kwargs.size > 1}: #{kwargs.keys.join(', ')}"
33
+ unless kwargs.empty?
34
+ arity = method(:initialize).super_method.arity
35
+ if arity != -1 && arity == args.size
36
+ raise ArgumentError,
37
+ "unknown keyword#{'s' if kwargs.size > 1}: #{kwargs.keys.join(', ')}"
38
+ end
39
+ args << kwargs
45
40
  end
46
- args << kwargs unless kwargs.empty?
41
+
47
42
  super(*args)
48
43
  end
44
+ $VERBOSE = true
49
45
  end
50
46
 
51
47
  end
52
48
 
53
- public def kwattr(*args)
54
- raise TypeError, "wrong type #{self.class} (expected Module)" unless Module === self
55
- extend KWAttr
56
- kwattr(*args)
49
+ class Module
50
+ def kwattr(*attrs, **opts)
51
+ names = [*attrs, *opts.keys]
52
+ attr_reader(*names)
53
+ prepend @kwattrs ||= KWAttr.new
54
+ @kwattrs.initializer(attrs, opts)
55
+ names
56
+ end
57
57
  end
data/test.rb CHANGED
@@ -15,8 +15,6 @@ rescue exception_class
15
15
  return p $!
16
16
  end
17
17
 
18
- fail unless raises?(TypeError) { kwattr }
19
-
20
18
  fail unless raises?(ArgumentError) { Test.new }
21
19
  fail unless raises?(ArgumentError) { Test.new(foo: 42) }
22
20
  fail unless raises?(ArgumentError) { Test.new(foo: 42, bar: 21, baz: 43) }
@@ -49,7 +47,6 @@ fail unless p(test.titi) == 1
49
47
  fail unless p(test.toto) == 2
50
48
 
51
49
  class TestDescendant < Test
52
- kwattr :bar
53
50
  kwattr :baz
54
51
  end
55
52
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kwattr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Étienne Barrié"
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-07 00:00:00.000000000 Z
11
+ date: 2015-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: benchmark-ips
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.2'
55
69
  description: ''
56
70
  email:
57
71
  - etienne.barrie@gmail.com
@@ -66,11 +80,11 @@ files:
66
80
  - Gemfile
67
81
  - README.md
68
82
  - Rakefile
83
+ - benchmark.rb
69
84
  - bin/console
70
85
  - bin/setup
71
86
  - kwattr.gemspec
72
87
  - lib/kwattr.rb
73
- - lib/kwattr/version.rb
74
88
  - test.rb
75
89
  homepage: https://github.com/etiennebarrie/kwattr
76
90
  licenses: []
@@ -1,3 +0,0 @@
1
- module KWattr
2
- VERSION = "0.2.0"
3
- end