def_initialize 0.0.1 → 0.1.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/.travis.yml +4 -1
- data/README.md +76 -4
- data/def_initialize.gemspec +3 -3
- data/lib/def_initialize.rb +24 -32
- data/lib/def_initialize/accessors_builder.rb +36 -0
- data/lib/def_initialize/dsl.rb +7 -0
- data/lib/def_initialize/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: baa0280d5bf1bcf38f202c06e1504b5fdd365977a7ec6695c579349ef0006b65
|
4
|
+
data.tar.gz: 3768cfd27fc19807146acf23403aa07c438398acb41e1bb7bb36ed1113a23150
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc0fdec0a482a0bf7429f59a97bd280e293da25c544f9570f88fc1bc39545188964ccc055c10ca7b95aaf158647877b5172d8edd38c3cb15f595bbc5082d6e27
|
7
|
+
data.tar.gz: f2f19e386c0809565eaf97d3c75163d0951b551a11ee92ee92c6263728e9dbec041752872289cdca64d5e5a0e6dfc9868977ade3f0a3972615d1064f732dd1e9
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://travis-ci.org/antoshalee/def_initialize)
|
2
|
+
|
1
3
|
# DefInitialize (WIP)
|
2
4
|
|
3
5
|
Another approach to reduce initialization boilerplate
|
@@ -23,26 +25,96 @@ Or install it yourself as:
|
|
23
25
|
|
24
26
|
```ruby
|
25
27
|
class Employee
|
26
|
-
include DefInitialize.with("name, uuid = SecureRandom.uuid, age
|
28
|
+
include DefInitialize.with("name, uuid = SecureRandom.uuid, age:, position: 'manager'")
|
27
29
|
end
|
28
30
|
|
29
31
|
# is the same as:
|
30
32
|
|
31
33
|
class Employee
|
32
|
-
attr_reader :name, :uuid, :age, :position
|
33
|
-
|
34
34
|
def initialize(name, uuid = SecureRandom.uuid, age:, position: 'manager')
|
35
35
|
@name = name
|
36
36
|
@uuid = uuid
|
37
37
|
@age = age
|
38
38
|
@position = position
|
39
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :name, :uuid, :age, :position
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
By convention, parameters starting with underscore symbol `'_'` are ignored:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
class Point
|
51
|
+
include DefInitialize.with("x, y, _c")
|
52
|
+
end
|
53
|
+
|
54
|
+
# transforms to:
|
55
|
+
|
56
|
+
class Point
|
57
|
+
def initialize(x, y, _c) # Note that `_c` is still required to pass
|
58
|
+
@x = x
|
59
|
+
@y = y
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
attr_reader :x, :y
|
40
65
|
end
|
41
66
|
```
|
42
67
|
|
68
|
+
### DSL
|
69
|
+
|
70
|
+
Alternatively, you can extend a class with `DefInitialize::DSL` and use `def_initialize` method. Note, how close it looks to the native declaration!
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
class Base
|
74
|
+
extend DefInitialize::DSL
|
75
|
+
end
|
76
|
+
|
77
|
+
class Circle < Base
|
78
|
+
def_initialize("radius")
|
79
|
+
end
|
80
|
+
|
81
|
+
class Rectangle < Base
|
82
|
+
def_initialize("length, width")
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
### Access control
|
87
|
+
|
88
|
+
You can specify level of access for your readers and writers:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class Person < Base
|
92
|
+
def_initialize("name", readers: :public, writers: :private)
|
93
|
+
end
|
94
|
+
|
95
|
+
# transforms to:
|
96
|
+
|
97
|
+
class Person
|
98
|
+
def initialize(name)
|
99
|
+
@name = name
|
100
|
+
end
|
101
|
+
|
102
|
+
attr_reader :name
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
attr_writer :name
|
107
|
+
end
|
108
|
+
|
109
|
+
```
|
110
|
+
Allowed values are `:public`, `:private`, `:protected` and `nil`. If value is `nil`, accessors won't be defined at all.
|
111
|
+
|
112
|
+
default value for `readers` is `private`, default value for `writers` is `nil`
|
113
|
+
|
114
|
+
|
43
115
|
### What should I do in more complex cases?
|
44
116
|
|
45
|
-
Just write old
|
117
|
+
Just write plain old `def initialize`.
|
46
118
|
|
47
119
|
|
48
120
|
## Development
|
data/def_initialize.gemspec
CHANGED
@@ -6,10 +6,10 @@ require 'def_initialize/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'def_initialize'
|
8
8
|
spec.version = DefInitialize::VERSION
|
9
|
-
spec.authors = ['Anton Lee']
|
10
|
-
spec.email = ['antoshalee@gmail.com']
|
9
|
+
spec.authors = ['Anton Lee', 'Vladimir Kochnev']
|
10
|
+
spec.email = ['antoshalee@gmail.com', 'hashtable@yandex.ru']
|
11
11
|
|
12
|
-
spec.summary = 'Define
|
12
|
+
spec.summary = 'Define an initializer along with attribute accessors in one line'
|
13
13
|
spec.homepage = 'https://github.com/antoshalee/def_initialize'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
data/lib/def_initialize.rb
CHANGED
@@ -1,51 +1,43 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DefInitialize
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
class Parser
|
8
|
-
VAR_RE = /(\w+)/
|
9
|
-
ARG_RE = /#{VAR_RE}(?:\s=\s.+?)*/
|
10
|
-
ARGS_RE = /#{ARG_RE}(?:, #{ARG_RE})*/
|
11
|
-
KWARG_RE = /#{VAR_RE}:(?:\s.+?)*/
|
12
|
-
KWARGS_RE = /#{KWARG_RE}(?:, #{KWARG_RE})*/
|
13
|
-
RE = /\A#{ARGS_RE}(?:, #{KWARGS_RE})?\z/
|
14
|
-
|
15
|
-
class << self
|
16
|
-
def parse(str)
|
17
|
-
if(match_data = str.match(RE))
|
18
|
-
match_data.captures
|
19
|
-
else
|
20
|
-
raise ArgumentError, 'Failed to parse arguments'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
4
|
+
require 'def_initialize/version'
|
5
|
+
require 'def_initialize/dsl'
|
6
|
+
require 'def_initialize/accessors_builder'
|
25
7
|
|
26
8
|
class Mixin < Module
|
27
|
-
def initialize(args_str)
|
28
|
-
|
9
|
+
def initialize(args_str, readers: :private, writers: nil)
|
10
|
+
accessors_options = { readers_mode: readers, writers_mode: writers }
|
11
|
+
|
12
|
+
# Create empty method just to inspect its parameters.
|
13
|
+
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
14
|
+
def initialize(#{args_str}); end
|
15
|
+
CODE
|
29
16
|
|
30
|
-
|
17
|
+
parameters = instance_method(:initialize).parameters
|
31
18
|
|
32
|
-
|
33
|
-
|
34
|
-
|
19
|
+
accessors, rows = [], []
|
20
|
+
|
21
|
+
parameters
|
22
|
+
.each do |(_type, name)|
|
23
|
+
next if !name || name.to_s.start_with?('_')
|
24
|
+
accessors << ":#{name}"
|
25
|
+
rows << "@#{name} = #{name}"
|
26
|
+
end
|
35
27
|
|
36
28
|
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
37
29
|
def initialize(#{args_str})
|
38
|
-
#{
|
30
|
+
#{rows.join("\n")}
|
39
31
|
end
|
40
32
|
|
41
|
-
|
33
|
+
#{AccessorsBuilder.build(accessors, accessors_options)}
|
42
34
|
CODE
|
43
35
|
end
|
44
36
|
end
|
45
37
|
|
46
38
|
class << self
|
47
|
-
def with(args_str)
|
48
|
-
Mixin.new(args_str)
|
39
|
+
def with(args_str, **opts)
|
40
|
+
Mixin.new(args_str, **opts)
|
49
41
|
end
|
50
42
|
end
|
51
43
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DefInitialize
|
4
|
+
module AccessorsBuilder
|
5
|
+
class << self
|
6
|
+
def build(accessors, readers_mode:, writers_mode:)
|
7
|
+
check_option!(readers_mode)
|
8
|
+
check_option!(writers_mode)
|
9
|
+
|
10
|
+
result = ''.dup
|
11
|
+
|
12
|
+
if readers_mode
|
13
|
+
result << "#{readers_mode}\n"
|
14
|
+
result << "attr_reader #{accessors.join(', ')}\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
if writers_mode
|
18
|
+
result << "#{writers_mode}\n"
|
19
|
+
result << "attr_writer #{accessors.join(', ')}\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def check_option!(value)
|
28
|
+
return unless value
|
29
|
+
return if %w[private public protected].include?(value.to_s)
|
30
|
+
|
31
|
+
raise ArgumentError,
|
32
|
+
"Uknown value #{value}. Must be :private, :public, :protected or nil"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: def_initialize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anton Lee
|
8
|
+
- Vladimir Kochnev
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
12
|
+
date: 2019-03-11 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
@@ -55,6 +56,7 @@ dependencies:
|
|
55
56
|
description:
|
56
57
|
email:
|
57
58
|
- antoshalee@gmail.com
|
59
|
+
- hashtable@yandex.ru
|
58
60
|
executables: []
|
59
61
|
extensions: []
|
60
62
|
extra_rdoc_files: []
|
@@ -71,6 +73,8 @@ files:
|
|
71
73
|
- bin/setup
|
72
74
|
- def_initialize.gemspec
|
73
75
|
- lib/def_initialize.rb
|
76
|
+
- lib/def_initialize/accessors_builder.rb
|
77
|
+
- lib/def_initialize/dsl.rb
|
74
78
|
- lib/def_initialize/version.rb
|
75
79
|
homepage: https://github.com/antoshalee/def_initialize
|
76
80
|
licenses:
|
@@ -94,5 +98,5 @@ requirements: []
|
|
94
98
|
rubygems_version: 3.0.3
|
95
99
|
signing_key:
|
96
100
|
specification_version: 4
|
97
|
-
summary: Define
|
101
|
+
summary: Define an initializer along with attribute accessors in one line
|
98
102
|
test_files: []
|