portrayal 0.7.0 → 0.7.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbd0b561e866c45f6e850b592620df78d4573635165807cd2284ab45baed9e0c
4
- data.tar.gz: 699be912aa836a55faa10886a3a1c1bb7b17c006f1db445694660d2fbe0ec0f4
3
+ metadata.gz: afdba4b2e460ce31fb430639e1270683d61d2b41bcb276a056e042ac8de8c61d
4
+ data.tar.gz: 39f66cc7e9224d04660d3cc1e1317f9c66752e2fd739eeb9068f10751275f9f8
5
5
  SHA512:
6
- metadata.gz: 58fc168ad299aee9555ec7e1a1355f533c65af5ff1620095a7e49829252b39e92f45714083cc03fd1cde2ccc027acabd98b3526618caae07fb226be7e294694b
7
- data.tar.gz: 8d59938b7bdcc5b9a32683695b6146186cb12bf6132326ecfff5b01685b7740dbf78ef513a43fbf5ff58716c38848881229600e4eb2f059dc13efc530120d68d
6
+ metadata.gz: 894bcfa84622297c663f9fa88c4f829a8475fa092caff07d047768adef1a110e5726747f53a284e6d823c57ead388a14fc4e5d0bb68342c463a170a725fa9442
7
+ data.tar.gz: 19dc417df48b783a7847957fdc8899c143b0e92ac4aaef35f1b07342d7d02fbea1091d504d9d47318c7baee0cf538616209555903307f5e8aace2267fd777fce
@@ -1,24 +1,18 @@
1
1
  name: RSpec
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
- pull_request:
7
- branches: [ main ]
8
-
2
+ on: [push, pull_request]
9
3
  jobs:
10
4
  test:
11
5
  runs-on: ubuntu-latest
12
6
  strategy:
7
+ fail-fast: false
13
8
  matrix:
14
- ruby: [ '2.4', '2.5', '2.6', '2.7' ]
9
+ ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
15
10
 
16
11
  name: Ruby ${{ matrix.ruby }}
17
12
  steps:
18
13
  - uses: actions/checkout@v2
19
- - uses: actions/setup-ruby@v1
14
+ - uses: ruby/setup-ruby@v1
20
15
  with:
21
16
  ruby-version: ${{ matrix.ruby }}
22
- - run: gem install bundler
23
- - run: bundle install
17
+ bundler-cache: true
24
18
  - run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.7.1 - 2021-03-22
6
+
7
+ * Fix default procs' behavior when overriding keywords in subclasses. Portrayal relies on an ordered ruby hash to initialize keywords in the correct order. However, if overriding the same keyword in a subclass (by declaring it again), it didn't move keyword to the bottom of the hash, so this would happen:
8
+
9
+ ```ruby
10
+ class Person
11
+ extend Portrayal
12
+ keyword :email, default: nil
13
+ end
14
+
15
+ class Employee < Person
16
+ keyword :employee_id
17
+ keyword :email, default: proc { "#{employee_id}@example.com" }
18
+ end
19
+
20
+ employee = Employee.new(employee_id: '1234')
21
+ employee.email # => "@example.com"
22
+ ```
23
+
24
+ The email is broken because it relies on having employee_id declared before email, but email was already declared first in the superclass. This change fixes situations like this by re-adding the keyword to the bottom of the hash on every re-declaration.
25
+
5
26
  ## 0.7.0 - 2020-12-13
6
27
 
7
28
  * **Breaking change:** Remove `optional` setting. To update find all `optional: true` and change to `default: nil` instead.
data/README.md CHANGED
@@ -263,6 +263,50 @@ end
263
263
 
264
264
  This defines `Person::Country`, while the accessor remains `visited_countries`.
265
265
 
266
+ ### Subclassing
267
+
268
+ Portrayal supports subclassing.
269
+
270
+ ```ruby
271
+ class Person
272
+ extend Portrayal
273
+
274
+ class << self
275
+ def from_contact(contact)
276
+ new name: contact.full_name,
277
+ address: contact.address.to_s,
278
+ email: contact.email
279
+ end
280
+ end
281
+
282
+ keyword :name
283
+ keyword :address
284
+ keyword :email, default: nil
285
+ end
286
+ ```
287
+
288
+ ```ruby
289
+ class Employee < Person
290
+ keyword :employee_id
291
+ keyword :email, default: proc { "#{employee_id}@example.com" }
292
+ end
293
+ ```
294
+
295
+ Now when you call `Employee.new` it will accept keywords of both superclass and subclass. You can also see how `email`'s default is overridden in the subclass.
296
+
297
+ However, if you try calling `Employee.from_contact(contact)` it will error out, because that constructor doesn't set an `employee_id` required in the subclass. You can remedy that with a small change.
298
+
299
+ ```ruby
300
+ def from_contact(contact, **kwargs)
301
+ new name: contact.full_name,
302
+ address: contact.address.to_s,
303
+ email: contact.email,
304
+ **kwargs
305
+ end
306
+ ```
307
+
308
+ If you add `**kwargs` to `Person.from_contact` and pass them through to new, then you are now able to call `Employee.from_contact(contact, employee_id: 'some_id')`
309
+
266
310
  ### Schema
267
311
 
268
312
  Every class that has at least one keyword defined in it automatically receives a class method called `portrayal`. This method is a schema of your object with some additional helpers.
@@ -46,7 +46,9 @@ module Portrayal
46
46
  def camelize(string); string.to_s.gsub(/(?:^|_+)([^_])/) { $1.upcase } end
47
47
 
48
48
  def add_keyword(name, default)
49
- @schema[name.to_sym] = default.equal?(NULL) ? nil : Default.new(default)
49
+ name = name.to_sym
50
+ @schema.delete(name) # Forcing keyword to be added at the end of the hash.
51
+ @schema[name] = default.equal?(NULL) ? nil : Default.new(default)
50
52
  end
51
53
 
52
54
  def initialize_dup(other)
@@ -1,3 +1,3 @@
1
1
  module Portrayal
2
- VERSION = '0.7.0'
2
+ VERSION = '0.7.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: portrayal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxim Chernyak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-13 00:00:00.000000000 Z
11
+ date: 2021-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler