kwattr 0.2.0 → 0.3.0
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 +4 -4
- data/README.md +6 -2
- data/Rakefile +5 -1
- data/benchmark.rb +124 -0
- data/kwattr.gemspec +3 -4
- data/lib/kwattr.rb +35 -35
- data/test.rb +0 -3
- metadata +17 -3
- data/lib/kwattr/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a5f6547c53d33b561a7706e2f35f265cdfc47b9
|
4
|
+
data.tar.gz: 519b1520e6d69054a81c8de80529982a0bc3c066
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
60
|
+
class Foo
|
61
|
+
kwattr :foo
|
62
|
+
end
|
63
|
+
|
64
|
+
class FooWithBar < Foo
|
61
65
|
kwattr :bar
|
62
66
|
end
|
63
67
|
|
64
|
-
|
68
|
+
FooWithBar.new(foo: 42, bar: 21) # => #<FooWithBar @foo=42, @bar=21>
|
65
69
|
```
|
66
70
|
|
67
71
|
### include
|
data/Rakefile
CHANGED
data/benchmark.rb
ADDED
@@ -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
|
data/kwattr.gemspec
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
|
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 =
|
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
|
data/lib/kwattr.rb
CHANGED
@@ -1,57 +1,57 @@
|
|
1
|
-
|
1
|
+
class KWAttr < Module
|
2
|
+
VERSION = "0.3.0"
|
2
3
|
|
3
|
-
|
4
|
+
attr_reader :required_attrs, :defaults
|
4
5
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
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
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
30
|
-
|
31
|
-
required
|
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
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
41
|
+
|
47
42
|
super(*args)
|
48
43
|
end
|
44
|
+
$VERBOSE = true
|
49
45
|
end
|
50
46
|
|
51
47
|
end
|
52
48
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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.
|
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-
|
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: []
|
data/lib/kwattr/version.rb
DELETED