prop_initializer 0.4.0 → 0.5.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: 96c417df7010839148ad78bae4904f00cc9fd4384a35acb7745633b818beb8bd
4
- data.tar.gz: ec4a050a9ef18d35e878675f44e93f0df30f076bd67b7d59a261cdd0449c0cc1
3
+ metadata.gz: 4dc72d5e414e9bd4690aeab766d53f8d00258f9a917ad40ca74300acab1cec12
4
+ data.tar.gz: '068996afcdb7cb460c9fcf90b8bec7b30b5694675628b1f9efc0799b6e6e9aaa'
5
5
  SHA512:
6
- metadata.gz: 944054343092908cf84a2a7e2f072ab1d6536ed943182d25714b80f68818afc68bc35cc0b95a8b7e92261938db453eb66fe40a2a84ccfb174e3b231943ac6124
7
- data.tar.gz: fd1e6b8d424d7c8ff1b28461e2bc99b9acf263fd38eef77d5f17169ee94275f4ddcf2e39af1e5654ec9135466ab757d78a9bbef666eb9026bf09b9c3903954ac
6
+ metadata.gz: b9393c607fb3f5fcf2e2cac36d69ea4bd07c5bcdad53954e32b34f599ce037f86ccacae6d050312b5b2a879e558521aad77113a94548c64ed371f5fb4f43f1ee
7
+ data.tar.gz: 14ec41b36d29501ef2e8cf8f58993a5f63d0549c3eebc8e182ee3e49c27b15e4522db669919c28caddb788e82361ece5bd1a9f6dee99dce7ab32c3de6d4e44e3
data/README.md CHANGED
@@ -2,19 +2,19 @@
2
2
 
3
3
  # Prop Initializer
4
4
 
5
+ ![prop_initializer: properties for any Ruby class. One prop line per property; the initializer, readers, writers and to_h are generated once, when the class loads. Built on Literal, used by Avo's components. Left: a ButtonComponent declaring props with a positional kind, a public reader, a default, a proc default and a coercion block. Right: the initialize, attr_reader and to_h it generates. Below, five notes: every argument kind; defaults; coercion blocks; readers, writers and predicates; after_initialize.](./banner.png)
6
+
5
7
  ## Overview
6
8
 
7
9
  The `prop_initializer` gem is a flexible tool for defining properties on Ruby classes.
8
10
 
9
- ![](./logo.png)
10
-
11
11
  It's a fork of the [Literal Gem](https://github.com/joeldrapper/literal), with a few tweaks. We sincerely thank [Joel Drapper](https://github.com/joeldrapper) for the inspiration and base code that made this possible.
12
12
 
13
13
  With `prop_initializer`, you can easily declare properties for any class, giving you flexible options for default values and more. However, the scope is narrowed down by removing strict typing requirements, providing a more lightweight and adaptable interface.
14
14
 
15
15
  ## Installation
16
16
 
17
- To use `prop_initializer ` in your Ruby project, add the following to your Gemfile:
17
+ To use `prop_initializer` in your Ruby project, add the following to your Gemfile:
18
18
 
19
19
  ```ruby
20
20
  gem "prop_initializer"
@@ -28,7 +28,7 @@ bundle install
28
28
 
29
29
  ## Usage
30
30
 
31
- To start using `prop_initializer `, you need to include the module in the class where you want to define properties.
31
+ To start using `prop_initializer`, you need to extend the class with the module where you want to define properties.
32
32
 
33
33
  ### Step 1: Extend the Properties Module
34
34
 
@@ -42,7 +42,7 @@ end
42
42
 
43
43
  ### Step 2: Define Properties
44
44
 
45
- Properties can be declared using the `prop` method, which generates writers and makes them available as instance variables (e.g., `@name`, `@size`, etc.).
45
+ Properties can be declared using the `prop` method. The generated initializer assigns each one to an instance variable (e.g., `@name`, `@size`, etc.).
46
46
 
47
47
  #### Basic Syntax:
48
48
 
@@ -53,6 +53,13 @@ prop :args, kind: :* # A property for handling splat arguments
53
53
  prop :kwargs, kind: :** # A property for handling keyword arguments
54
54
  ```
55
55
 
56
+ A default must be a frozen value or a proc. A proc runs on each new instance once the positional and splat properties, and the keyword properties declared before it, are assigned, so it can read them:
57
+
58
+ ```ruby
59
+ prop :count, default: 2
60
+ prop :items, default: -> { Array.new(@count) }
61
+ ```
62
+
56
63
  #### Custom Property with Block:
57
64
 
58
65
  You can define a custom processing block when declaring a property, for example:
@@ -65,7 +72,7 @@ end
65
72
 
66
73
  ### Step 3: Accessing Properties
67
74
 
68
- By default, `PropInitializer` generates a writer for each declared property. The properties are stored as instance variables, which can be accessed within the class:
75
+ By default, `PropInitializer` generates no reader or writer. The properties are stored as instance variables, which can be accessed within the class:
69
76
 
70
77
  ```ruby
71
78
  @name # Accesses the value of the 'name' property
@@ -86,6 +93,14 @@ This will automatically generate a public getter method, allowing you to retriev
86
93
  my_class_instance.title # Public getter for the 'title' property
87
94
  ```
88
95
 
96
+ #### Writer and Predicate:
97
+
98
+ `writer: :public` adds a setter and `predicate: :public` a `title?` method. A setter runs the property's block, if it has one, the same way the initializer does.
99
+
100
+ #### after_initialize:
101
+
102
+ Define `after_initialize`, public or private, and it runs once every property is assigned.
103
+
89
104
  ### Example:
90
105
 
91
106
  ```ruby
data/Rakefile CHANGED
@@ -1,3 +1,9 @@
1
- require "bundler/setup"
2
-
3
1
  require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList["test/**/*_test.rb"]
7
+ end
8
+
9
+ task default: :test
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PropInitializer::Null
4
- def self.inspect
5
- "PropInitializer::Null"
6
- end
4
+ def self.inspect
5
+ "PropInitializer::Null"
6
+ end
7
7
 
8
- freeze
8
+ freeze
9
9
  end
@@ -2,118 +2,125 @@
2
2
 
3
3
  # @api private
4
4
  class PropInitializer::Properties::Schema
5
- include Enumerable
6
-
7
- def initialize(properties_index: {}, sorted_properties: [])
8
- @properties_index = properties_index
9
- @sorted_properties = sorted_properties
10
- @mutex = Mutex.new
11
- end
12
-
13
- attr_reader :properties_index
14
-
15
- def [](key)
16
- @properties_index[key]
17
- end
18
-
19
- def <<(value)
20
- @mutex.synchronize do
21
- @properties_index[value.name] = value
22
- # ruby's sort is unstable, this trick makes it stable
23
- n = 0
24
- @sorted_properties = @properties_index.values.sort_by! { |it| n += 1; [it, n] }
25
- end
26
-
27
- self
28
- end
29
-
30
- def dup
31
- self.class.new(
32
- properties_index: @properties_index.dup,
33
- sorted_properties: @sorted_properties.dup,
34
- )
35
- end
36
-
37
- def each(&)
38
- @sorted_properties.each(&)
39
- end
40
-
41
- def size
42
- @sorted_properties.size
43
- end
44
-
45
- def generate_initializer(buffer = +"")
46
- buffer << "def initialize(#{generate_initializer_params})\n"
47
- generate_initializer_body(buffer)
48
- buffer << "" \
49
- " after_initialize if respond_to?(:after_initialize)\n" \
50
- "end\n"
51
- end
52
-
53
- def generate_to_h(buffer = +"")
54
- buffer << "def to_h\n" << " {\n"
55
-
56
- sorted_properties = @sorted_properties
57
- i, n = 0, sorted_properties.size
58
- while i < n
59
- property = sorted_properties[i]
60
- buffer << " " << property.name.name << ": @" << property.name.name << ",\n"
61
- i += 1
62
- end
63
-
64
- buffer << " }\n" << "end\n"
65
- end
66
-
67
- private
68
-
69
- def generate_initializer_params(buffer = +"")
70
- sorted_properties = @sorted_properties
71
- i, n = 0, sorted_properties.size
72
- while i < n
73
- property = sorted_properties[i]
74
-
75
- case property.kind
76
- when :*
77
- buffer << "*" << property.escaped_name
78
- when :**
79
- buffer << "**" << property.escaped_name
80
- when :&
81
- buffer << "&" << property.escaped_name
82
- when :positional
83
- if property.default?
84
- buffer << property.escaped_name << " = PropInitializer::Null"
85
- else
86
- buffer << property.escaped_name << " = nil"
87
- end
88
- when :keyword
89
- if property.default?
90
- buffer << property.name.name << ": PropInitializer::Null"
91
- else
92
- buffer << property.name.name << ": nil"
93
- end
94
- else
95
- raise "You should never see this error."
96
- end
97
-
98
- i += 1
99
- buffer << ", " if i < n
100
- end
101
-
102
- buffer
103
- end
104
-
105
- def generate_initializer_body(buffer = +"")
106
- buffer << " properties = self.class.prop_initializer_properties.properties_index\n"
107
- generate_initializer_handle_properties(@sorted_properties, buffer)
108
- end
109
-
110
- def generate_initializer_handle_properties(properties, buffer = +"")
111
- i, n = 0, properties.size
112
- while i < n
113
- properties[i].generate_initializer_handle_property(buffer)
114
- i += 1
115
- end
116
-
117
- buffer
118
- end
5
+ include Enumerable
6
+
7
+ def initialize(properties_index: {}, sorted_properties: [])
8
+ @properties_index = properties_index
9
+ @sorted_properties = sorted_properties
10
+ @mutex = Mutex.new
11
+ end
12
+
13
+ attr_reader :properties_index
14
+
15
+ def [](key)
16
+ @properties_index[key]
17
+ end
18
+
19
+ def <<(value)
20
+ @mutex.synchronize do
21
+ @properties_index[value.name] = value
22
+ # ruby's sort is unstable, this trick makes it stable
23
+ n = 0
24
+ @sorted_properties = @properties_index.values.sort_by! { |it| n += 1; [ it, n ] }
25
+ end
26
+
27
+ self
28
+ end
29
+
30
+ def dup
31
+ self.class.new(
32
+ properties_index: @properties_index.dup,
33
+ sorted_properties: @sorted_properties.dup,
34
+ )
35
+ end
36
+
37
+ def each(&)
38
+ @sorted_properties.each(&)
39
+ end
40
+
41
+ def size
42
+ @sorted_properties.size
43
+ end
44
+
45
+ def generate_initializer(buffer = +"")
46
+ buffer << "alias initialize initialize\n" \
47
+ "def initialize(#{generate_initializer_params})\n"
48
+ generate_initializer_body(buffer)
49
+ buffer << "" \
50
+ " after_initialize() if respond_to?(:after_initialize, true)\n" \
51
+ "end\n"
52
+ end
53
+
54
+ def generate_to_h(buffer = +"")
55
+ buffer << "alias to_h to_h\n" \
56
+ "def to_h\n" << " {\n"
57
+
58
+ sorted_properties = @sorted_properties
59
+ i, n = 0, sorted_properties.size
60
+ while i < n
61
+ property = sorted_properties[i]
62
+ buffer << " " << property.name.name << ": @" << property.name.name << ",\n"
63
+ i += 1
64
+ end
65
+
66
+ buffer << " }\n" << "end\n"
67
+ end
68
+
69
+ private
70
+
71
+ def generate_initializer_params(buffer = +"")
72
+ sorted_properties = @sorted_properties
73
+ i, n = 0, sorted_properties.size
74
+ while i < n
75
+ property = sorted_properties[i]
76
+
77
+ case property.kind
78
+ when :*
79
+ buffer << "*" << property.escaped_name
80
+ when :**
81
+ buffer << "**" << property.escaped_name
82
+ when :&
83
+ buffer << "&" << property.escaped_name
84
+ when :positional
85
+ buffer << property.escaped_name << " = " << generate_initializer_default(property)
86
+ when :keyword
87
+ buffer << property.name.name << ": " << generate_initializer_default(property)
88
+ else
89
+ raise "You should never see this error."
90
+ end
91
+
92
+ i += 1
93
+ buffer << ", " if i < n
94
+ end
95
+
96
+ buffer
97
+ end
98
+
99
+ def generate_initializer_default(property)
100
+ if property.inline_default?
101
+ property.default.inspect
102
+ elsif property.default?
103
+ "PropInitializer::Null"
104
+ else
105
+ "nil"
106
+ end
107
+ end
108
+
109
+ def generate_initializer_body(buffer = +"")
110
+ if @sorted_properties.any?(&:lookup?)
111
+ buffer << " __pi_properties = self.class.prop_initializer_properties.properties_index\n"
112
+ end
113
+
114
+ generate_initializer_handle_properties(@sorted_properties, buffer)
115
+ end
116
+
117
+ def generate_initializer_handle_properties(properties, buffer = +"")
118
+ i, n = 0, properties.size
119
+ while i < n
120
+ properties[i].generate_initializer_handle_property(buffer)
121
+ i += 1
122
+ end
123
+
124
+ buffer
125
+ end
119
126
  end
@@ -13,7 +13,7 @@ module PropInitializer::Properties
13
13
  end
14
14
 
15
15
  unless PropInitializer::Property::VISIBILITY_OPTIONS.include?(predicate)
16
- raise ArgumentError.new(p"The predicate must be one of #{PropInitializer::Property::VISIBILITY_OPTIONS.map(&:inspect).join(', ')}.")
16
+ raise ArgumentError.new("The predicate must be one of #{PropInitializer::Property::VISIBILITY_OPTIONS.map(&:inspect).join(', ')}.")
17
17
  end
18
18
 
19
19
  if reader && :class == name
@@ -39,6 +39,8 @@ module PropInitializer::Properties
39
39
  prop_initializer_properties << property
40
40
  __define_prop_initializer_methods__(property)
41
41
  include(__prop__initializer_extension__)
42
+
43
+ name
42
44
  end
43
45
 
44
46
  def prop_initializer_properties
@@ -67,7 +69,17 @@ module PropInitializer::Properties
67
69
  if defined?(@__prop__initializer_extension__)
68
70
  @__prop__initializer_extension__
69
71
  else
70
- @__prop__initializer_extension__ = Module.new
72
+ @__prop__initializer_extension__ = Module.new do
73
+ set_temporary_name "PropInitializer::Properties(Extension)" if respond_to?(:set_temporary_name)
74
+
75
+ def initialize
76
+ after_initialize if respond_to?(:after_initialize, true)
77
+ end
78
+
79
+ def to_h
80
+ {}
81
+ end
82
+ end
71
83
  end
72
84
  end
73
85
 
@@ -1,184 +1,187 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class PropInitializer::Property
4
- ORDER = { :positional => 0, :* => 1, :keyword => 2, :** => 3, :& => 4 }.freeze
5
- RUBY_KEYWORDS = %i[alias and begin break case class def do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield].to_h { |k| [k, "__#{k}__"] }.freeze
6
- GENERATOR_PROPERTY_LOCAL = "__pi_prop"
7
-
8
- VISIBILITY_OPTIONS = Set[false, :private, :protected, :public].freeze
9
- KIND_OPTIONS = Set[:positional, :*, :keyword, :**, :&].freeze
10
-
11
- include Comparable
12
-
13
- def initialize(name:, kind:, reader:, writer:, predicate:, default:, coercion:)
14
- @name = name
15
- @kind = kind
16
- @reader = reader
17
- @writer = writer
18
- @predicate = predicate
19
- @default = default
20
- @coercion = coercion
21
- end
22
-
23
- attr_reader :name, :kind, :reader, :writer, :predicate, :default, :coercion
24
-
25
- def optional?
26
- default?
27
- end
28
-
29
- def required?
30
- !optional?
31
- end
32
-
33
- def keyword?
34
- @kind == :keyword
35
- end
36
-
37
- def positional?
38
- @kind == :positional
39
- end
40
-
41
- def splat?
42
- @kind == :*
43
- end
44
-
45
- def double_splat?
46
- @kind == :**
47
- end
48
-
49
- def block?
50
- @kind == :&
51
- end
52
-
53
- def default?
54
- nil != @default
55
- end
56
-
57
- def param
58
- case @kind
59
- when :*
60
- "*#{escaped_name}"
61
- when :**
62
- "**#{escaped_name}"
63
- when :&
64
- "&#{escaped_name}"
65
- when :positional
66
- escaped_name
67
- when :keyword
68
- "#{@name.name}:"
69
- else
70
- raise "You should never see this error."
71
- end
72
- end
73
-
74
- def <=>(other)
75
- ORDER[@kind] <=> ORDER[other.kind]
76
- end
77
-
78
- def coerce(value, context:)
79
- context.instance_exec(value, &@coercion)
80
- end
81
-
82
- def ruby_keyword?
83
- !!RUBY_KEYWORDS[@name]
84
- end
85
-
86
- def escaped_name
87
- RUBY_KEYWORDS[@name] || @name.name
88
- end
89
-
90
- def default_value
91
- case @default
92
- when Proc then @default.call
93
- else @default
94
- end
95
- end
96
-
97
- def generate_reader_method(buffer = +"")
98
- buffer <<
99
- (@reader ? @reader.name : "public") <<
100
- "\ndef " <<
101
- @name.name <<
102
- "\n value = @" <<
103
- @name.name <<
104
- "\n value\nend\n"
105
- end
106
-
107
- def generate_writer_method(buffer = +"")
108
- buffer <<
109
- (@writer ? @writer.name : "public") <<
110
- " def " <<
111
- @name.name <<
112
- "=(value)\n" <<
113
- " @#{@name.name} = value\nend\n"
114
- end
115
-
116
- def generate_predicate_method(buffer = +"")
117
- buffer <<
118
- (@predicate ? @predicate.name : "public") <<
119
- " def " <<
120
- @name.name <<
121
- "?\n" <<
122
- " !!@" <<
123
- @name.name <<
124
- "\n" <<
125
- "end\n"
126
- end
127
-
128
- def generate_initializer_handle_property(buffer = +"")
129
- buffer << " # " << @name.name << "\n" <<
130
- " #{GENERATOR_PROPERTY_LOCAL} = properties[:" << @name.name << "]\n"
131
-
132
- if @kind == :keyword && ruby_keyword?
133
- generate_initializer_escape_keyword(buffer)
134
- end
135
-
136
- if default?
137
- generate_initializer_assign_default(buffer)
138
- end
139
-
140
- if @coercion
141
- generate_initializer_coerce_property(buffer)
142
- end
143
-
144
- generate_initializer_assign_value(buffer)
145
- end
146
-
147
- private
148
-
149
- def generate_initializer_escape_keyword(buffer = +"")
150
- buffer <<
151
- escaped_name <<
152
- " = binding.local_variable_get(:" <<
153
- @name.name <<
154
- ")\n"
155
- end
156
-
157
- def generate_initializer_coerce_property(buffer = +"")
158
- buffer <<
159
- escaped_name <<
160
- "= #{GENERATOR_PROPERTY_LOCAL}.coerce(" <<
161
- escaped_name <<
162
- ", context: self)\n"
163
- end
164
-
165
- def generate_initializer_assign_default(buffer = +"")
166
- buffer <<
167
- " if " <<
168
- ((@kind == :&) ? "nil" : "PropInitializer::Null") <<
169
- " == " <<
170
- escaped_name <<
171
- "\n " <<
172
- escaped_name <<
173
- " = #{GENERATOR_PROPERTY_LOCAL}.default_value\n end\n"
174
- end
175
-
176
- def generate_initializer_assign_value(buffer = +"")
177
- buffer <<
178
- " @" <<
179
- @name.name <<
180
- " = " <<
181
- escaped_name <<
182
- "\n"
183
- end
4
+ ORDER = { :positional => 0, :* => 1, :keyword => 2, :** => 3, :& => 4 }.freeze
5
+ RUBY_KEYWORDS = %i[alias and begin break case class def do else elsif end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield].to_h { |k| [ k, "__#{k}__" ] }.freeze
6
+ GENERATOR_PROPERTY_LOCAL = "__pi_prop"
7
+
8
+ VISIBILITY_OPTIONS = Set[false, :private, :protected, :public].freeze
9
+ KIND_OPTIONS = Set[:positional, :*, :keyword, :**, :&].freeze
10
+
11
+ include Comparable
12
+
13
+ def initialize(name:, kind:, reader:, writer:, predicate:, default:, coercion:)
14
+ @name = name
15
+ @kind = kind
16
+ @reader = reader
17
+ @writer = writer
18
+ @predicate = predicate
19
+ @default = default
20
+ @coercion = coercion
21
+ end
22
+
23
+ attr_reader :name, :kind, :reader, :writer, :predicate, :default, :coercion
24
+
25
+ def optional?
26
+ default?
27
+ end
28
+
29
+ def required?
30
+ !optional?
31
+ end
32
+
33
+ def keyword?
34
+ @kind == :keyword
35
+ end
36
+
37
+ def positional?
38
+ @kind == :positional
39
+ end
40
+
41
+ def splat?
42
+ @kind == :*
43
+ end
44
+
45
+ def double_splat?
46
+ @kind == :**
47
+ end
48
+
49
+ def block?
50
+ @kind == :&
51
+ end
52
+
53
+ def default?
54
+ nil != @default
55
+ end
56
+
57
+ # Symbol, Integer, true and false go into the signature as literals, so the initializer never looks the
58
+ # property up. Not for a block parameter, and not for a Symbol the generated UTF-8 source cannot spell.
59
+ def inline_default?
60
+ return false unless positional? || keyword?
61
+
62
+ Integer === @default || true == @default || false == @default ||
63
+ (Symbol === @default && (Encoding::UTF_8 == @default.encoding || Encoding::US_ASCII == @default.encoding))
64
+ end
65
+
66
+ def lookup?
67
+ (default? && !inline_default?) || !!@coercion
68
+ end
69
+
70
+ def param
71
+ case @kind
72
+ when :*
73
+ "*#{escaped_name}"
74
+ when :**
75
+ "**#{escaped_name}"
76
+ when :&
77
+ "&#{escaped_name}"
78
+ when :positional
79
+ escaped_name
80
+ when :keyword
81
+ "#{@name.name}:"
82
+ else
83
+ raise "You should never see this error."
84
+ end
85
+ end
86
+
87
+ def <=>(other)
88
+ ORDER[@kind] <=> ORDER[other.kind]
89
+ end
90
+
91
+ def ruby_keyword?
92
+ !!RUBY_KEYWORDS[@name]
93
+ end
94
+
95
+ def escaped_name
96
+ RUBY_KEYWORDS[@name] || @name.name
97
+ end
98
+
99
+ def generate_reader_method(buffer = +"")
100
+ buffer << @reader.name << " attr_reader :" << @name.name << "\n"
101
+ end
102
+
103
+ def generate_writer_method(buffer = +"")
104
+ return buffer << @writer.name << " attr_writer :" << @name.name << "\n" unless @coercion
105
+
106
+ # Through self.class at call time, not captured: a subclass may redeclare the prop with another block,
107
+ # or with none, and still inherit this writer.
108
+ buffer <<
109
+ @writer.name << " def " << @name.name << "=(value)\n" \
110
+ " coercion = self.class.prop_initializer_properties[:" << @name.name << "].coercion\n" \
111
+ " @" << @name.name << " = coercion ? instance_exec(value, &coercion) : value\n" \
112
+ "end\n"
113
+ end
114
+
115
+ def generate_predicate_method(buffer = +"")
116
+ buffer <<
117
+ (@predicate ? @predicate.name : "public") <<
118
+ " def " <<
119
+ @name.name <<
120
+ "?\n" <<
121
+ " !!@" <<
122
+ @name.name <<
123
+ "\n" <<
124
+ "end\n"
125
+ end
126
+
127
+ def generate_initializer_handle_property(buffer = +"")
128
+ buffer << " # " << @name.name << "\n"
129
+
130
+ if lookup?
131
+ buffer << " #{GENERATOR_PROPERTY_LOCAL} = __pi_properties[:" << @name.name << "]\n"
132
+ end
133
+
134
+ if @kind == :keyword && ruby_keyword?
135
+ generate_initializer_escape_keyword(buffer)
136
+ end
137
+
138
+ if default? && !inline_default?
139
+ generate_initializer_assign_default(buffer)
140
+ end
141
+
142
+ if @coercion
143
+ generate_initializer_coerce_property(buffer)
144
+ end
145
+
146
+ generate_initializer_assign_value(buffer)
147
+ end
148
+
149
+ private
150
+
151
+ def generate_initializer_escape_keyword(buffer = +"")
152
+ buffer <<
153
+ escaped_name <<
154
+ " = ::Kernel.binding.local_variable_get(:" <<
155
+ @name.name <<
156
+ ")\n"
157
+ end
158
+
159
+ def generate_initializer_coerce_property(buffer = +"")
160
+ buffer <<
161
+ " " <<
162
+ escaped_name <<
163
+ " = instance_exec(" <<
164
+ escaped_name <<
165
+ ", &#{GENERATOR_PROPERTY_LOCAL}.coercion)\n"
166
+ end
167
+
168
+ def generate_initializer_assign_default(buffer = +"")
169
+ buffer <<
170
+ " if " <<
171
+ ((@kind == :&) ? "nil" : "PropInitializer::Null") <<
172
+ " == " <<
173
+ escaped_name <<
174
+ "\n " <<
175
+ escaped_name <<
176
+ " = " << (Proc === @default ? "instance_exec(&#{GENERATOR_PROPERTY_LOCAL}.default)" : "#{GENERATOR_PROPERTY_LOCAL}.default") << "\n end\n"
177
+ end
178
+
179
+ def generate_initializer_assign_value(buffer = +"")
180
+ buffer <<
181
+ " @" <<
182
+ @name.name <<
183
+ " = " <<
184
+ escaped_name <<
185
+ "\n"
186
+ end
184
187
  end
@@ -1,3 +1,3 @@
1
1
  module PropInitializer
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -1,5 +1,4 @@
1
1
  require "prop_initializer/version"
2
- require "prop_initializer/railtie"
3
2
 
4
3
  require "zeitwerk"
5
4
 
@@ -7,5 +6,4 @@ loader = Zeitwerk::Loader.for_gem
7
6
  loader.setup
8
7
 
9
8
  module PropInitializer
10
- # Your code goes here...
11
9
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prop_initializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Bob
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-05-11 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: zeitwerk
@@ -41,15 +40,12 @@ files:
41
40
  - lib/prop_initializer/properties.rb
42
41
  - lib/prop_initializer/properties/schema.rb
43
42
  - lib/prop_initializer/property.rb
44
- - lib/prop_initializer/railtie.rb
45
43
  - lib/prop_initializer/version.rb
46
- - lib/tasks/prop_initializer_tasks.rake
47
44
  homepage: https://github.com/avo-hq/prop_initializer
48
45
  licenses:
49
46
  - MIT
50
47
  metadata:
51
48
  homepage_uri: https://github.com/avo-hq/prop_initializer
52
- post_install_message:
53
49
  rdoc_options: []
54
50
  require_paths:
55
51
  - lib
@@ -57,15 +53,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
53
  requirements:
58
54
  - - ">="
59
55
  - !ruby/object:Gem::Version
60
- version: '0'
56
+ version: 3.2.0
61
57
  required_rubygems_version: !ruby/object:Gem::Requirement
62
58
  requirements:
63
59
  - - ">="
64
60
  - !ruby/object:Gem::Version
65
61
  version: '0'
66
62
  requirements: []
67
- rubygems_version: 3.5.22
68
- signing_key:
63
+ rubygems_version: 4.0.16
69
64
  specification_version: 4
70
65
  summary: A flexible property initializer for Ruby classes inspired by the Literal
71
66
  gem.
@@ -1,6 +0,0 @@
1
- require "rails/railtie"
2
-
3
- module PropInitializer
4
- class Railtie < ::Rails::Railtie
5
- end
6
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :prop_initializer do
3
- # # Task goes here
4
- # end