extant 0.3.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 59966f18b3d32352d1ab9700a02a424c1dc812f7
4
+ data.tar.gz: 5b8021c55eef67a6643fd7c50fdf6828953f814c
5
+ SHA512:
6
+ metadata.gz: bc0226bf520414c661d44cfd55a6398553fdc72c1e57144c50317492b4e554eca5bd920a1da12ae5c9a4bf72f327d4f60d4fa12432dd47c289ff05e744368443
7
+ data.tar.gz: 198d0d6440bb0c89aa66957a1d836c4edc0c82901a56c328b0683fab6083933979509da904cdc7dc5c5c587de299a38fa2aa7632f89685f0cbfe60e458a4458f
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 NCC Group Domain Services
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,80 @@
1
+ # Extant
2
+
3
+ _Sponsored by NCC Group Domain Services_
4
+
5
+ Extant provides attribute management for Ruby objects. It is somewhat similar to
6
+ `attr_accessor`, except it does many additional things like, type coercion,
7
+ change tracking (dirty attributes), and most importantly tracking of existence.
8
+
9
+ ## Installation
10
+
11
+ ``` terminal
12
+ $ gem install extant
13
+ ```
14
+
15
+ or in your **Gemfile**
16
+
17
+ ``` ruby
18
+ gem 'extant'
19
+ ```
20
+
21
+ ## Getting Started
22
+
23
+ ```ruby
24
+ class Widget
25
+ include Extant::Attributes
26
+
27
+ attribute :name, String
28
+ attribute :price, Integer
29
+ attribute :production_ready, Extant::Coercers::Boolean, default: false
30
+ end
31
+ ```
32
+
33
+ Basic Usage
34
+ ```ruby
35
+ widget = Widget.new(
36
+ name: 'Doodad',
37
+ price: 100
38
+ )
39
+
40
+ widget.name # => 'Doodad'
41
+ widget.price # => 100
42
+ widget.production_ready # => false
43
+
44
+ widget.attributes # => { name: 'Doodad', price: 100, production_ready: false }
45
+ ```
46
+
47
+ Coercion
48
+ ```ruby
49
+ widget = Widget.new(
50
+ price: 'not a number'
51
+ )
52
+
53
+ widget.extant_attributes[:price].coerced? # => false
54
+ widget.price # => nil
55
+ widget.extant_attributes[:price].pre_coerce_value # => 'not a number'
56
+ ```
57
+
58
+ Existence
59
+ ```ruby
60
+ widget = Widget.new
61
+
62
+ widget.name # => nil
63
+ widget.extant_attributes[:name].set? # => false
64
+
65
+ widget = Widget.new(
66
+ name: nil
67
+ )
68
+
69
+ widget.name # => nil
70
+ widget.extant_attributes[:name].set? # => true
71
+ widget.extant_attributes[:name].coerced? # => true
72
+ ```
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork
77
+ 2. Make changes
78
+ 3. Pull request
79
+ 4. Celebrate
80
+
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ task :environment do
9
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'extant/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "extant"
8
+ spec.version = Extant::VERSION
9
+ spec.authors = ["NCC Group Domain Services"]
10
+ spec.email = ["brady.love@nccgroup.trust", "emily.dobervich@nccgroup.trust"]
11
+ spec.licenses = ['MIT']
12
+
13
+ spec.summary = %q{Extant, it helps you manage your attributes' existance.}
14
+ spec.description = %q{Define attributes, readers and writers on classes.}
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.9"
20
+ spec.add_development_dependency "rake", "~> 10.0"
21
+ spec.add_development_dependency "rspec", "~> 3.0"
22
+ spec.add_development_dependency "pry-nav"
23
+ spec.add_development_dependency "pry-doc"
24
+ end
@@ -0,0 +1,8 @@
1
+ require 'extant/version'
2
+ require 'extant/unset_value'
3
+ require 'extant/uncoerced_value'
4
+ require 'extant/attributes'
5
+
6
+ module Extant
7
+
8
+ end
@@ -0,0 +1,78 @@
1
+ module Extant
2
+ class Attribute
3
+ attr_reader :name, :coercer_class, :pre_coerce_value, :value
4
+
5
+ def initialize(name, value, definition)
6
+ self.name = name
7
+ self.has_been_coereced = false
8
+ self.definition = definition
9
+
10
+ if UnsetValue == value
11
+ @value = nil
12
+ self.is_unset = true
13
+ else
14
+ set_value(value)
15
+ end
16
+ end
17
+
18
+ def value=(val)
19
+ set_value(val)
20
+ self.value_has_changed = true
21
+ end
22
+
23
+ def coerced?
24
+ !!has_been_coereced
25
+ end
26
+
27
+ def has_changed?
28
+ !!value_has_changed
29
+ end
30
+
31
+ def unset?
32
+ !set?
33
+ end
34
+
35
+ def set?
36
+ !is_unset
37
+ end
38
+
39
+ def coercer_name
40
+ coercer_class.try(:coercer_name)
41
+ end
42
+
43
+ def inspect
44
+ "<Extant::Attribute:#{self.object_id} Name: :#{name} Value: #{value.inspect}>"
45
+ end
46
+
47
+ private
48
+
49
+ def coercer_class
50
+ definition.coercer_class
51
+ end
52
+
53
+ def set_value(val)
54
+ self.pre_coerce_value = val
55
+
56
+ @value = if coercer_class
57
+ coercer = coercer_class.new(val)
58
+ coercer.coerce.tap { self.has_been_coereced = coercer.coerced? }
59
+ else
60
+ self.has_been_coereced = true
61
+ val
62
+ end
63
+
64
+ if UncoercedValue == @value
65
+ @value = nil
66
+
67
+ if definition.allow_nil && pre_coerce_value == nil
68
+ self.has_been_coereced = true
69
+ end
70
+ end
71
+
72
+ self.is_unset = false
73
+ end
74
+
75
+ attr_accessor :value_has_changed, :has_been_coereced, :is_unset, :definition
76
+ attr_writer :name, :coercer_class, :pre_coerce_value
77
+ end
78
+ end
@@ -0,0 +1,28 @@
1
+ module Extant
2
+ class AttributeDefinition
3
+ attr_accessor :name, :type, :coercer_class, :has_default, :default_value,
4
+ :allow_nil
5
+
6
+ def initialize(model, name, opts={})
7
+ self.name = name
8
+ self.type = opts[:type]
9
+ self.has_default = opts.key?(:default)
10
+ self.default_value = opts[:default]
11
+ self.allow_nil = opts.fetch(:allow_nil, true)
12
+
13
+ if type
14
+ self.coercer_class = Extant::Coercers.find(type)
15
+ end
16
+
17
+ model.instance_eval do
18
+ define_method name do
19
+ extant_attributes[name].value
20
+ end
21
+
22
+ define_method "#{name}=" do |val|
23
+ extant_attributes[name].value = val
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,130 @@
1
+ require 'extant/attribute'
2
+ require 'extant/attribute_definition'
3
+
4
+ module Extant
5
+ module Attributes
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def attribute_definitions
12
+ @attributes ||= {}
13
+ end
14
+
15
+ def attribute(name, type=nil, **opts)
16
+ opts[:type] = type
17
+ attribute_definitions[name] = AttributeDefinition.new(self, name, opts)
18
+ end
19
+ end
20
+
21
+ def initialize(attrs={})
22
+ attrs = Hash[attrs.map{ |k, v| [k.to_sym, v] }]
23
+ attribute_definitions.each do |k, definition|
24
+ value = if attrs.key?(k)
25
+ attrs[k]
26
+ else
27
+ UnsetValue
28
+ end
29
+
30
+ if UnsetValue == value && definition.has_default
31
+ value = definition.default_value.is_a?(Proc) ? definition.default_value.call : definition.default_value
32
+ end
33
+
34
+ extant_attributes[k] =
35
+ Extant::Attribute.new(k, value, definition)
36
+ end
37
+
38
+ self.original_extant_attributes = extant_attributes
39
+ end
40
+
41
+ def attributes
42
+ self.class.attribute_definitions.each_with_object({}) do |(k, _), attrs|
43
+ attrs[k] = send(k)
44
+ end
45
+ end
46
+
47
+ def attribute_definitions
48
+ self.class.attribute_definitions
49
+ end
50
+
51
+ def extant_attributes
52
+ @extant_attributes ||= {}
53
+ end
54
+
55
+ def set_attributes
56
+ self.class.attribute_definitions.each_with_object({}) do |(k, _), attrs|
57
+ if extant_attributes[k].set?
58
+ attrs[k] = send(k)
59
+ end
60
+ end
61
+ end
62
+
63
+ def changed_attributes
64
+ self.class.attribute_definitions.each_with_object({}) do |(k, _), attrs|
65
+ if extant_attributes[k].has_changed?
66
+ attrs[k] = send(k)
67
+ end
68
+ end
69
+ end
70
+
71
+ def each_extant_attribute
72
+ extant_attributes.values.each do |v|
73
+ yield v
74
+ end
75
+ end
76
+
77
+ def update_attributes(attrs={})
78
+ attrs.each do |k, v|
79
+ send("#{k}=".to_sym, v) if respond_to?("#{k}=".to_sym)
80
+ end
81
+
82
+ self
83
+ end
84
+
85
+ def dirty?(attr=nil)
86
+ if attr
87
+ !!changed_extant_attributes[attr]
88
+ else
89
+ changed_extant_attributes.any?
90
+ end
91
+ end
92
+
93
+ def original_extant_attributes
94
+ @original_extant_attributes ||= {}
95
+ end
96
+
97
+ def with(attrs={}, metadata={})
98
+ new_instance = self.class.new(self.attributes)
99
+ new_instance.update_attributes(attrs)
100
+
101
+ new_instance.send(:with_metadata=, metadata)
102
+ new_instance.send(:original_extant_attributes=, original_extant_attributes)
103
+ new_instance
104
+ end
105
+
106
+ def with_metadata
107
+ @with_metadata || {}
108
+ end
109
+
110
+ private
111
+
112
+ attr_writer :with_metadata
113
+
114
+ def changed_extant_attributes
115
+ self.class.attribute_definitions.each_with_object({}) do |(k, _), attrs|
116
+ if extant_attributes[k].has_changed?
117
+ attrs[k] = extant_attributes[k]
118
+ end
119
+ end
120
+ end
121
+
122
+ def original_extant_attributes=(attrs={})
123
+ attrs.each do |k, v|
124
+ original_extant_attributes[k] = v.dup
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ require 'extant/coercers'
@@ -0,0 +1,47 @@
1
+ module Extant
2
+ module Coercers
3
+ def self.find(type)
4
+ if type.is_a?(::Hash)
5
+ coercer_options = {
6
+ hash_format: type
7
+ }
8
+
9
+ type = HashCoercerBuilder.build(coercer_options)
10
+ end
11
+
12
+ if type.is_a?(::Array)
13
+ coercer_options = {
14
+ array_format: type
15
+ }
16
+
17
+ type = ArrayCoercerBuilder.build(coercer_options)
18
+ end
19
+
20
+ if type.is_a?(Class) && type.ancestors.include?(Extant::Coercers::Base)
21
+ coercer_class = type
22
+ else
23
+ coercer_class = Object.const_get("Extant::Coercers::#{type}")
24
+
25
+ unless coercer_class.method_defined?(:coerce)
26
+ raise "#{type} must respond to #coerce"
27
+ end
28
+ end
29
+
30
+ coercer_class
31
+ end
32
+ end
33
+ end
34
+
35
+ require 'extant/coercers/base'
36
+
37
+ require 'extant/coercers/boolean'
38
+ require 'extant/coercers/date_time'
39
+ require 'extant/coercers/fixnum'
40
+ require 'extant/coercers/float'
41
+ require 'extant/coercers/hash'
42
+ require 'extant/coercers/array'
43
+ require 'extant/coercers/integer'
44
+ require 'extant/coercers/string'
45
+ require 'extant/coercers/symbol'
46
+ require 'extant/coercers/time'
47
+ require 'extant/coercers/uuid'
@@ -0,0 +1,56 @@
1
+ module Extant::Coercers
2
+ class Array < Base
3
+ class << self
4
+ attr_accessor :value_type
5
+ end
6
+
7
+ def coerce
8
+ return ArgumentError unless value.respond_to?(:to_a)
9
+ result = value.to_a
10
+ return ArgumentError unless result.is_a?(::Array)
11
+
12
+ if value_type
13
+ result = result.map do |v|
14
+ coerce_value(v)
15
+ end
16
+ end
17
+
18
+ self.coerced = true
19
+
20
+ result
21
+ rescue ArgumentError
22
+ UncoercedValue
23
+ end
24
+
25
+ private
26
+
27
+ def coerce_value(v)
28
+ coercer = value_type.new(v)
29
+ result = coercer.coerce
30
+ raise ArgumentError unless coercer.coerced?
31
+ result
32
+ end
33
+
34
+ def key_type
35
+ self.class.key_type
36
+ end
37
+
38
+ def value_type
39
+ self.class.value_type
40
+ end
41
+ end
42
+
43
+ class ArrayCoercerBuilder
44
+ def self.build(opts)
45
+ value_type_local = Extant::Coercers.find(opts[:array_format].first)
46
+
47
+ Class.new(Extant::Coercers::Array) do
48
+ self.value_type = value_type_local
49
+
50
+ def self.coercer_name
51
+ 'array'
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,27 @@
1
+ module Extant::Coercers
2
+ class Base
3
+ UncoercedValue = Extant::UncoercedValue
4
+
5
+ def self.coercer_name
6
+ self.name.split("::").last.gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
7
+ end
8
+
9
+ def initialize(value, options={})
10
+ self.value = value
11
+ self.coerced = false
12
+ self.options = {}
13
+ end
14
+
15
+ def coerce
16
+ rase NotImplementedError.new("#{self.class.name} must implement #{coerce}")
17
+ end
18
+
19
+ def coerced?
20
+ coerced
21
+ end
22
+
23
+ private
24
+
25
+ attr_accessor :value, :coerced, :options
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Extant::Coercers
2
+ class Boolean < Base
3
+ def coerce
4
+ if [true, "true", 1].include?(value)
5
+ self.coerced = true
6
+ return true
7
+ elsif [false, "false", 0].include?(value)
8
+ self.coerced = true
9
+ return false
10
+ end
11
+
12
+ Extant::UncoercedValue
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Extant::Coercers
2
+ class DateTime < Base
3
+ def coerce
4
+ if value.is_a?(::DateTime)
5
+ self.coerced = true
6
+ return value
7
+ end
8
+
9
+ result = ::DateTime.parse(value.to_s)
10
+ self.coerced = true
11
+ result
12
+ rescue ArgumentError
13
+ UncoercedValue
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Extant::Coercers
2
+ class Fixnum < Base
3
+ def coerce
4
+ result = Integer(value)
5
+ self.coerced = true
6
+ result
7
+ rescue ArgumentError, TypeError
8
+ UncoercedValue
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Extant::Coercers
2
+ class Float < Base
3
+ def coerce
4
+ result = Float(value)
5
+ self.coerced = true
6
+ result
7
+ rescue ArgumentError, TypeError
8
+ UncoercedValue
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ module Extant::Coercers
2
+ class Hash < Base
3
+ class << self
4
+ attr_accessor :key_type, :value_type
5
+ end
6
+
7
+ def coerce
8
+ result = ::Hash[value]
9
+
10
+ if key_type && value_type
11
+ result = result.each_with_object({}) do |(k, v), h|
12
+ h[coerce_key(k)] = coerce_value(v)
13
+ end
14
+ end
15
+
16
+ self.coerced = true
17
+
18
+ result
19
+ rescue ArgumentError
20
+ UncoercedValue
21
+ end
22
+
23
+ private
24
+
25
+ def coerce_key(v)
26
+ coercer = key_type.new(v)
27
+ result = coercer.coerce
28
+ raise ArgumentError unless coercer.coerced?
29
+ result
30
+ end
31
+
32
+ def coerce_value(v)
33
+ coercer = value_type.new(v)
34
+ result = coercer.coerce
35
+ raise ArgumentError unless coercer.coerced?
36
+ result
37
+ end
38
+
39
+ def key_type
40
+ self.class.key_type
41
+ end
42
+
43
+ def value_type
44
+ self.class.value_type
45
+ end
46
+ end
47
+
48
+ class HashCoercerBuilder
49
+ def self.build(opts)
50
+ key_type_local = Extant::Coercers.find(opts[:hash_format].keys.first)
51
+ value_type_local = Extant::Coercers.find(opts[:hash_format].values.first)
52
+
53
+ Class.new(Extant::Coercers::Hash) do
54
+ self.key_type = key_type_local
55
+ self.value_type = value_type_local
56
+
57
+ def self.coercer_name
58
+ 'hash'
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,11 @@
1
+ module Extant::Coercers
2
+ class Integer < Base
3
+ def coerce
4
+ result = Integer(value)
5
+ self.coerced = true
6
+ result
7
+ rescue ArgumentError, TypeError
8
+ UncoercedValue
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Extant::Coercers
2
+ class String < Base
3
+ def coerce
4
+ return UncoercedValue if value == nil
5
+
6
+ self.coerced = true
7
+ value.to_s
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ module Extant::Coercers
2
+ class Symbol < Base
3
+ def coerce
4
+ return UncoercedValue if value == nil
5
+
6
+ if value.is_a?(::String)
7
+ result = value.to_sym
8
+ elsif value.is_a?(::Symbol)
9
+ result = value
10
+ else
11
+ raise ArgumentError
12
+ end
13
+
14
+ self.coerced = true
15
+ result
16
+ rescue ArgumentError
17
+ UncoercedValue
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ require 'time'
2
+
3
+ module Extant::Coercers
4
+ class Time < Base
5
+ def coerce
6
+ if value.is_a?(::Time)
7
+ self.coerced = true
8
+ return value
9
+ end
10
+
11
+ result = ::Time.parse(value.to_s)
12
+ self.coerced = true
13
+ result
14
+ rescue ArgumentError
15
+ UncoercedValue
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ module Extant::Coercers
2
+ class Uuid < Base
3
+ UUID_REGEX = /\A[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}\z/i
4
+
5
+ def coerce
6
+ if value.to_s =~ UUID_REGEX
7
+ self.coerced = true
8
+ value.to_s
9
+ else
10
+ UncoercedValue
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ require 'singleton'
2
+
3
+ module Extant
4
+ class UncoercedValue
5
+ include Singleton
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'singleton'
2
+
3
+ module Extant
4
+ class UnsetValue
5
+ include Singleton
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Extant
2
+ VERSION = "0.3.0"
3
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: extant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - NCC Group Domain Services
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-nav
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-doc
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Define attributes, readers and writers on classes.
84
+ email:
85
+ - brady.love@nccgroup.trust
86
+ - emily.dobervich@nccgroup.trust
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - extant.gemspec
99
+ - lib/extant.rb
100
+ - lib/extant/attribute.rb
101
+ - lib/extant/attribute_definition.rb
102
+ - lib/extant/attributes.rb
103
+ - lib/extant/coercers.rb
104
+ - lib/extant/coercers/array.rb
105
+ - lib/extant/coercers/base.rb
106
+ - lib/extant/coercers/boolean.rb
107
+ - lib/extant/coercers/date_time.rb
108
+ - lib/extant/coercers/fixnum.rb
109
+ - lib/extant/coercers/float.rb
110
+ - lib/extant/coercers/hash.rb
111
+ - lib/extant/coercers/integer.rb
112
+ - lib/extant/coercers/string.rb
113
+ - lib/extant/coercers/symbol.rb
114
+ - lib/extant/coercers/time.rb
115
+ - lib/extant/coercers/uuid.rb
116
+ - lib/extant/uncoerced_value.rb
117
+ - lib/extant/unset_value.rb
118
+ - lib/extant/version.rb
119
+ homepage:
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.0.14
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Extant, it helps you manage your attributes' existance.
143
+ test_files: []
144
+ has_rdoc: