portrayal 0.7.0 → 0.7.1

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: 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