philosophal 1.2.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1df7f3c754eeef6776d0e3a18bcfdb81124e413187beb2f580dd550cbdcd046e
4
- data.tar.gz: 03ed60c26e12f8225145e6f00a138da84e3d1aa11ffd1ab1be878df0032e6896
3
+ metadata.gz: d1bb80908d227d997cf25e816e00335f9c61328aa4eb285ee7c51632adfcc9cb
4
+ data.tar.gz: 56ca323ff898cb43b8604850e0ea94cd5b323c236d365a70ad8d36e9321bd01f
5
5
  SHA512:
6
- metadata.gz: ab3fd3bf30dbaba5d2936979b832b2f9a715b7dbab19eba5d08c7feb4e84aa5affd41247b294ffc7ff9a4c054dcaba932ba2cb98d9c8699b5825d1dbad4c0a9b
7
- data.tar.gz: 2b372e50b9bcf123531cdc0df806061893e86a3ddc70eddc2cc47731a017cff18dea606aea8c3477c2d8f2adf1faaa051c3728ad8645b166a0c5c120e583f951
6
+ metadata.gz: 2cf9f37bd111eb6ca5c021a5fefd0da9b7cf48e624adf5ac9d12c57f885315b327ae1539946744317fbd120623455b82fe5d9aa3186a0613d9cb72f2102785ec
7
+ data.tar.gz: 70f39c48ee39f045a7208e141b1cd56c7cff8f6871e17a855628d2b85007ee7fe850df89fa084615eb26585078a5f0b4e2623e45b1d0befb59c4a9f62af4ba3c
data/CHANGELOG.md CHANGED
@@ -1,4 +1,14 @@
1
- ## [Unreleased]
1
+ ## [1.3.0] - 2026-10-19
2
+
3
+ - Breaking: minimum required Ruby version is now **3.3** (was 3.1)
4
+ - Breaking: assigning `nil` no longer converts it (e.g. to `0` or `""`); the property is reset and its reader returns the default value
5
+ - Fix: converting a Numeric to **DateTime** no longer requires ActiveSupport (`Time.zone`)
6
+ - Fix: properties declared in a subclass no longer leak into the parent class
7
+ - Fix: a property set to `false` is no longer replaced by its default value, and predicate methods (`prop?`) take the default into account
8
+ - Fix: **ArrayOf** and **HashOf** instances are now really shared for the same subtypes, and **HashOf** accepts anonymous classes
9
+ - Fix: descriptions are no longer evaluated as Ruby code (parentheses or `#{...}` in a description broke or ran code)
10
+ - Fix: `json.load` no longer modifies the given hash or array, and accepts frozen hashes
11
+ - Fix: `override: true` now also replaces a method defined in the class itself before `cprop`
2
12
 
3
13
  ## [1.0.0] - 2025-03-24
4
14
 
@@ -87,7 +87,7 @@ module Philosophal
87
87
  return obj.to_datetime if obj.respond_to?(:to_datetime)
88
88
  return DateTime.new(*obj) if obj.is_a?(Array)
89
89
  return DateTime.parse(obj) if obj.is_a?(String)
90
- return Time.zone.at(obj).to_datetime if obj.is_a?(Numeric)
90
+ return Time.at(obj).to_datetime if obj.is_a?(Numeric)
91
91
 
92
92
  raise Philosophal::TypeError
93
93
  end
@@ -27,7 +27,7 @@ module Philosophal
27
27
  def load_from_array(array)
28
28
  raise LoadError, 'invalid json parameter' if array.find { |hash| !hash.is_a?(Hash) }
29
29
 
30
- array.map! do |hash|
30
+ array.map do |hash|
31
31
  load_from_hash(hash)
32
32
  end
33
33
  end
@@ -35,11 +35,11 @@ module Philosophal
35
35
  def load_from_hash(hash)
36
36
  obj = @klass.new
37
37
 
38
- hash.each_key do |key|
38
+ hash.each do |key, value|
39
39
  setter = setter_from_key(key)
40
40
  next unless obj.respond_to?(setter)
41
41
 
42
- obj.public_send(setter, hash.delete(key))
42
+ obj.public_send(setter, value)
43
43
  end
44
44
 
45
45
  obj
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Philosophal
4
+ module Properties
5
+ module InstanceMethods
6
+ def cprop?(property_name, klass)
7
+ property = self.class.philosophal_properties.properties_index[property_name.to_sym]
8
+ return false unless property
9
+
10
+ klass = klass.class unless klass.is_a?(Class)
11
+ property.type == klass
12
+ end
13
+
14
+ def philosophal_inspect(light = false)
15
+ keys_map = philosophal_inspect_map
16
+
17
+ if light
18
+ keys_map.reject! do |_, v|
19
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
20
+ end
21
+ end
22
+
23
+ keys_str = keys_map.map { |k, v| [k, v.inspect].join(': ') }.join(', ')
24
+ "#{self.class}:#{format('0x00%x', object_id << 1)} #{keys_str}"
25
+ end
26
+ alias cprop_inspect philosophal_inspect
27
+
28
+ def philosophal_inspect_map
29
+ philosophal_values.to_h do |property|
30
+ [
31
+ property.name,
32
+ send(property.name)
33
+ ]
34
+ end
35
+ end
36
+ alias cprop_inspect_map philosophal_inspect_map
37
+
38
+ def philosophal_values
39
+ self.class.philosophal_properties.properties_index.values
40
+ end
41
+
42
+ def to_json_hash
43
+ philosophal_values.select(&:json).to_h do |property|
44
+ [
45
+ property.json_name,
46
+ send(property.name)
47
+ ]
48
+ end
49
+ end
50
+
51
+ def to_json(*_args)
52
+ to_json_hash.to_json
53
+ end
54
+ end
55
+ end
56
+ end
@@ -10,6 +10,14 @@ module Philosophal
10
10
  @mutex = Mutex.new
11
11
  end
12
12
 
13
+ # Called by #dup: a subclass gets its own index, so its properties do not leak into the parent.
14
+ def initialize_copy(source)
15
+ super
16
+ @properties_index = source.properties_index.dup
17
+ @mutex = Mutex.new
18
+ clear_caches
19
+ end
20
+
13
21
  attr_reader :properties_index
14
22
 
15
23
  def [](key)
@@ -23,6 +31,7 @@ module Philosophal
23
31
  def <<(value)
24
32
  @mutex.synchronize do
25
33
  @properties_index[value.name] = value
34
+ clear_caches
26
35
  end
27
36
 
28
37
  self
@@ -47,6 +56,14 @@ module Philosophal
47
56
  [property.json_name, key]
48
57
  end
49
58
  end
59
+
60
+ private
61
+
62
+ def clear_caches
63
+ %i[@immutables @mutables @json_names_h].each do |cache|
64
+ remove_instance_variable(cache) if instance_variable_defined?(cache)
65
+ end
66
+ end
50
67
  end
51
68
  end
52
69
  end
@@ -3,36 +3,21 @@
3
3
  module Philosophal
4
4
  module Properties
5
5
  autoload :Schema, 'philosophal/properties/schema'
6
+ autoload :InstanceMethods, 'philosophal/properties/instance_methods'
6
7
  autoload :JSONLoader, 'philosophal/loaders/json_loader'
7
8
 
8
9
  include Philosophal::Types
9
10
 
10
- def cprop(name, type, default: nil, transform: nil, immutable: false, description: nil, json: false)
11
- default.freeze if default && !(default.is_a?(Proc) || default.frozen?)
11
+ def cprop(name, type, default: nil, transform: nil, immutable: false, description: nil, json: false, override: true)
12
+ __check_philosophal_options__(name, transform:, immutable:, override:, description:, json:)
12
13
 
13
- if transform && !(transform.is_a?(Proc) || transform.is_a?(Symbol))
14
- raise Philosophal::ArgumentError, "transform param must be a Symbol object or a Proc (#{name})."
15
- end
16
-
17
- unless Philosophal::Types::BooleanType::TRUE_FALSE_SET.include?(immutable)
18
- raise Philosophal::ArgumentError, 'immutable param must be true or false.'
19
- end
20
-
21
- if description
22
- raise Philosophal::ArgumentError, 'description param must be a string.' unless description.is_a?(String)
23
-
24
- description.freeze unless description.frozen?
25
- end
14
+ default.freeze unless default.is_a?(Proc)
15
+ description&.freeze
16
+ json = json.to_sym if json.is_a?(String)
26
17
 
27
- if json
28
- unless json.is_a?(TrueClass) || json.is_a?(String) || json.is_a?(Symbol)
29
- raise Philosophal::ArgumentError, 'json param must be true or a String or a Symbol.'
30
- end
31
-
32
- json = json.to_sym if json.is_a?(String)
33
- end
34
-
35
- property = __philosophal_property_class__.new(name:, type:, default:, transform:, immutable:, description:, json:)
18
+ property = __philosophal_property_class__.new(
19
+ name:, type:, default:, transform:, immutable:, description:, json:, override:
20
+ )
36
21
 
37
22
  philosophal_properties << property
38
23
  __define_philosophal_methods__(property)
@@ -81,79 +66,57 @@ module Philosophal
81
66
  end
82
67
 
83
68
  def __philosophal_extension__
84
- if defined?(@__philosophal_extension__)
85
- @__philosophal_extension__
86
- else
87
- @__philosophal_extension__ = Module.new do
88
- def cprop?(property_name, klass)
89
- property = self.class.philosophal_properties.properties_index[property_name.to_sym]
90
- return false unless property
91
-
92
- klass = klass.class unless klass.is_a?(Class)
93
- property.type == klass
94
- end
95
-
96
- def philosophal_inspect(light = false)
97
- keys_map = philosophal_inspect_map
98
-
99
- if light
100
- keys_map.reject! do |_, v|
101
- v.nil? || (v.respond_to?(:empty?) && v.empty?)
102
- end
103
- end
104
-
105
- keys_str = keys_map.map { |k, v| [k, v.inspect].join(': ') }.join(', ')
106
- "#{self.class}:#{format('0x00%x', object_id << 1)} #{keys_str}"
107
- end
108
- alias cprop_inspect philosophal_inspect
109
-
110
- def philosophal_inspect_map
111
- philosophal_values.to_h do |property|
112
- [
113
- property.name,
114
- send(property.name)
115
- ]
116
- end
117
- end
118
- alias cprop_inspect_map philosophal_inspect_map
119
-
120
- def philosophal_values
121
- self.class.philosophal_properties.properties_index.values
122
- end
123
-
124
- def to_json_hash
125
- philosophal_values.select(&:json).to_h do |property|
126
- [
127
- property.json_name,
128
- send(property.name)
129
- ]
130
- end
131
- end
132
-
133
- def to_json(*_args)
134
- to_json_hash.to_json
135
- end
136
- end
69
+ @__philosophal_extension__ ||= Module.new { include Philosophal::Properties::InstanceMethods }
70
+ end
71
+
72
+ def __generate_philosophal_methods__(new_property)
73
+ buffer = +''
74
+
75
+ new_property.method_generators.each do |method_name, generator|
76
+ next unless new_property.override? || !method_defined?(method_name)
77
+
78
+ __remove_philosophal_own_method__(method_name) if new_property.override?
79
+ new_property.public_send(generator, buffer)
137
80
  end
81
+
82
+ # puts buffer
83
+ return buffer if buffer.empty?
84
+
85
+ +"# frozen_string_philosophal: true\n" << buffer
86
+ end
87
+
88
+ # Generated methods live in an included module, so a method defined in the class itself
89
+ # would hide them: it is removed to let the property override it.
90
+ def __remove_philosophal_own_method__(method_name)
91
+ return unless method_defined?(method_name, false) || private_method_defined?(method_name, false)
92
+
93
+ remove_method(method_name)
138
94
  end
139
95
 
140
- def __generate_philosophal_methods__(new_property, buffer = +'')
141
- buffer << "# frozen_string_philosophal: true\n"
142
- if new_property.immutable
143
- new_property.generate_immutable_writer_method(buffer)
144
- else
145
- new_property.generate_writer_method(buffer)
96
+ def __check_philosophal_options__(name, transform:, immutable:, override:, description:, json:)
97
+ __check_philosophal_transform_option__(name, transform)
98
+ __check_philosophal_boolean_option__(:override, override)
99
+ __check_philosophal_boolean_option__(:immutable, immutable)
100
+
101
+ if description && !description.is_a?(String)
102
+ raise Philosophal::ArgumentError, 'description param must be a string.'
146
103
  end
147
104
 
148
- new_property.generate_reader_method(buffer)
105
+ return if !json || json == true || json.is_a?(String) || json.is_a?(Symbol)
106
+
107
+ raise Philosophal::ArgumentError, 'json param must be true or a String or a Symbol.'
108
+ end
149
109
 
150
- new_property.generate_boolean_method(buffer) if new_property.type == Philosophal::Types::BooleanType::Instance
110
+ def __check_philosophal_transform_option__(name, transform)
111
+ return if !transform || transform.is_a?(Proc) || transform.is_a?(Symbol)
151
112
 
152
- new_property.generate_description_method(buffer) if new_property.description
113
+ raise Philosophal::ArgumentError, "transform param must be a Symbol object or a Proc (#{name})."
114
+ end
153
115
 
154
- # puts buffer
116
+ def __check_philosophal_boolean_option__(option_name, value)
117
+ return if Philosophal::Types::BooleanType::TRUE_FALSE_SET.include?(value)
155
118
 
156
- buffer
119
+ raise Philosophal::ArgumentError, "#{option_name} param must be true or false."
157
120
  end
158
121
  end
159
122
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Philosophal
4
4
  class Property
5
- def initialize(name:, type:, default:, transform:, immutable:, description:, json:)
5
+ def initialize(name:, type:, default:, transform:, immutable:, description:, json:, override:)
6
6
  @name = name
7
7
  @type = type
8
8
  @default = default
@@ -10,9 +10,10 @@ module Philosophal
10
10
  @immutable = immutable
11
11
  @description = description
12
12
  @json = json
13
+ @override = override
13
14
  end
14
15
 
15
- attr_reader :name, :type, :default, :transform, :immutable, :description, :json
16
+ attr_reader :name, :type, :default, :transform, :immutable, :description, :json, :override
16
17
 
17
18
  def json_name
18
19
  return @json if @json.is_a?(Symbol)
@@ -35,61 +36,93 @@ module Philosophal
35
36
  @transform != nil
36
37
  end
37
38
 
39
+ def override?
40
+ @override
41
+ end
42
+
38
43
  def check_conversion(value)
39
44
  Philosophal.convert(self, value)
40
45
  end
41
46
 
42
- def generate_writer_method(buffer = +'')
43
- buffer <<
44
- ' def ' << @name.name << "=(value)\n " \
45
- '@' << @name.name << ' = self.class.philosophal_properties[:' <<
46
- @name.name <<
47
- "].check_conversion(value)\n" \
48
- "rescue Philosophal::TypeError => error\n" \
49
- "error.set_backtrace(caller(1))\n raise\n" \
50
- "end\n"
51
- end
52
-
53
- def generate_immutable_writer_method(buffer = +'')
54
- buffer <<
55
- ' def ' << @name.name << "=(value)\n " \
56
- 'raise FrozenError, "can\'t modify frozen variable @' <<
57
- @name.name << '" if defined?(@' << @name.name << ")\n" \
58
- '@' << @name.name << ' = self.class.philosophal_properties[:' <<
59
- @name.name <<
60
- "].check_conversion(value).freeze\n" \
61
- "rescue Philosophal::TypeError => error\n" \
62
- "error.set_backtrace(caller(1))\n raise\n" \
63
- "end\n"
64
- end
65
-
66
- def generate_reader_method(buffer = +'')
67
- buffer <<
68
- ' def ' <<
69
- @name.name <<
70
- "\n " \
71
- '@' << @name.name << ' || self.class.philosophal_properties[:' <<
72
- @name.name <<
73
- "].default_value\n" \
74
- "end\n"
75
- end
76
-
77
- def generate_boolean_method(buffer = +'')
78
- buffer <<
79
- ' def ' <<
80
- @name.name <<
81
- "?\n " \
82
- '!!@' << @name.name <<
83
- "\nend\n"
84
- end
85
-
86
- def generate_description_method(buffer = +'')
87
- buffer <<
88
- ' def ' <<
89
- @name.name <<
90
- "_description\n " \
91
- '%(' << @description << ')' \
92
- "\nend\n"
47
+ def method_generators
48
+ generators = {
49
+ writer_method_name => immutable ? :generate_immutable_writer_method : :generate_writer_method,
50
+ reader_method_name => :generate_reader_method
51
+ }
52
+ generators[boolean_method_name] = :generate_boolean_method if type == Philosophal::Types::BooleanType::Instance
53
+ generators[description_method_name] = :generate_description_method if description
54
+ generators
55
+ end
56
+
57
+ def writer_method_name
58
+ return @writer_method_name if defined? @writer_method_name
59
+
60
+ @writer_method_name = :"#{@name.name}="
61
+ end
62
+
63
+ def generate_writer_method(buffer)
64
+ buffer << <<~RUBY
65
+ def #{writer_method_name.name}(value)
66
+ @#{@name.name} = self.class.philosophal_properties[:#{@name.name}].check_conversion(value)
67
+ rescue Philosophal::TypeError => error
68
+ error.set_backtrace(caller(1))
69
+ raise
70
+ end
71
+ RUBY
72
+ end
73
+
74
+ def generate_immutable_writer_method(buffer)
75
+ buffer << <<~RUBY
76
+ def #{writer_method_name.name}(value)
77
+ raise FrozenError, "can't modify frozen variable @#{@name.name}" if defined?(@#{@name.name})
78
+ @#{@name.name} = self.class.philosophal_properties[:#{@name.name}].check_conversion(value).freeze
79
+ rescue Philosophal::TypeError => error
80
+ error.set_backtrace(caller(1))
81
+ raise
82
+ end
83
+ RUBY
84
+ end
85
+
86
+ def reader_method_name
87
+ @name
88
+ end
89
+
90
+ def generate_reader_method(buffer)
91
+ buffer << <<~RUBY
92
+ def #{reader_method_name.name}
93
+ @#{@name.name}.nil? ? self.class.philosophal_properties[:#{@name.name}].default_value : @#{@name.name}
94
+ end
95
+ RUBY
96
+ end
97
+
98
+ def boolean_method_name
99
+ return @boolean_method_name if defined? @boolean_method_name
100
+
101
+ @boolean_method_name = :"#{@name.name}?"
102
+ end
103
+
104
+ def generate_boolean_method(buffer)
105
+ buffer << <<~RUBY
106
+ def #{boolean_method_name.name}
107
+ !!#{reader_method_name.name}
108
+ end
109
+ RUBY
110
+ end
111
+
112
+ def description_method_name
113
+ return @description_method_name if defined? @description_method_name
114
+
115
+ @description_method_name = :"#{@name.name}_description"
116
+ end
117
+
118
+ # The description is read from the schema rather than written into the generated code,
119
+ # so it is never evaluated as Ruby.
120
+ def generate_description_method(buffer)
121
+ buffer << <<~RUBY
122
+ def #{description_method_name.name}
123
+ self.class.philosophal_properties[:#{@name.name}].description
124
+ end
125
+ RUBY
93
126
  end
94
127
  end
95
128
  end
@@ -3,12 +3,14 @@
3
3
  module Philosophal
4
4
  class Transform
5
5
  def self.make(method, value)
6
- case method
7
- when Proc
8
- method.call(value)
9
- else
10
- value.send(method)
11
- end
6
+ return method.call(value) if method.is_a?(Proc)
7
+
8
+ result = value.send(method)
9
+ self_method?(method) ? value : result
10
+ end
11
+
12
+ def self.self_method?(method)
13
+ method.to_s.end_with?('!')
12
14
  end
13
15
  end
14
16
  end
@@ -4,7 +4,7 @@ module Philosophal
4
4
  module Types
5
5
  class ArrayOfType
6
6
  def self.instance(subtype)
7
- memorization.fetch(subtype, new(subtype).freeze)
7
+ memorization[subtype] ||= new(subtype).freeze
8
8
  end
9
9
 
10
10
  def self.memorization
@@ -13,11 +13,12 @@ module Philosophal
13
13
  @memorization = {}
14
14
  end
15
15
 
16
+ private_class_method :new
17
+
16
18
  attr_reader :subtype
17
19
 
18
20
  def initialize(subtype)
19
21
  @subtype = subtype
20
- self.class.memorization[subtype] = self
21
22
  end
22
23
 
23
24
  def ===(array)
@@ -4,8 +4,7 @@ module Philosophal
4
4
  module Types
5
5
  class HashOfType
6
6
  def self.instance(key_type, value_type)
7
- subtype = { key_type:, value_type: }
8
- memorization.fetch(Marshal.dump(subtype), new(subtype).freeze)
7
+ memorization[[key_type, value_type]] ||= new({ key_type:, value_type: }).freeze
9
8
  end
10
9
 
11
10
  def self.memorization
@@ -14,11 +13,12 @@ module Philosophal
14
13
  @memorization = {}
15
14
  end
16
15
 
16
+ private_class_method :new
17
+
17
18
  attr_reader :subtype
18
19
 
19
20
  def initialize(subtype)
20
21
  @subtype = subtype.freeze
21
- self.class.memorization[Marshal.dump(subtype)] = self
22
22
  end
23
23
 
24
24
  def ===(hash)
data/lib/philosophal.rb CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'date'
4
4
  require 'pathname'
5
- require 'set'
6
5
  require 'time'
7
6
  require 'json'
8
7
 
@@ -20,25 +19,24 @@ module Philosophal
20
19
  autoload :ArgumentError, 'philosophal/errors/argument_error'
21
20
 
22
21
  def self.convert(property, value)
23
- if property.type === value
24
- if property.transform?
25
- Transform.make(property.transform, value)
26
- else
27
- value
28
- end
29
- else
30
- convert_method, subtype = Convertor.convert_method_for(property.type)
31
- raise Philosophal::TypeError unless convert_method
22
+ # nil means "no value": it is neither converted nor transformed, so the reader falls back to the default.
23
+ return if value.nil?
24
+
25
+ converted = property.type === value ? value : convert_to_type(property.type, value) # rubocop:disable Style/CaseEquality
26
+ return converted unless property.transform?
32
27
 
33
- converted = if subtype
34
- Convertor.send(convert_method, value, subtype)
35
- else
36
- Convertor.send(convert_method, value)
37
- end
28
+ Transform.make(property.transform, converted)
29
+ end
38
30
 
39
- return converted unless property.transform?
31
+ def self.convert_to_type(type, value)
32
+ convert_method, subtype = Convertor.convert_method_for(type)
33
+ raise Philosophal::TypeError unless convert_method
40
34
 
41
- Transform.make(property.transform, converted)
35
+ if subtype
36
+ Convertor.send(convert_method, value, subtype)
37
+ else
38
+ Convertor.send(convert_method, value)
42
39
  end
43
40
  end
41
+ private_class_method :convert_to_type
44
42
  end
metadata CHANGED
@@ -1,30 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philosophal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxime Désécot
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-29 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Auto convert value on setter method call
11
+ date: 2026-10-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ description: 'Declare typed attributes with cprop: values are converted, transformed,
28
+ defaulted or frozen on assignment, with JSON import/export.'
14
29
  email:
15
30
  - maxime.desecot@gmail.com
16
31
  executables: []
17
32
  extensions: []
18
33
  extra_rdoc_files: []
19
34
  files:
20
- - ".rubocop.yml"
21
- - ".ruby-version"
22
- - ".tool-versions"
23
35
  - CHANGELOG.md
24
36
  - LICENSE
25
37
  - README.md
26
- - Rakefile
27
- - VERSION
28
38
  - lib/philosophal.rb
29
39
  - lib/philosophal/convertor.rb
30
40
  - lib/philosophal/errors/argument_error.rb
@@ -33,6 +43,7 @@ files:
33
43
  - lib/philosophal/loaders/errors.rb
34
44
  - lib/philosophal/loaders/json_loader.rb
35
45
  - lib/philosophal/properties.rb
46
+ - lib/philosophal/properties/instance_methods.rb
36
47
  - lib/philosophal/properties/schema.rb
37
48
  - lib/philosophal/property.rb
38
49
  - lib/philosophal/transform.rb
@@ -46,7 +57,7 @@ licenses:
46
57
  - GPL-3.0-only
47
58
  metadata:
48
59
  homepage_uri: https://github.com/RaoH37/philosophal
49
- source_code_uri: https://github.com/RaoH37/philosophal
60
+ bug_tracker_uri: https://github.com/RaoH37/philosophal/issues
50
61
  changelog_uri: https://github.com/RaoH37/philosophal/blob/main/CHANGELOG.md
51
62
  rubygems_mfa_required: 'true'
52
63
  post_install_message:
@@ -57,15 +68,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
68
  requirements:
58
69
  - - ">="
59
70
  - !ruby/object:Gem::Version
60
- version: '3.1'
71
+ version: '3.3'
61
72
  required_rubygems_version: !ruby/object:Gem::Requirement
62
73
  requirements:
63
74
  - - ">="
64
75
  - !ruby/object:Gem::Version
65
76
  version: '0'
66
77
  requirements: []
67
- rubygems_version: 3.3.27
78
+ rubygems_version: 3.5.22
68
79
  signing_key:
69
80
  specification_version: 4
70
- summary: Philosophal setter convertor
81
+ summary: Typed, auto-converting properties for Ruby classes
71
82
  test_files: []
data/.rubocop.yml DELETED
@@ -1,12 +0,0 @@
1
- require:
2
- - rubocop-minitest
3
- - rubocop-packaging
4
- - rubocop-performance
5
- - rubocop-md
6
-
7
- AllCops:
8
- TargetRubyVersion: 3.1
9
- NewCops: enable
10
-
11
- Style/Documentation:
12
- Enabled: false
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 3.1.7
data/.tool-versions DELETED
@@ -1 +0,0 @@
1
- ruby 3.1.7
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'minitest/test_task'
5
-
6
- Minitest::TestTask.create
7
-
8
- require 'rubocop/rake_task'
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[test rubocop]
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.2.0