trinkets 0.1.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
  SHA256:
3
- metadata.gz: 68ed0792dc692c54ba0b00f781bc49b0baf2ce0d79b98fca94c2807c5532e8d7
4
- data.tar.gz: f5724dff46a3b64e7ee40ac72fb852bc8e47e0b6683fc95704c901bbd19c7f0b
3
+ metadata.gz: '018b1a7eeedc27c57853bd408ac7b698f1573f7b2646c7fdb8f36e2dce2b0add'
4
+ data.tar.gz: 50d9ec8927e0f127c17a410148c923e382b2749afe5ba87f13ef6d518349ecd4
5
5
  SHA512:
6
- metadata.gz: 9d2738f9ce51557a84ae9c70896556d20cb321feb7ea31e9eee2be023dc25fa66bae7f85db4e720829b9d0338611b6c9c75e8fe7ac2f93df7db3728856c4bbf2
7
- data.tar.gz: 2b0bb1da03c91f7eebff9a9f1994b5590c52cee0ab11b8643b1155805be00c79017092fcf49c017d52f95f1a8d08fc59e84659d913d4e35c6784b8bd7b541cba
6
+ metadata.gz: 73b50ad1d15f661512a2c1b230b993b6d4a9a56d5a8a72ebc9a7cd9cfe03989bd32897131f1991a071daaac50fdad2eaf8fb0cbfd4dd60430ea6de74c3cddbcc
7
+ data.tar.gz: 8643d7e712ef9798b459cb9dc28f35e72f4dc80215e2b860c7a23a06a4c029dac83d7271324f2605d6812d30c40ad96032d348fca2c1eeb62812c7923666e81f
data/CHANGELOG.md CHANGED
@@ -0,0 +1,10 @@
1
+
2
+ ### [0.3.0](https://github.com/SilverPhoenix99/trinkets/tree/v0.3.0)
3
+ * Restructured folders to default to `/refine/`.
4
+ * Added `Enumerable#each_with_hash`/`Enumerator#with_hash`.
5
+
6
+ ### [0.2.0](https://github.com/SilverPhoenix99/trinkets/tree/v0.2.0)
7
+ * Added `attr: :none` as an option for `Class::init`.
8
+
9
+ ### [0.1.0](https://github.com/SilverPhoenix99/trinkets/tree/v0.1.0)
10
+ * Added `Class::init`.
data/README.md CHANGED
@@ -1,53 +1,82 @@
1
- # Trinkets
2
-
3
- It's the bootleg [facets](https://github.com/rubyworks/facets?tab=readme-ov-file#ruby-facets).
4
-
5
- ## Installation
6
-
7
- ```
8
- gem install trinkets
9
- ```
10
-
11
- ## Usage
12
-
13
- There are 3 ways to load trinkets:
14
- * As refinements;
15
- * As explicit `include` or `extend`;
16
- * As implicit `include` or `extend`, a.k.a. monkey-patching.
17
-
18
- ### Refinement
19
-
20
- ```ruby
21
- require 'trinkets/refine/class/init'
22
-
23
- using ::Trinkets::Class::Init
24
- ```
25
-
26
- ### Extend
27
-
28
- ```ruby
29
- require 'trinkets/extend/class/init'
30
-
31
- class Test
32
- extend ::Trinkets::Class::Init
33
- end
34
- ```
35
-
36
- ### Mokey Patching
37
-
38
- ```ruby
39
- require 'trinkets/patch/class/init'
40
- ```
41
-
42
- ## Available modules
43
-
44
- |Trinket|
45
- |---|
46
- |[class/init](doc/class/init.md)|
47
-
48
- [//]: # (TODO: Development)
49
- [//]: # (TODO: Contributing)
50
-
51
- ## License
52
-
53
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
1
+ # Trinkets
2
+
3
+ It's the bootleg [facets](https://github.com/rubyworks/facets?tab=readme-ov-file#ruby-facets).
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ gem install trinkets
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ The trinkets are loaded with the following structure:
14
+ ```ruby
15
+ require 'trinkets/{how-to-patch}/{class}/{method}'
16
+ ```
17
+
18
+ There are 3 ways to load trinkets, which are represented by the `{how-to-patch}` portion in the requires:
19
+ * `refine` : As refinements;
20
+ * `extend`/`include` : As explicit `extend` or `include`;
21
+ * `patch` : As implicit `include` or `extend`, a.k.a. monkey-patching.
22
+
23
+ ### Refinement
24
+
25
+ ```ruby
26
+ require 'trinkets/class/init'
27
+
28
+ using ::Trinkets::Class::Init
29
+ ```
30
+
31
+ The `refine` subdirectory is the default, and it can be omitted from `require`. The above is the same as:
32
+
33
+ ```ruby
34
+ require 'trinkets/refine/class/init'
35
+ ```
36
+
37
+ ### Extend
38
+
39
+ ```ruby
40
+ require 'trinkets/extend/class/init'
41
+
42
+ class Test
43
+ extend ::Trinkets::Class::Init
44
+ end
45
+ ```
46
+
47
+ ### Mokey Patching
48
+
49
+ ```ruby
50
+ require 'trinkets/patch/class/init'
51
+ ```
52
+
53
+ ## Available modules
54
+
55
+ |Trinket|
56
+ |---|
57
+ |[class/init](doc/class/init.md)|
58
+ |[enumerable/each_with_hash](doc/enumerable/each_with_hash.md)|
59
+
60
+ ## Versioning
61
+
62
+ Versions follow semantic versioning: `major.minor.patch`
63
+ * `major`: breaking changes.
64
+ * `minor`: improvements and new features that are backwards compatible.
65
+ * `patch`: backwards compatible fixes to existing features, or documentation improvements.
66
+
67
+ [//]: # (TODO: Development)
68
+
69
+ ## Contributing
70
+
71
+ Steps to include when developing the feature/fix:
72
+ * Add or change the appropriate RSpec tests.
73
+ * Document the feature.
74
+ * Might not apply to fixes if the feature didn't change.
75
+ * Bump the [version](lib/trinkets/version.rb).
76
+ * Update the Changelog.
77
+
78
+ [//]: # (TODO: Contributing)
79
+
80
+ ## License
81
+
82
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/doc/class/init.md CHANGED
@@ -1,122 +1,181 @@
1
- # Description
2
-
3
- It allows generating simple `#initialize` methods.
4
-
5
- To use it define a class and call `::init` like you would call `::attr` methods:
6
- * pass the name of the arguments as symbols
7
- * pass options at the end:
8
- * `attr` : what getters and/or setters to define
9
- * can be `:accessor`, `:reader` or `:writer`
10
- * defaults to `:accessor`
11
- * `kw` : if arguments are to be set as keyword arguments
12
- * defaults to `false`
13
-
14
- The same options can be used per individual argument
15
-
16
- # Examples
17
-
18
- ## Simple Initialize
19
- ```ruby
20
- class Test
21
- init :a, :b
22
- end
23
-
24
- # would be the same as
25
- class Test
26
- attr_accessor :a, :b
27
- def initialize(a, b)
28
- @a = a
29
- @b = b
30
- end
31
- end
32
-
33
- test = Test.new(1, 2)
34
- test.a
35
- # 1
36
-
37
- test.b
38
- # 2
39
-
40
- test.a = 3
41
- test.a
42
- # 3
43
- ```
44
-
45
- ## Read only access to instance variables
46
- ```ruby
47
- class TestAttr
48
- init :a, :b, attr: :reader
49
- end
50
-
51
- # would be the same as
52
- class Test
53
- attr_reader :a, :b
54
- def initialize(a, b)
55
- @a = a
56
- @b = b
57
- end
58
- end
59
-
60
- test = Test.new(1, 2)
61
- test.a
62
- # 1
63
-
64
- test.b
65
- # 2
66
-
67
- test.a = 3
68
- # > raises ArgumentError
69
- ```
70
-
71
- ## Initialize uses keyword arguments
72
- ```ruby
73
- class TestKW
74
- init :a, :b, kw: :true
75
- end
76
-
77
- # would be the same as
78
- class Test
79
- attr_accessor :a, :b
80
- def initialize(a:, b:)
81
- @a = a
82
- @b = b
83
- end
84
- end
85
-
86
- test = Test.new(a: 1, b: 2)
87
- test.a
88
- # 1
89
-
90
- test.b
91
- # 2
92
- ```
93
-
94
- ## Individual argument options
95
- ```ruby
96
- class TestIndividualArgsOptions
97
- init [:a, kw: true, attr: :reader], :b, [:c, kw: true]
98
- end
99
-
100
- # would be the same as
101
- class Test
102
- attr_reader :a
103
- attr_accessor :b, :c
104
- def initialize(b, a:, c:)
105
- @a = a
106
- @b = b
107
- end
108
- end
109
-
110
- test = Test.new(2, a: 1, c: 3)
111
- test.a
112
- # 1
113
-
114
- test.b
115
- # 2
116
-
117
- test.c
118
- # 3
119
-
120
- test.a = 4
121
- # > raises ArgumentError
122
- ```
1
+ # Description
2
+
3
+ It allows generating simple `#initialize` methods.
4
+
5
+ To use it, define a class and call `::init` like you would call `::attr` methods:
6
+ * pass the name of the arguments as symbols
7
+ * pass options at the end:
8
+ * `attr` : what getters and/or setters to define
9
+ * can be `:accessor`, `:reader`, `:writer` or `:none`
10
+ * defaults to `:accessor`
11
+ * `kw` : if arguments are to be set as keyword arguments
12
+ * defaults to `false`
13
+
14
+ The same options can be used per individual argument.
15
+
16
+ # Requiring
17
+
18
+ ```ruby
19
+ # As a refinement
20
+ require 'trinkets/class/init' # implicit
21
+ # or
22
+ require 'trinkets/refine/class/init' # explicit
23
+
24
+ # As extend
25
+ require 'trinkets/extend/class/init'
26
+
27
+ # As monkey-patch
28
+ require 'trinkets/patch/class/init'
29
+ ```
30
+
31
+ # Examples
32
+
33
+ ## Simple Initialize
34
+ ```ruby
35
+ class Test
36
+ init :a, :b
37
+ end
38
+
39
+ # would be the same as
40
+ class Test
41
+ attr_accessor :a, :b
42
+ def initialize(a, b)
43
+ @a = a
44
+ @b = b
45
+ end
46
+ end
47
+
48
+ test = Test.new(1, 2)
49
+
50
+ test.a
51
+ # 1
52
+
53
+ test.b
54
+ # 2
55
+
56
+ test.a = 3
57
+ # 3
58
+ ```
59
+
60
+ ## Read only access to instance variables
61
+ ```ruby
62
+ class TestAttr
63
+ init :a, :b, attr: :reader
64
+ end
65
+
66
+ # would be the same as
67
+ class TestAttr
68
+ attr_reader :a, :b
69
+ def initialize(a, b)
70
+ @a = a
71
+ @b = b
72
+ end
73
+ end
74
+
75
+ test = TestAttr.new(1, 2)
76
+
77
+ test.a
78
+ # 1
79
+
80
+ test.b
81
+ # 2
82
+
83
+ test.a = 3
84
+ # => raises NoMethodError
85
+ ```
86
+
87
+ ## Initialize uses keyword arguments
88
+ ```ruby
89
+ class TestKW
90
+ init :a, :b, kw: :true
91
+ end
92
+
93
+ # would be the same as
94
+ class TestKW
95
+ attr_accessor :a, :b
96
+ def initialize(a:, b:)
97
+ @a = a
98
+ @b = b
99
+ end
100
+ end
101
+
102
+ test = TestKW.new(a: 1, b: 2)
103
+
104
+ test.a
105
+ # 1
106
+
107
+ test.b
108
+ # 2
109
+ ```
110
+
111
+ ## Individual attribute options
112
+ ```ruby
113
+ class TestAttrOptions
114
+ init [:a, kw: true, attr: :reader],
115
+ :b,
116
+ [:c, kw: true],
117
+ [:d, attr: :none]
118
+ end
119
+
120
+ # would be the same as
121
+ class TestAttrOptions
122
+ attr_reader :a
123
+ attr_accessor :b, :c
124
+ def initialize(b, d, a:, c:)
125
+ @a = a
126
+ @b = b
127
+ @c = c
128
+ @d = d
129
+ end
130
+ end
131
+
132
+ test = TestAttrOptions.new(2, 4, a: 1, c: 3)
133
+
134
+ test.a
135
+ # 1
136
+
137
+ test.b
138
+ # 2
139
+
140
+ test.c
141
+ # 3
142
+
143
+ test.d
144
+ # => raises NoMethodError
145
+
146
+ test.a = 5
147
+ # => raises NoMethodError
148
+ ```
149
+
150
+ ## Mixed together
151
+ ```ruby
152
+ class TestMixed
153
+ init [:a, attr: :reader],
154
+ :b,
155
+ kw: true
156
+ end
157
+
158
+ # would be the same as
159
+ class TestMixed
160
+ attr_reader :a
161
+ attr_accessor :b
162
+ def initialize(a:, b:)
163
+ @a = a
164
+ @b = b
165
+ end
166
+ end
167
+
168
+ test = TestMixed.new(1, 2)
169
+
170
+ test.a
171
+ # 1
172
+
173
+ test.b
174
+ # 2
175
+
176
+ test.b = 3
177
+ # 3
178
+
179
+ test.a = 4
180
+ # => raises NoMethodError
181
+ ```
@@ -0,0 +1,47 @@
1
+ # Description
2
+
3
+ It defines `Enumerable#each_with_hash`, which is a simple wrapper for `Enumerable#each_with_object({})`.
4
+
5
+ It also includes the alias `Enumerator#with_hash(&)`.
6
+
7
+ # Requiring
8
+
9
+ ```ruby
10
+ # As a refinement
11
+ require 'trinkets/enumerable/each_with_hash' # implicit
12
+ # or
13
+ require 'trinkets/refine/enumerable/each_with_hash' # explicit
14
+
15
+ # As include
16
+ require 'trinkets/include/enumerable/each_with_hash'
17
+
18
+ # As monkey-patch
19
+ require 'trinkets/patch/enumerable/each_with_hash'
20
+ ```
21
+
22
+ # Examples
23
+
24
+ These examples are all equivalent.
25
+
26
+ ```ruby
27
+ [2, 3, 4, 5].each_with_hash { |value, hash| hash[value] = value * value }
28
+ # => {2=>4, 3=>9, 4=>16, 5=>25}
29
+
30
+ [2, 3, 4, 5].each_with_hash
31
+ # => #<Enumerator: [2, 3, 4, 5]:each_with_object({})>
32
+ ```
33
+
34
+ ```ruby
35
+ [2, 3, 4, 5].each
36
+ .with_hash { |value, hash| hash[value] = value * value }
37
+
38
+ # => {2=>4, 3=>9, 4=>16, 5=>25}
39
+ ```
40
+
41
+ ```ruby
42
+ [2, 3, 4, 5].each
43
+ .with_hash
44
+ .each { |value, hash| hash[value] = value * value }
45
+
46
+ # => {2=>4, 3=>9, 4=>16, 5=>25}
47
+ ```
@@ -3,11 +3,11 @@
3
3
  module Trinkets
4
4
  module Class
5
5
  module Init
6
- ATTR = %i[accessor reader writer].freeze
6
+ ATTR = %i[accessor reader writer none].freeze
7
7
 
8
8
  def init(*attrs, attr: ATTR.first, kw: false)
9
9
  raise ArgumentError, 'At least 1 attribute is required.' if attrs.empty?
10
- raise ArgumentError, '`attr` must be one of :accessor (default), :reader or :writer' unless ATTR.include?(attr)
10
+ raise ArgumentError, '`attr` must be one of :accessor (default), :reader, :writer or :none' unless ATTR.include?(attr)
11
11
 
12
12
  default_attr_options = { attr: attr, kw: kw }
13
13
 
@@ -22,7 +22,7 @@ module Trinkets
22
22
  h[name] = opts
23
23
  end
24
24
 
25
- attr_methods = ATTR
25
+ attr_methods = (ATTR - [:none])
26
26
  .each_with_object({}) do |name, h|
27
27
  h[name] = method("attr_#{name}")
28
28
  end
@@ -30,9 +30,9 @@ module Trinkets
30
30
  # even though options like `kw` aren't used, they serve here to validate the `attrs` options
31
31
  attr_init = ->(name, attr: ATTR.first, kw: false) do
32
32
  unless ATTR.include?(attr)
33
- raise ArgumentError, "attr `#{name}`, option attr` must be one of :accessor (default), :reader or :writer"
33
+ raise ArgumentError, "attr `#{name}`, option attr` must be one of :accessor (default), :reader, :writer or :none"
34
34
  end
35
- attr_methods[attr].call(name)
35
+ attr_methods[attr].call(name) unless attr == :none
36
36
  end
37
37
 
38
38
  attrs.each { |name, opts| attr_init.call(name, **opts) }
@@ -0,0 +1,14 @@
1
+ module Trinkets
2
+
3
+ module Enumerable
4
+ module WithHash
5
+ def each_with_hash(&) = each_with_object({}, &)
6
+ end
7
+ end
8
+
9
+ module Enumerator
10
+ module WithHash
11
+ def with_hash(&) = each_with_hash(&)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../../include/enumerable/each_with_hash'
2
+
3
+ module ::Enumerable
4
+ include ::Trinkets::Enumerable::WithHash
5
+ end
6
+
7
+ class ::Enumerator
8
+ include ::Trinkets::Enumerator::WithHash
9
+ end
@@ -0,0 +1,15 @@
1
+ require_relative '../../include/enumerable/each_with_hash'
2
+
3
+ module Trinkets
4
+ module Enumerable
5
+ module WithHash
6
+ refine ::Enumerable do
7
+ import_methods ::Trinkets::Enumerable::WithHash
8
+ end
9
+
10
+ refine ::Enumerator do
11
+ import_methods ::Trinkets::Enumerator::WithHash
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ require_relative '../../../explicit/trinkets/refine/class/init'
@@ -0,0 +1 @@
1
+ require_relative '../../../explicit/trinkets/refine/enumerable/each_with_hash'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Trinkets
4
- VERSION = "0.1.0"
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trinkets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SilverPhoenix99
@@ -9,9 +9,9 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-01-28 00:00:00.000000000 Z
12
+ date: 2024-02-03 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: Truly outrageous trinkets.
14
+ description: Truly outrageous bootleg facets in your trinkets box.
15
15
  email:
16
16
  - antoniopedrosilvapinto@gmail.com
17
17
  - pedro.at.miranda@gmail.com
@@ -19,40 +19,44 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
- - ".rspec"
23
22
  - CHANGELOG.md
24
23
  - LICENSE.txt
25
24
  - README.md
26
- - Rakefile
27
25
  - doc/class/init.md
28
- - lib/trinkets.rb
29
- - lib/trinkets/extend/class/init.rb
30
- - lib/trinkets/patch/class/init.rb
31
- - lib/trinkets/refine/class/init.rb
26
+ - doc/enumerable/each_with_hash.md
27
+ - lib/explicit/trinkets/extend/class/init.rb
28
+ - lib/explicit/trinkets/include/enumerable/each_with_hash.rb
29
+ - lib/explicit/trinkets/patch/class/init.rb
30
+ - lib/explicit/trinkets/patch/enumerable/each_with_hash.rb
31
+ - lib/explicit/trinkets/refine/class/init.rb
32
+ - lib/explicit/trinkets/refine/enumerable/each_with_hash.rb
33
+ - lib/implicit/trinkets/class/init.rb
34
+ - lib/implicit/trinkets/enumerable/each_with_hash.rb
32
35
  - lib/trinkets/version.rb
33
- - trinkets.gemspec
34
- homepage: http://nowhere.example.com
36
+ homepage: https://github.com/SilverPhoenix99/trinkets
35
37
  licenses:
36
38
  - MIT
37
39
  metadata:
38
- homepage_uri: http://nowhere.example.com
40
+ homepage_uri: https://github.com/SilverPhoenix99/trinkets
39
41
  post_install_message:
40
42
  rdoc_options: []
41
43
  require_paths:
42
- - lib
44
+ - lib/explicit
45
+ - lib/implicit
46
+ - lib/trinkets
43
47
  required_ruby_version: !ruby/object:Gem::Requirement
44
48
  requirements:
45
49
  - - ">="
46
50
  - !ruby/object:Gem::Version
47
- version: 3.2.0
51
+ version: 3.1.0
48
52
  required_rubygems_version: !ruby/object:Gem::Requirement
49
53
  requirements:
50
54
  - - ">="
51
55
  - !ruby/object:Gem::Version
52
56
  version: '0'
53
57
  requirements: []
54
- rubygems_version: 3.5.3
58
+ rubygems_version: 3.5.5
55
59
  signing_key:
56
60
  specification_version: 4
57
- summary: Trinkets in your box.
61
+ summary: Bootleg facets, with new trinkets.
58
62
  test_files: []
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
data/lib/trinkets.rb DELETED
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'trinkets/version'
data/trinkets.gemspec DELETED
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'lib/trinkets/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'trinkets'
7
- spec.version = Trinkets::VERSION
8
- spec.authors = %w[SilverPhoenix99 P3t3rU5]
9
- spec.email = %w[antoniopedrosilvapinto@gmail.com pedro.at.miranda@gmail.com]
10
-
11
- spec.summary = 'Trinkets in your box.'
12
- spec.description = 'Truly outrageous trinkets.'
13
- spec.homepage = 'http://nowhere.example.com'
14
- spec.license = 'MIT'
15
- spec.required_ruby_version = '>= 3.2.0'
16
-
17
- # spec.metadata['allowed_push_host'] = 'TODO: Set to your gem server "https://example.com"'
18
-
19
- spec.metadata['homepage_uri'] = spec.homepage
20
- # spec.metadata['source_code_uri'] = "TODO: Put your gem's public repo URL here."
21
- # spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
22
-
23
- # Specify which files should be added to the gem when it is released.
24
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
- spec.files = Dir.chdir(__dir__) do
26
- `git ls-files -z`.split("\x0").reject do |f|
27
- (File.expand_path(f) == __FILE__) ||
28
- f.start_with?(*%w[bin/ test/ spec/ features/ .git appveyor Gemfile])
29
- end
30
- end
31
- spec.require_paths = ['lib']
32
- end