Make Dash greedier when creating getters
Dash, in its current form, was created to be very conservative in creating the getters for its properties. It only creates them when the accompanying setter has not already been created. This means that the property translation capability that is layered on top of Dash to create a Trash cannot have dependence between properties in an order-independent way. This change makes it so Dash now greedily creates a getter method for each property. To ensure that we don't do this more than once for a given Dash class, we track the getters we have previously created. This keeps the number of warnings from Ruby down to the same number of warnings that were emitted prior to this change. Given that Dash users expect the getter to be set, this doesn't feel like it should cause any backwards-compatibility issues.
This commit is contained in:
parent
b7209f6f58
commit
91a5153fa3
|
@ -1,16 +1,16 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2018-02-07 19:58:08 -0600 using RuboCop version 0.52.1.
|
||||
# on 2018-08-11 15:53:09 -0500 using RuboCop version 0.52.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 9
|
||||
# Offense count: 8
|
||||
Metrics/AbcSize:
|
||||
Max: 26
|
||||
Max: 24
|
||||
|
||||
# Offense count: 57
|
||||
# Offense count: 58
|
||||
# Configuration parameters: CountComments, ExcludedMethods.
|
||||
Metrics/BlockLength:
|
||||
Max: 620
|
||||
|
@ -42,14 +42,13 @@ Metrics/PerceivedComplexity:
|
|||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 2
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Style/IfUnlessModifier:
|
||||
Exclude:
|
||||
- 'lib/hashie/extensions/dash/property_translation.rb'
|
||||
- 'lib/hashie/extensions/strict_key_access.rb'
|
||||
|
||||
# Offense count: 256
|
||||
# Offense count: 261
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
|
|
|
@ -42,11 +42,8 @@ module Hashie
|
|||
defaults.delete property_name
|
||||
end
|
||||
|
||||
unless instance_methods.map(&:to_s).include?("#{property_name}=")
|
||||
define_method(property_name) { |&block| self.[](property_name, &block) }
|
||||
property_assignment = "#{property_name}=".to_sym
|
||||
define_method(property_assignment) { |value| self.[]=(property_name, value) }
|
||||
end
|
||||
define_getter_for(property_name)
|
||||
define_setter_for(property_name)
|
||||
|
||||
@subclasses.each { |klass| klass.property(property_name, options) } if defined? @subclasses
|
||||
|
||||
|
@ -61,9 +58,11 @@ module Hashie
|
|||
|
||||
class << self
|
||||
attr_reader :properties, :defaults
|
||||
attr_reader :getters
|
||||
attr_reader :required_properties
|
||||
end
|
||||
instance_variable_set('@properties', Set.new)
|
||||
instance_variable_set('@getters', Set.new)
|
||||
instance_variable_set('@defaults', {})
|
||||
instance_variable_set('@required_properties', {})
|
||||
|
||||
|
@ -71,6 +70,7 @@ module Hashie
|
|||
super
|
||||
(@subclasses ||= Set.new) << klass
|
||||
klass.instance_variable_set('@properties', properties.dup)
|
||||
klass.instance_variable_set('@getters', getters.dup)
|
||||
klass.instance_variable_set('@defaults', defaults.dup)
|
||||
klass.instance_variable_set('@required_properties', required_properties.dup)
|
||||
end
|
||||
|
@ -87,6 +87,18 @@ module Hashie
|
|||
required_properties.key? name
|
||||
end
|
||||
|
||||
private_class_method def self.define_getter_for(property_name)
|
||||
return if getters.include?(property_name)
|
||||
define_method(property_name) { |&block| self.[](property_name, &block) }
|
||||
getters << property_name
|
||||
end
|
||||
|
||||
private_class_method def self.define_setter_for(property_name)
|
||||
setter = :"#{property_name}="
|
||||
return if instance_methods.include?(setter)
|
||||
define_method(setter) { |value| self.[]=(property_name, value) }
|
||||
end
|
||||
|
||||
# You may initialize a Dash with an attributes hash
|
||||
# just like you would many other kinds of data objects.
|
||||
def initialize(attributes = {}, &block)
|
||||
|
|
|
@ -312,5 +312,17 @@ describe Hashie::Trash do
|
|||
expect(subject.to_h[:value]).to eq(nil)
|
||||
expect(subject.copy_of_value).to eq(0)
|
||||
end
|
||||
|
||||
it 'is not order-dependent in definition' do
|
||||
simple = Class.new(Hashie::Trash) do
|
||||
property :copy_of_id, from: :id
|
||||
property :id
|
||||
end
|
||||
|
||||
subject = simple.new(id: 1)
|
||||
|
||||
expect(subject.id).to eq(1)
|
||||
expect(subject.copy_of_id).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue