smart_properties 1.13.0 → 1.13.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
  SHA1:
3
- metadata.gz: fbf78f2b4f868f64a7e675336305c7f68579ec33
4
- data.tar.gz: 12eeb1777b492bfb56f4d3fe68e0b2fbea222d88
3
+ metadata.gz: b393bac2287b2fc8bc96acdfe0da75ee774d9193
4
+ data.tar.gz: f6cc1a80370cdd4d2c361c4eaf6b933841747a10
5
5
  SHA512:
6
- metadata.gz: 67139c47fcc6da96c64d3d4489cfc16144f5cdb8772ece8b96e493a3aed6b127de5197003d7695f1d61365e7b2154a5983c2653c9b33e9529ac3d5f4702293b1
7
- data.tar.gz: 926f1575ffe3723a502ae0f2d427df880d638fafc47ff5870a19df87e81103cf435bf4f2931d583a08e9f7095e1ac41e2d2d7fcab6c54b628b728522f6777b64
6
+ metadata.gz: f878809a07157695137651ad2a20daf44b7dbbec3beae5685fc05c9512f6c165a366d6cf9b67256912bc8e1e50acb3fff98245997364560e894d35a816f46c0d
7
+ data.tar.gz: 70571022057eb569d0b0702e25218d99a052be2506fb63d43262ef31ce869a05f462b38e3dbce681f2368b52516f4321328207cb40f9a0311df5cd9989cb8f8b
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.4.1
data/README.md CHANGED
@@ -220,7 +220,7 @@ class Person
220
220
  end
221
221
  ```
222
222
 
223
- #### Custom readers
223
+ #### Custom reader naming
224
224
 
225
225
  In Ruby, predicate methods by convention end with a `?`.
226
226
  This convention is violated in the example above, but can easily be fixed by supplying a custom `reader` name:
@@ -235,6 +235,22 @@ end
235
235
  To ensure backwards compatibility, boolean properties do not automatically change their reader name.
236
236
  It is thus your responsibility to configure the property properly.
237
237
 
238
+ #### Custom reader implementation
239
+
240
+ For convenience, it is possible to use the `super` method to access the original reader when overriding a reader.
241
+ This is recommended over direct access to the instance variable.
242
+
243
+ ```ruby
244
+ class Person
245
+ property :name
246
+ property! :address
247
+
248
+ def name
249
+ super || address.name
250
+ end
251
+ end
252
+ ```
253
+
238
254
  ### Constructor argument forwarding
239
255
 
240
256
  The `SmartProperties` initializer forwards anything to the super constructor
data/dev.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: smart-properties
3
+ up:
4
+ - ruby: 2.4.1
5
+ - bundler
6
+ commands:
7
+ test: bundle exec rake test
@@ -0,0 +1,34 @@
1
+ require 'benchmark'
2
+ require_relative '../lib/smart_properties'
3
+
4
+ class A
5
+ include SmartProperties
6
+ property :a
7
+ end
8
+
9
+ class B < A
10
+ property :b
11
+ end
12
+
13
+ class C < B
14
+ property :c
15
+ end
16
+
17
+ class A2
18
+ def initialize(**attrs)
19
+ attrs.each { |k, v| send("#{k}=", v) }
20
+ end
21
+ attr_accessor :a
22
+ end
23
+
24
+ class B2 < A2
25
+ attr_accessor :b
26
+ end
27
+
28
+ class C2 < B2
29
+ attr_accessor :c
30
+ end
31
+
32
+ puts Benchmark.measure { 1_000_000.times { C.new(a: 1, b: 2, c: 3) } }
33
+ # puts Benchmark.measure { 1_000_000.times { C2.new(a: 1, b: 2, c: 3) } }
34
+
@@ -2,22 +2,6 @@ module SmartProperties
2
2
  class Property
3
3
  MODULE_REFERENCE = :"@_smart_properties_method_scope"
4
4
 
5
- # Defines the two index methods #[] and #[]=. This module will be included
6
- # in the SmartProperties method scope.
7
- module IndexMethods
8
- def [](name)
9
- return if name.nil?
10
- name = name.to_sym
11
- reader = self.class.properties[name].reader
12
- public_send(reader) if self.class.properties.key?(name)
13
- end
14
-
15
- def []=(name, value)
16
- return if name.nil?
17
- public_send(:"#{name.to_sym}=", value) if self.class.properties.key?(name)
18
- end
19
- end
20
-
21
5
  attr_reader :name
22
6
  attr_reader :converter
23
7
  attr_reader :accepter
@@ -65,7 +49,13 @@ module SmartProperties
65
49
  def convert(scope, value)
66
50
  return value unless converter
67
51
  return value if null_object?(value)
68
- scope.instance_exec(value, &converter)
52
+
53
+ case converter
54
+ when Symbol
55
+ converter.to_proc.call(value)
56
+ else
57
+ scope.instance_exec(value, &converter)
58
+ end
69
59
  end
70
60
 
71
61
  def default(scope)
@@ -99,7 +89,7 @@ module SmartProperties
99
89
  if klass.instance_variable_defined?(MODULE_REFERENCE)
100
90
  klass.instance_variable_get(MODULE_REFERENCE)
101
91
  else
102
- m = Module.new { include IndexMethods }
92
+ m = Module.new
103
93
  klass.send(:include, m)
104
94
  klass.instance_variable_set(MODULE_REFERENCE, m)
105
95
  m
@@ -132,12 +122,22 @@ module SmartProperties
132
122
  scope.instance_variable_get(instance_variable_name)
133
123
  end
134
124
 
125
+ def to_h
126
+ {
127
+ accepter: @accepter,
128
+ converter: @converter,
129
+ default: @default,
130
+ instance_variable_name: @instance_variable_name,
131
+ name: @name,
132
+ reader: @reader,
133
+ required: @required
134
+ }
135
+ end
136
+
135
137
  private
136
138
 
137
139
  def null_object?(object)
138
- return true if object == nil
139
- return true if object.nil?
140
- false
140
+ object.nil?
141
141
  rescue NoMethodError => error
142
142
  # BasicObject does not respond to #nil? by default, so we need to double
143
143
  # check if somebody implemented it and it fails internally or if the
@@ -1,3 +1,3 @@
1
1
  module SmartProperties
2
- VERSION = "1.13.0"
2
+ VERSION = "1.13.1"
3
3
  end
@@ -153,6 +153,18 @@ module SmartProperties
153
153
 
154
154
  raise SmartProperties::InitializationError.new(self, missing_properties) unless missing_properties.empty?
155
155
  end
156
+
157
+ def [](name)
158
+ return if name.nil?
159
+ name = name.to_sym
160
+ reader = self.class.properties[name].reader
161
+ public_send(reader) if self.class.properties.key?(name)
162
+ end
163
+
164
+ def []=(name, value)
165
+ return if name.nil?
166
+ public_send(:"#{name.to_sym}=", value) if self.class.properties.key?(name)
167
+ end
156
168
  end
157
169
 
158
170
  require_relative 'smart_properties/property_collection'
data/spec/base_spec.rb CHANGED
@@ -47,6 +47,13 @@ RSpec.describe SmartProperties do
47
47
 
48
48
  it { is_expected.to have_smart_property(:title) }
49
49
 
50
+ it "should return a property's configuration with #to_h" do
51
+ expect(klass.properties.values.first.to_h).to match(
52
+ accepter: String, converter: :to_title, default: an_instance_of(RSpec::Mocks::Double),
53
+ instance_variable_name: :@title, name: :title, reader: :title, required: true
54
+ )
55
+ end
56
+
50
57
  context "an instance of this class when initialized with no arguments" do
51
58
  subject(:instance) { klass.new }
52
59
 
@@ -157,4 +164,34 @@ RSpec.describe SmartProperties do
157
164
  end
158
165
  end
159
166
  end
167
+
168
+ context "when used to build a class that has a property called relation for an arbitrary Relation class" do
169
+ class Relation
170
+ attr_reader :equality_tested
171
+
172
+ def initialize
173
+ @equality_tested = false
174
+ end
175
+
176
+ def ==(_)
177
+ @equality_tested = true
178
+ false
179
+ end
180
+ end
181
+
182
+ subject(:klass) do
183
+ DummyClass.new do
184
+ property :relation, accepts: Relation, required: true
185
+ end
186
+ end
187
+
188
+ context 'with an instance of Relation' do
189
+ let(:relation) { Relation.new }
190
+
191
+ it 'should not execute #== on the object' do
192
+ instance = klass.new(relation: relation)
193
+ expect(relation.equality_tested).to eq(false)
194
+ end
195
+ end
196
+ end
160
197
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_properties
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Tennhard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-13 00:00:00.000000000 Z
11
+ date: 2017-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -63,11 +63,14 @@ extensions: []
63
63
  extra_rdoc_files: []
64
64
  files:
65
65
  - ".gitignore"
66
+ - ".ruby-version"
66
67
  - ".yardopts"
67
68
  - Gemfile
68
69
  - LICENSE
69
70
  - README.md
70
71
  - Rakefile
72
+ - dev.yml
73
+ - experiments/initialization_performance.rb
71
74
  - lib/smart_properties.rb
72
75
  - lib/smart_properties/errors.rb
73
76
  - lib/smart_properties/property.rb
@@ -105,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
108
  version: '0'
106
109
  requirements: []
107
110
  rubyforge_project:
108
- rubygems_version: 2.5.1
111
+ rubygems_version: 2.6.11
109
112
  signing_key:
110
113
  specification_version: 4
111
114
  summary: SmartProperties – Ruby accessors on steroids