phlex-slotable 0.3.1 → 0.4.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: 7ed2552d628d6851db0da87a5105818d55b5a28bda04d7b5dd9dc0f6fe7357a5
4
- data.tar.gz: dd6b66cb419fae64ee1ea963670735a3773a6d1c26bf18c2cc1be01ad43e559b
3
+ metadata.gz: 47c3384e49460492a4ff914af1ecd7c6a16fa2841f90d49a4b83b84c305cf892
4
+ data.tar.gz: aed5afef686e5f630b98842de12b18cc9f5634dd9f099b07273a7aa281f2915a
5
5
  SHA512:
6
- metadata.gz: 0aafc0d75f3907534255f8ffdc8800e8541373884c5e149afc12dfd5f1e811644c6f037ec32640501f8faec83dace3ea6368c6a17c51fe88b2e27557813f4b70
7
- data.tar.gz: a5d11b19a175d1228c0ec7561986dbec0f0a976829b0b0300d599c15d32e801d9afcd4fd2dabdd3a180efccf2f12bde9673ee84744c712fa9aca7b77f3a8e412
6
+ metadata.gz: 02c8d0105b65526025feea5fe1aadd7851a96e8406ccb574c0b7bb45d732e54dc85c98f6fbb182af5f57ae8f404cbe17a879bafad42ef6ce9ecd0c168c286d75
7
+ data.tar.gz: 76a8bfd794fd7a7040bf1699db0dd3001f9d7de0cac0f641515494307a3cb370ab173588e2ba3610553c601f907d1da3990d5580702c1308c008e6d2ce11a327
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2024-02-14
4
+ - [BREAKING CHANGE] Rename `many` option to `collection`.
5
+
6
+ *stephannv*
7
+
8
+ - Improve generic slot performance
9
+
10
+ *stephannv*
11
+
3
12
  ## [0.3.1] - 2024-02-14
4
13
  - Support Ruby 2.7
5
14
 
data/README.md CHANGED
@@ -6,7 +6,21 @@
6
6
 
7
7
  Phlex::Slotable enables slots feature to [Phlex](https://www.phlex.fun/) views. Inspired by ViewComponent.
8
8
 
9
- ## Installation
9
+ - [What is a slot?](#what-is-a-slot)
10
+ - [Getting started](#getting-started)
11
+ - [Generic slot](#generic-slot)
12
+ - [Slot collection](#slot-collection)
13
+ - [Component slot](#component-slot)
14
+ - [Lambda slot](#lambda-slot)
15
+ - [Polymorphic slot](#polymorphic-slot)
16
+ - [Development](#development)
17
+ - [Contributing](#contributing)
18
+
19
+ ## What is a slot?
20
+
21
+ In the context of view components, a **slot** serves as a placeholder inside a component that can be filled with custom content. Essentially, slots enable a component to accept external content and autonomously organize it within its structure. This abstraction allows developers to work with components without needing to understand their internals, thereby ensuring visual consistency and improving developer experience.
22
+
23
+ ## Getting started
10
24
 
11
25
  Install the gem and add to the application's Gemfile by executing:
12
26
 
@@ -16,268 +30,272 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
30
 
17
31
  $ gem install phlex-slotable
18
32
 
19
- ## Usage
33
+ > [!TIP]
34
+ > If you prefer not to add another dependency to your project, you can simply copy the [Phlex::Slotable](https://github.com/stephannv/phlex-slotable/blob/main/lib/phlex/slotable.rb) file into your project.
35
+
36
+ Afterward, simply include `Phlex::Slotable` into your Phlex component and utilize `slot` macro to define the component's slots. For example:
37
+
38
+ ```ruby
39
+ class MyComponent < Phlex::HTML
40
+ include Phlex::Slotable
41
+
42
+ slot :my_slot
43
+ end
44
+ ```
20
45
 
21
- #### Basic
46
+ Below, you will find a more detailed explanation of how to use the `slot` API.
22
47
 
23
- To incorportate slots into your Phlex views, include `Phlex::Slotable` and utilize `slot` class method to define them.
48
+ ## Generic slot
24
49
 
25
- - `slot :slot_name` declaration establishes a single slot intended for rendering once within a view
26
- - `slot :slot_name, many: true` denotes a slot capable of being rendered multiple times within a view
50
+ Any content can be passed to components through generic slots, also known as passthrough slots. To define a generic slot, use `slot :{slot_name}`. For example:
27
51
 
28
52
  ```ruby
29
- class BlogComponent < Phlex::HTML
53
+ class PageComponent < Phlex::HTML
30
54
  include Phlex::Slotable
31
55
 
32
- slot :header
33
- slot :post, many: true
34
-
35
- # ...
56
+ slot :title
36
57
  end
37
58
  ```
38
59
 
39
- To render a single slot, utilize the `{slot_name}_slot` method. For example, you can render the `header_slot` using `render header_slot`.
40
-
41
- For multi-slot rendering, iterate over the `{slot_name}_slots` collection and and render each slot individually, eg. `post_slots.each { |s| render s }`.
60
+ To render a slot, render the `{slot_name}_slot`:
42
61
 
43
62
  ```ruby
44
- class BlogComponent < Phlex::HTML
63
+ class PageComponent < Phlex::HTML
45
64
  include Phlex::Slotable
46
65
 
47
- slot :header
48
- slot :post, many: true
66
+ slot :title
49
67
 
50
68
  def template
51
- div id: "header" do
52
- render header_slot
53
- end
69
+ header { render title_slot }
70
+ end
71
+ end
72
+ ```
54
73
 
55
- div id: "main" do
56
- post_slots.each do |slot|
57
- p { render slot }
58
- end
74
+ To pass content to the component's slot, you should use `with_{slot_name}`:
59
75
 
60
- span { "Count: #{post_slots.count}" }
61
- end
76
+ ```ruby
77
+ PageComponent.new.call do |page|
78
+ page.with_title do
79
+ h1 { "Hello World!" }
62
80
  end
63
81
  end
64
82
  ```
65
83
 
66
- When setting slot content, ensure to utilize the `with_{slot_name}` method while rendering the view:
84
+ Returning:
85
+
86
+ ```html
87
+ <header>
88
+ <h1>Hello World!</h1>
89
+ </header>
90
+ ```
91
+
92
+ You can test if a slot has been passed to the component with `{slot_name}_slot?` method. For example:
67
93
 
68
94
  ```ruby
69
- class MyPage < Phlex::HTML
70
- def template
71
- render BlogComponent.new do |blog|
72
- blog.with_header do
73
- h1 { "Hello World!" }
74
- end
95
+ class PageComponent < Phlex::HTML
96
+ include Phlex::Slotable
97
+
98
+ slot :title
75
99
 
76
- blog.with_post { "Post A" }
77
- blog.with_post { "Post B" }
78
- blog.with_post { "Post C" }
100
+ def template
101
+ if header_slot?
102
+ header { render title_slot }
103
+ else
104
+ plain "No title"
79
105
  end
80
106
  end
81
107
  end
82
-
83
- MyPage.new.call
84
108
  ```
85
109
 
86
- This will output:
110
+ ## Slot collection
87
111
 
88
- ```html
89
- <div id="header">
90
- <h1>Hello World</h1>
91
- </div>
92
- <div id="main">
93
- <p>Post A</p>
94
- <p>Post B</p>
95
- <p>Post C</p>
112
+ A slot collection denotes a slot capable of being rendered multiple times within a component. It has some minor differences compared to a single slot seen previously. First, you should pass `collection: true` when defining the slot:
96
113
 
97
- <span>Count: 3</span>
98
- </div>
99
- ```
114
+ ```ruby
115
+ class ListComponent < Phlex::HTML
116
+ include Phlex::Slotable
100
117
 
101
- #### Predicate methods
118
+ slot :item, collection: true
119
+ end
120
+ ```
102
121
 
103
- You can verify whether a slot has been provided to the view using `{slot_name}_slot?` for single slots or `{slot_name}_slots?` when for multi-slots.
122
+ To render a collection of slots, iterate over the `{slot_name}_slots` collection and render each slot individually:
104
123
 
105
124
  ```ruby
106
- class BlogComponent < Phlex::HTML
107
- include Phlex::Slotable
125
+ class ListComponent < Phlex::HTML
126
+ include Phlex::Slotable
108
127
 
109
- slot :header
110
- slot :post, many: true
128
+ slot :item, collection: true
111
129
 
112
130
  def template
113
- if header_slot?
114
- div id: "header" do
115
- render header_slot
116
- end
117
- end
118
-
119
- div id: "main" do
120
- if post_slots?
121
- post_slots.each do |slot|
122
- p { render slot }
131
+ if item_slots?
132
+ ul do
133
+ item_slots.each do |item_slot|
134
+ li { render item_slot }
123
135
  end
124
-
125
- span { "Count: #{post_slots.count}" }
126
- else
127
- span { "No post yet" }
128
136
  end
129
137
  end
138
+
139
+ span { "Total: #{item_slots.size}" }
130
140
  end
131
141
  end
132
142
  ```
133
143
 
134
- #### View slot
135
-
136
- Slots have the capability to render other views, Simply pass the view class name to the `slot` method.
144
+ To set slot content, use the `with_{slot_name}` method when rendering the component. Unlike the single slot, `with_{slot_name}` can be called multiple times:
137
145
 
138
146
  ```ruby
139
- class HeaderComponent < Phlex::HTML
140
- def initialize(size:)
141
- @size = size
142
- end
143
-
144
- def template(&content)
145
- h1(class: "text-#{@size}", &content)
146
- end
147
+ ListComponent.new.call do |list|
148
+ list.with_item { "Item A" }
149
+ list.with_item { "Item B" }
150
+ list.with_item { "Item C" }
147
151
  end
152
+ ```
148
153
 
149
- class PostComponent < Phlex::HTML
150
- def initialize(featured:)
151
- @featured = featured
152
- end
154
+ Returning:
153
155
 
154
- def template(&content)
155
- p(class: @featured ? "featured" : nil, &content)
156
- end
156
+ ```html
157
+ <ul>
158
+ <li>Item A</li>
159
+ <li>Item B</li>
160
+ <li>Item C</li>
161
+ </ul>
162
+
163
+ <span>Total: 3</span>
164
+ ```
165
+
166
+ ## Component slot
167
+
168
+ Slots have the capability to render other components. When defining a slot, provide the name of a component class as the second argument to define a component slot
169
+
170
+ ```ruby
171
+ class ListHeaderComponent < Phlex::HTML
172
+ # omitted code
157
173
  end
158
174
 
159
- class BlogComponent < Phlex::HTML
175
+ class ListItemComponent < Phlex::HTML
176
+ # omitted code
177
+ end
178
+
179
+ class ListComponent < Phlex::HTML
160
180
  include Phlex::Slotable
161
181
 
162
- slot :header, HeaderComponent
163
- slot :post, PostComponent, many: true
182
+ slot :header, ListHeaderComponent
183
+ slot :item, ListItemComponent, collection: true
164
184
 
165
185
  def template
166
- if header_slot?
167
- div id: "header" do
168
- render header_slot
169
- end
186
+ div id: "header" do
187
+ render header_slot if header_slot?
170
188
  end
171
189
 
172
- div id: "main" do
173
- if post_slots?
174
- post_slots.each { render slot }
175
-
176
- span { "Count: #{post_slots.count}" }
177
- else
178
- span { "No post yet" }
179
- end
190
+ ul do
191
+ item_slots.each { |slot| render slot }
180
192
  end
181
193
  end
182
194
  end
183
195
 
184
- class MyPage < Phlex::HTML
185
- def template
186
- render BlogComponent.new do |blog|
187
- blog.with_header(size: :lg) { "Hello World!" }
196
+ ListComponent.new.call do |list|
197
+ list.with_header(size: "lg") { "Hello World!" }
188
198
 
189
- blog.with_post(featured: true) { "Post A" }
190
- blog.with_post { "Post B" }
191
- blog.with_post { "Post C" }
192
- end
193
- end
199
+ list.with_item(active: true) { "Item A" }
200
+ list.with_item { "Item B" }
201
+ list.with_item { "Item C" }
194
202
  end
195
-
196
- MyPage.new.call
197
203
  ```
198
204
 
199
- The output:
205
+ Returning:
200
206
 
201
207
  ```html
202
208
  <div id="header">
203
- <h1 class="text-lg">Hello World</h1>
204
- </div>
205
- <div id="main">
206
- <p class="featured">Post A</p>
207
- <p>Post B</p>
208
- <p>Post C</p>
209
+ <h1 class="text-lg">Hello World!</h1>
209
210
 
210
- <span>Count: 3</span>
211
+ <ul>
212
+ <li class="active">Item A</li>
213
+ <li>Item B</li>
214
+ <li>Item C</li>
215
+ </ul>
211
216
  </div>
212
217
  ```
213
218
 
214
- You can pass the class name as a string for cases where the class isn't evaluated yet, such as with inner classes. For example:
215
- ```ruby
216
- class BlogComponent < Phlex::HTML
217
- include Phlex::Slotable
219
+ > [!TIP]
220
+ > You can also pass the component class as a string if your component class hasn't been defined yet. For example:
221
+ >
222
+ > ```ruby
223
+ > slot :header, "HeaderComponent"
224
+ > slot :item, "ItemComponent", collection: true
225
+ >```
218
226
 
219
- # This will not work
220
- slot :header, HeaderComponent # uninitialized constant BlogComponent::HeaderComponent
221
- # You should do this
222
- slot :header, "HeaderComponent"
223
227
 
224
- private
228
+ ## Lambda slot
225
229
 
226
- class HeaderComponent < Phlex::HTML
227
- # ...
228
- end
229
- end
230
- ```
230
+ Lambda slots are valuable when you prefer not to create another component for straightforward structures or when you need to render another component with specific parameters.
231
231
 
232
- #### Lambda slots
233
- Lambda slots are valuable when you prefer not to create another component for straightforward structures or when you need to render another view with specific parameters
234
232
  ```ruby
235
-
236
- class BlogComponent < Phlex::HTML
233
+ class ListComponent < Phlex::HTML
237
234
  include Phlex::Slotable
238
235
 
239
- slot :header, ->(size:, &content) { render HeaderComponent.new(size: size, color: "blue"), &content }
240
- slot :post, ->(featured:, &content) { span(class: featured ? "featured" : nil, &content) }, many: true
241
- end
236
+ slot :header, ->(size:, &content) do
237
+ render HeaderComponent.new(size: size, color: "primary")
238
+ end
239
+ slot :item, ->(href:, &content) { li { a(href: href, &content) } }, collection: true
242
240
 
243
- class MyPage < Phlex::HTML
244
241
  def template
245
- render BlogComponent.new do |blog|
246
- blog.with_header(size: :lg) { "Hello World!" }
242
+ div id: "header" do
243
+ render header_slot if header_slot?
244
+ end
247
245
 
248
- blog.with_post(featured: true) { "Post A" }
249
- blog.with_post { "Post B" }
250
- blog.with_post { "Post C" }
246
+ ul do
247
+ item_slots.each { |slot| render slot }
251
248
  end
252
249
  end
253
250
  end
254
- ```
255
-
256
- You can access the internal view state within lambda slots. For example:
257
- ```ruby
258
- class BlogComponent < Phlex::HTML
259
- include Phlex::Slotable
260
251
 
261
- slot :header, ->(size:, &content) { render HeaderComponent.new(size: size, color: @header_color), &content }
252
+ ListComponent.new.call do |list|
253
+ list.with_header(size: "lg") { "Hello World!" }
262
254
 
263
- def initialize(header_color:)
264
- @header_color = header_color
265
- end
255
+ list.with_item(href: "/a") { "Item A" }
256
+ list.with_item(href: "/b") { "Item B" }
257
+ list.with_item(href: "/c") { "Item C" }
266
258
  end
259
+ ```
267
260
 
268
- class MyPage < Phlex::HTML
269
- def template
270
- render BlogComponent.new(header_color: "red") do |blog|
271
- blog.with_header(size: :lg) { "Hello World!" }
272
- end
273
- end
274
- end
261
+ Returning:
262
+
263
+ ```html
264
+ <div id="header">
265
+ <h1 class="text-lg text-primary">Hello World!</h1>
266
+
267
+ <ul>
268
+ <li><a href="/a">Item A</a></li>
269
+ <li><a href="/b">Item B</a></li>
270
+ <li><a href="/c">Item C</a></li>
271
+ </ul>
272
+ </div>
275
273
  ```
276
274
 
277
- #### Polymorphic slots
278
- Polymorphic slots can render one of several possible slots, allowing for flexibility in component content. This feature is particularly useful when you require a fixed structure but need to accommodate different types of content. To implement this, simply pass a types hash containing the types along with corresponding slot definitions.
275
+ > [!TIP]
276
+ > You can access the internal component state within lambda slots. For example
277
+ >
278
+ > ```ruby
279
+ > slot :header, ->(&content) { render HeaderComponent.new(featured: @featured), &content }
280
+ >
281
+ > def initialize(featured:)
282
+ > @featured = feature
283
+ > end
284
+ > ```
285
+
286
+ ## Polymorphic slot
287
+
288
+ Polymorphic slots can render one of several possible slots, allowing for flexibility in component content. This feature is particularly useful when you require a fixed structure but need to accommodate different types of content. To implement this, simply pass a types hash containing the types along with corresponding slot definitions.
279
289
 
280
290
  ```ruby
291
+ class IconComponent < Phlex::HTML
292
+ # omitted code
293
+ end
294
+
295
+ class ImageComponent < Phlex::HTML
296
+ # omitted code
297
+ end
298
+
281
299
  class CardComponent < Phlex::HTML
282
300
  include Phlex::Slotable
283
301
 
@@ -285,73 +303,45 @@ class CardComponent < Phlex::HTML
285
303
 
286
304
  def template
287
305
  if avatar_slot?
288
- figure id: "avatar" do
289
- render avatar_slot
306
+ div id: "avatar" do
307
+ render avatar_slot
290
308
  end
291
309
  end
292
310
  end
293
311
  end
294
- ```
295
312
 
296
- This allows you to set the icon slot using `with_icon_avatar` or the image slot using `with_image_avatar`:
297
- ```ruby
298
- class UserCardComponent < Phlex::HTML
299
- def initialize(user:)
300
- @user = user
301
- end
313
+ User = Data.define(:image_url)
314
+ user = User.new(image_url: "user.png")
302
315
 
303
- def template
304
- render CardComponent.new do |card|
305
- if @user.image?
306
- card.with_image_avatar(src: @user.image)
307
- else
308
- card.with_icon_avatar(name: :user)
309
- end
310
- end
316
+ CardComponent.new.call do |card|
317
+ if user.image_url
318
+ card.with_image_avatar(src: user.image_url)
319
+ else
320
+ card.with_icon_avatar(name: :user)
311
321
  end
312
322
  end
313
323
  ```
314
324
 
315
- Please note that you can still utilize the other slot definition APIs:
316
- ```ruby
317
- class CardComponent < Phlex::HTML
318
- include Phlex::Slotable
319
-
320
- slot :avatar, types: {
321
- icon: IconComponent,
322
- image: "ImageComponent",
323
- text: ->(size:, &content) { span(class: "text-#{size}", &content) }
324
- }, many: true
325
-
326
- def template
327
- if avatar_slots?
328
- avatar_slots.each do |slot|
329
- render slot
330
- end
331
- end
332
-
333
- span { "Count: #{avatar_slots.size}" }
334
- end
325
+ Returning:
335
326
 
336
- ...
337
- end
338
-
339
- class UsersCardComponent < Phlex::HTML
340
- def template
341
- render CardComponent.new do |card|
342
- card.with_image_avatar(src: @user.image)
343
- card.with_icon_avatar(name: :user)
344
- card.with_text_avatar(size: :lg) { "SV" }
345
- end
346
- end
347
- end
327
+ ```html
328
+ <div id="avatar">
329
+ <img src="user.png"/>
330
+ </div>
348
331
  ```
349
332
 
333
+ Note that you need to use `with_{type}_{slot_name}` to set slot content. In the example above, it was used `with_image_avatar` and `with_icon_avatar`.
350
334
 
351
- ## Roadmap
352
- - ~~Accept Strings as view class name~~
353
- - ✅ ~~Allow lambda slots~~
354
- - ✅ ~~Allow polymorphic slots~~
335
+ > [!TIP]
336
+ > You can take advantage of all the previously introduced features, such as lambda slot and slot collection:
337
+ >
338
+ > ```ruby
339
+ > slot :avatar, collection: true, types: {
340
+ > icon: IconComponent,
341
+ > image: "ImageComponent",
342
+ > text: ->(&content) { span(class: "avatar", &content) }
343
+ > }
344
+ > ```
355
345
 
356
346
  ## Development
357
347
 
@@ -361,7 +351,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
361
351
 
362
352
  ## Contributing
363
353
 
364
- Bug reports and pull requests are welcome on GitHub at https://github.com/stephannv/phlex-slot. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/stephannv/phlex-slotable/blob/master/CODE_OF_CONDUCT.md).
354
+ Bug reports and pull requests are welcome on GitHub at https://github.com/stephannv/phlex-slotable. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/stephannv/phlex-slotable/blob/master/CODE_OF_CONDUCT.md).
365
355
 
366
356
  ## License
367
357
 
data/benchmark/main.rb CHANGED
@@ -34,7 +34,7 @@ class SlotableList < Phlex::HTML
34
34
  include Phlex::Slotable
35
35
 
36
36
  slot :header
37
- slot :item, many: true
37
+ slot :item, collection: true
38
38
 
39
39
  def template
40
40
  if header_slot
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlex
4
4
  module Slotable
5
- VERSION = "0.3.1"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
@@ -9,35 +9,36 @@ module Phlex
9
9
  end
10
10
 
11
11
  module ClassMethods
12
- def slot(slot_name, callable = nil, types: nil, many: false)
12
+ def slot(slot_name, callable = nil, types: nil, collection: false)
13
13
  include Phlex::DeferredRender
14
14
 
15
15
  if types
16
16
  types.each do |type, callable|
17
- define_setter_method(slot_name, callable, many: many, type: type)
17
+ define_setter_method(slot_name, callable, collection: collection, type: type)
18
18
  end
19
19
  else
20
- define_setter_method(slot_name, callable, many: many)
20
+ define_setter_method(slot_name, callable, collection: collection)
21
21
  end
22
- define_predicate_method(slot_name, many: many)
23
- define_getter_method(slot_name, many: many)
22
+ define_predicate_method(slot_name, collection: collection)
23
+ define_getter_method(slot_name, collection: collection)
24
24
  end
25
25
 
26
26
  private
27
27
 
28
- def define_setter_method(slot_name, callable, many:, type: nil)
28
+ def define_setter_method(slot_name, callable, collection:, type: nil)
29
29
  slot_name_with_type = type ? "#{type}_#{slot_name}" : slot_name
30
+ signature = callable.nil? ? "(&block)" : "(*args, **kwargs, &block)"
30
31
 
31
- setter_method = if many
32
+ setter_method = if collection
32
33
  <<-RUBY
33
- def with_#{slot_name_with_type}(*args, **kwargs, &block)
34
+ def with_#{slot_name_with_type}#{signature}
34
35
  @#{slot_name}_slots ||= []
35
36
  @#{slot_name}_slots << #{callable_value(slot_name_with_type, callable)}
36
37
  end
37
38
  RUBY
38
39
  else
39
40
  <<-RUBY
40
- def with_#{slot_name_with_type}(*args, **kwargs, &block)
41
+ def with_#{slot_name_with_type}#{signature}
41
42
  @#{slot_name}_slot = #{callable_value(slot_name_with_type, callable)}
42
43
  end
43
44
  RUBY
@@ -52,8 +53,8 @@ module Phlex
52
53
  private :"__call_#{slot_name}__"
53
54
  end
54
55
 
55
- def define_getter_method(slot_name, many:)
56
- getter_method = if many
56
+ def define_getter_method(slot_name, collection:)
57
+ getter_method = if collection
57
58
  <<-RUBY
58
59
  def #{slot_name}_slots
59
60
  @#{slot_name}_slots ||= []
@@ -72,8 +73,8 @@ module Phlex
72
73
  class_eval(getter_method, __FILE__, __LINE__ + 1)
73
74
  end
74
75
 
75
- def define_predicate_method(slot_name, many:)
76
- predicate_method = if many
76
+ def define_predicate_method(slot_name, collection:)
77
+ predicate_method = if collection
77
78
  <<-RUBY
78
79
  def #{slot_name}_slots?
79
80
  #{slot_name}_slots.any?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlex-slotable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - stephann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-14 00:00:00.000000000 Z
11
+ date: 2024-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex