cmdx 1.1.2 → 1.5.1
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 +4 -4
- data/.DS_Store +0 -0
- data/.cursor/prompts/docs.md +4 -1
- data/.cursor/prompts/llms.md +20 -0
- data/.cursor/prompts/rspec.md +4 -1
- data/.cursor/prompts/yardoc.md +3 -2
- data/.cursor/rules/cursor-instructions.mdc +55 -1
- data/.irbrc +6 -0
- data/.rubocop.yml +29 -18
- data/CHANGELOG.md +11 -132
- data/LLM.md +3317 -0
- data/README.md +68 -44
- data/docs/attributes/coercions.md +162 -0
- data/docs/attributes/defaults.md +90 -0
- data/docs/attributes/definitions.md +281 -0
- data/docs/attributes/naming.md +78 -0
- data/docs/attributes/validations.md +309 -0
- data/docs/basics/chain.md +56 -249
- data/docs/basics/context.md +56 -289
- data/docs/basics/execution.md +114 -0
- data/docs/basics/setup.md +37 -334
- data/docs/callbacks.md +89 -467
- data/docs/deprecation.md +91 -174
- data/docs/getting_started.md +212 -202
- data/docs/internationalization.md +11 -647
- data/docs/interruptions/exceptions.md +23 -198
- data/docs/interruptions/faults.md +71 -151
- data/docs/interruptions/halt.md +109 -186
- data/docs/logging.md +44 -256
- data/docs/middlewares.md +113 -426
- data/docs/outcomes/result.md +81 -228
- data/docs/outcomes/states.md +33 -221
- data/docs/outcomes/statuses.md +21 -311
- data/docs/tips_and_tricks.md +120 -70
- data/docs/workflows.md +99 -283
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/attribute.rb +229 -0
- data/lib/cmdx/attribute_registry.rb +94 -0
- data/lib/cmdx/attribute_value.rb +193 -0
- data/lib/cmdx/callback_registry.rb +69 -77
- data/lib/cmdx/chain.rb +56 -73
- data/lib/cmdx/coercion_registry.rb +52 -68
- data/lib/cmdx/coercions/array.rb +19 -18
- data/lib/cmdx/coercions/big_decimal.rb +20 -24
- data/lib/cmdx/coercions/boolean.rb +26 -25
- data/lib/cmdx/coercions/complex.rb +21 -22
- data/lib/cmdx/coercions/date.rb +25 -23
- data/lib/cmdx/coercions/date_time.rb +24 -25
- data/lib/cmdx/coercions/float.rb +25 -22
- data/lib/cmdx/coercions/hash.rb +31 -32
- data/lib/cmdx/coercions/integer.rb +30 -24
- data/lib/cmdx/coercions/rational.rb +29 -24
- data/lib/cmdx/coercions/string.rb +19 -22
- data/lib/cmdx/coercions/symbol.rb +37 -0
- data/lib/cmdx/coercions/time.rb +26 -25
- data/lib/cmdx/configuration.rb +49 -108
- data/lib/cmdx/context.rb +222 -44
- data/lib/cmdx/deprecator.rb +61 -0
- data/lib/cmdx/errors.rb +42 -252
- data/lib/cmdx/exceptions.rb +39 -0
- data/lib/cmdx/faults.rb +78 -39
- data/lib/cmdx/freezer.rb +51 -0
- data/lib/cmdx/identifier.rb +30 -0
- data/lib/cmdx/locale.rb +52 -0
- data/lib/cmdx/log_formatters/json.rb +21 -22
- data/lib/cmdx/log_formatters/key_value.rb +20 -22
- data/lib/cmdx/log_formatters/line.rb +15 -22
- data/lib/cmdx/log_formatters/logstash.rb +22 -23
- data/lib/cmdx/log_formatters/raw.rb +16 -22
- data/lib/cmdx/middleware_registry.rb +70 -74
- data/lib/cmdx/middlewares/correlate.rb +90 -54
- data/lib/cmdx/middlewares/runtime.rb +58 -0
- data/lib/cmdx/middlewares/timeout.rb +48 -68
- data/lib/cmdx/railtie.rb +12 -45
- data/lib/cmdx/result.rb +229 -314
- data/lib/cmdx/task.rb +194 -366
- data/lib/cmdx/utils/call.rb +49 -0
- data/lib/cmdx/utils/condition.rb +71 -0
- data/lib/cmdx/utils/format.rb +61 -0
- data/lib/cmdx/validator_registry.rb +63 -72
- data/lib/cmdx/validators/exclusion.rb +38 -67
- data/lib/cmdx/validators/format.rb +48 -49
- data/lib/cmdx/validators/inclusion.rb +43 -74
- data/lib/cmdx/validators/length.rb +101 -162
- data/lib/cmdx/validators/numeric.rb +95 -170
- data/lib/cmdx/validators/presence.rb +37 -50
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx/worker.rb +178 -0
- data/lib/cmdx/workflow.rb +85 -81
- data/lib/cmdx.rb +19 -13
- data/lib/generators/cmdx/install_generator.rb +14 -13
- data/lib/generators/cmdx/task_generator.rb +25 -50
- data/lib/generators/cmdx/templates/install.rb +11 -46
- data/lib/generators/cmdx/templates/task.rb.tt +3 -2
- data/lib/locales/en.yml +18 -4
- data/src/cmdx-logo.png +0 -0
- metadata +32 -116
- data/docs/ai_prompts.md +0 -393
- data/docs/basics/call.md +0 -317
- data/docs/configuration.md +0 -344
- data/docs/parameters/coercions.md +0 -396
- data/docs/parameters/defaults.md +0 -335
- data/docs/parameters/definitions.md +0 -446
- data/docs/parameters/namespacing.md +0 -378
- data/docs/parameters/validations.md +0 -405
- data/docs/testing.md +0 -553
- data/lib/cmdx/callback.rb +0 -53
- data/lib/cmdx/chain_inspector.rb +0 -56
- data/lib/cmdx/chain_serializer.rb +0 -63
- data/lib/cmdx/coercion.rb +0 -57
- data/lib/cmdx/coercions/virtual.rb +0 -29
- data/lib/cmdx/core_ext/hash.rb +0 -83
- data/lib/cmdx/core_ext/module.rb +0 -98
- data/lib/cmdx/core_ext/object.rb +0 -125
- data/lib/cmdx/correlator.rb +0 -122
- data/lib/cmdx/error.rb +0 -67
- data/lib/cmdx/fault.rb +0 -140
- data/lib/cmdx/immutator.rb +0 -52
- data/lib/cmdx/lazy_struct.rb +0 -246
- data/lib/cmdx/log_formatters/pretty_json.rb +0 -40
- data/lib/cmdx/log_formatters/pretty_key_value.rb +0 -38
- data/lib/cmdx/log_formatters/pretty_line.rb +0 -41
- data/lib/cmdx/logger.rb +0 -49
- data/lib/cmdx/logger_ansi.rb +0 -68
- data/lib/cmdx/logger_serializer.rb +0 -116
- data/lib/cmdx/middleware.rb +0 -70
- data/lib/cmdx/parameter.rb +0 -312
- data/lib/cmdx/parameter_evaluator.rb +0 -231
- data/lib/cmdx/parameter_inspector.rb +0 -66
- data/lib/cmdx/parameter_registry.rb +0 -106
- data/lib/cmdx/parameter_serializer.rb +0 -59
- data/lib/cmdx/result_ansi.rb +0 -71
- data/lib/cmdx/result_inspector.rb +0 -71
- data/lib/cmdx/result_logger.rb +0 -59
- data/lib/cmdx/result_serializer.rb +0 -104
- data/lib/cmdx/rspec/matchers.rb +0 -28
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +0 -42
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +0 -57
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +0 -87
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +0 -51
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +0 -58
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/have_context.rb +0 -86
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +0 -54
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +0 -52
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +0 -114
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +0 -66
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +0 -64
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +0 -78
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +0 -76
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +0 -62
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +0 -85
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +0 -68
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +0 -92
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +0 -46
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +0 -181
- data/lib/cmdx/task_deprecator.rb +0 -58
- data/lib/cmdx/task_processor.rb +0 -246
- data/lib/cmdx/task_serializer.rb +0 -57
- data/lib/cmdx/utils/ansi_color.rb +0 -73
- data/lib/cmdx/utils/log_timestamp.rb +0 -36
- data/lib/cmdx/utils/monotonic_runtime.rb +0 -34
- data/lib/cmdx/utils/name_affix.rb +0 -52
- data/lib/cmdx/validator.rb +0 -57
- data/lib/generators/cmdx/templates/workflow.rb.tt +0 -7
- data/lib/generators/cmdx/workflow_generator.rb +0 -84
- data/lib/locales/ar.yml +0 -35
- data/lib/locales/cs.yml +0 -35
- data/lib/locales/da.yml +0 -35
- data/lib/locales/de.yml +0 -35
- data/lib/locales/el.yml +0 -35
- data/lib/locales/es.yml +0 -35
- data/lib/locales/fi.yml +0 -35
- data/lib/locales/fr.yml +0 -35
- data/lib/locales/he.yml +0 -35
- data/lib/locales/hi.yml +0 -35
- data/lib/locales/it.yml +0 -35
- data/lib/locales/ja.yml +0 -35
- data/lib/locales/ko.yml +0 -35
- data/lib/locales/nl.yml +0 -35
- data/lib/locales/no.yml +0 -35
- data/lib/locales/pl.yml +0 -35
- data/lib/locales/pt.yml +0 -35
- data/lib/locales/ru.yml +0 -35
- data/lib/locales/sv.yml +0 -35
- data/lib/locales/th.yml +0 -35
- data/lib/locales/tr.yml +0 -35
- data/lib/locales/vi.yml +0 -35
- data/lib/locales/zh.yml +0 -35
data/docs/parameters/defaults.md
DELETED
@@ -1,335 +0,0 @@
|
|
1
|
-
# Parameters - Defaults
|
2
|
-
|
3
|
-
Parameter defaults provide fallback values when arguments are not provided or resolve to `nil`. Defaults ensure tasks have sensible values for optional parameters while maintaining flexibility for callers to override when needed.
|
4
|
-
|
5
|
-
## Table of Contents
|
6
|
-
|
7
|
-
- [TLDR](#tldr)
|
8
|
-
- [Default Fundamentals](#default-fundamentals)
|
9
|
-
- [Dynamic Defaults](#dynamic-defaults)
|
10
|
-
- [Defaults with Coercion and Validation](#defaults-with-coercion-and-validation)
|
11
|
-
- [Nested Parameter Defaults](#nested-parameter-defaults)
|
12
|
-
- [Error Handling](#error-handling)
|
13
|
-
|
14
|
-
## TLDR
|
15
|
-
|
16
|
-
```ruby
|
17
|
-
# Fixed defaults
|
18
|
-
optional :priority, default: "normal"
|
19
|
-
optional :retries, type: :integer, default: 3
|
20
|
-
optional :tags, type: :array, default: []
|
21
|
-
|
22
|
-
# Dynamic defaults
|
23
|
-
optional :created_at, default: -> { Time.now }
|
24
|
-
optional :template, default: :determine_template
|
25
|
-
|
26
|
-
# With coercion - defaults are coerced too
|
27
|
-
optional :max_items, type: :integer, default: "50" # → 50
|
28
|
-
|
29
|
-
# Nested defaults
|
30
|
-
optional :config, type: :hash, default: {} do
|
31
|
-
optional :timeout, default: 30
|
32
|
-
end
|
33
|
-
```
|
34
|
-
|
35
|
-
## Default Fundamentals
|
36
|
-
|
37
|
-
> [!NOTE]
|
38
|
-
> Defaults apply when parameters are not provided or resolve to `nil`. They work seamlessly with coercion, validation, and nested parameters.
|
39
|
-
|
40
|
-
```ruby
|
41
|
-
class ProcessOrderTask < CMDx::Task
|
42
|
-
required :order_id, type: :integer
|
43
|
-
|
44
|
-
# Fixed value defaults
|
45
|
-
optional :priority, default: "standard"
|
46
|
-
optional :send_email, type: :boolean, default: true
|
47
|
-
optional :max_retries, type: :integer, default: 3
|
48
|
-
optional :tags, type: :array, default: []
|
49
|
-
optional :metadata, type: :hash, default: {}
|
50
|
-
|
51
|
-
def call
|
52
|
-
# Defaults used when parameters not provided
|
53
|
-
process_order_with_priority(priority) # "standard"
|
54
|
-
send_notification if send_email # true
|
55
|
-
retry_failed_steps(max_retries) # 3
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# Using defaults
|
60
|
-
ProcessOrderTask.call(order_id: 123)
|
61
|
-
# priority: "standard", send_email: true, max_retries: 3
|
62
|
-
|
63
|
-
# Overriding defaults
|
64
|
-
ProcessOrderTask.call(
|
65
|
-
order_id: 123,
|
66
|
-
priority: "urgent",
|
67
|
-
send_email: false,
|
68
|
-
tags: ["rush"]
|
69
|
-
)
|
70
|
-
```
|
71
|
-
|
72
|
-
## Dynamic Defaults
|
73
|
-
|
74
|
-
> [!TIP]
|
75
|
-
> Use procs, lambdas, or method symbols for dynamic defaults evaluated at runtime. Essential for timestamps, UUIDs, and context-dependent values.
|
76
|
-
|
77
|
-
```ruby
|
78
|
-
class SendNotificationTask < CMDx::Task
|
79
|
-
required :user_id, type: :integer
|
80
|
-
required :message, type: :string
|
81
|
-
|
82
|
-
# Proc defaults - evaluated when accessed
|
83
|
-
optional :sent_at, type: :datetime, default: -> { Time.now }
|
84
|
-
optional :tracking_id, default: -> { SecureRandom.uuid }
|
85
|
-
|
86
|
-
# Environment-aware defaults
|
87
|
-
optional :service, default: -> { Rails.env.production? ? "sendgrid" : "test" }
|
88
|
-
|
89
|
-
# Method symbol defaults
|
90
|
-
optional :template, default: :default_template
|
91
|
-
optional :priority, default: :calculate_priority
|
92
|
-
|
93
|
-
def call
|
94
|
-
notification = {
|
95
|
-
message: message,
|
96
|
-
sent_at: sent_at, # Current time when accessed
|
97
|
-
tracking_id: tracking_id, # Unique UUID when accessed
|
98
|
-
template: template, # Result of default_template method
|
99
|
-
priority: priority # Result of calculate_priority method
|
100
|
-
}
|
101
|
-
|
102
|
-
NotificationService.send(notification, service: service)
|
103
|
-
end
|
104
|
-
|
105
|
-
private
|
106
|
-
|
107
|
-
def default_template
|
108
|
-
user.premium? ? "premium_notification" : "standard_notification"
|
109
|
-
end
|
110
|
-
|
111
|
-
def calculate_priority
|
112
|
-
user.vip? ? "high" : "normal"
|
113
|
-
end
|
114
|
-
|
115
|
-
def user
|
116
|
-
@user ||= User.find(user_id)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
```
|
120
|
-
|
121
|
-
## Defaults with Coercion and Validation
|
122
|
-
|
123
|
-
> [!IMPORTANT]
|
124
|
-
> Defaults are subject to the same coercion and validation rules as provided values, ensuring consistency and catching configuration errors early.
|
125
|
-
|
126
|
-
### Coercion with Defaults
|
127
|
-
|
128
|
-
```ruby
|
129
|
-
class ConfigureServiceTask < CMDx::Task
|
130
|
-
# String defaults coerced to target types
|
131
|
-
optional :max_connections, type: :integer, default: "100"
|
132
|
-
optional :config, type: :hash, default: '{"timeout": 30}'
|
133
|
-
optional :allowed_hosts, type: :array, default: '["localhost"]'
|
134
|
-
optional :debug_mode, type: :boolean, default: "false"
|
135
|
-
|
136
|
-
# Dynamic defaults with coercion
|
137
|
-
optional :session_id, type: :string, default: -> { Time.now.to_i }
|
138
|
-
|
139
|
-
def call
|
140
|
-
max_connections # → 100 (Integer from "100")
|
141
|
-
config # → {"timeout" => 30} (Hash from JSON)
|
142
|
-
allowed_hosts # → ["localhost"] (Array from JSON)
|
143
|
-
debug_mode # → false (Boolean from "false")
|
144
|
-
session_id # → "1640995200" (String from Integer)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
```
|
148
|
-
|
149
|
-
### Validation with Defaults
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
class ScheduleTaskTask < CMDx::Task
|
153
|
-
required :task_name, type: :string
|
154
|
-
|
155
|
-
# Default must pass validation rules
|
156
|
-
optional :priority, default: "medium",
|
157
|
-
inclusion: { in: %w[low medium high urgent] }
|
158
|
-
|
159
|
-
optional :timeout, type: :integer, default: 300,
|
160
|
-
numeric: { min: 60, max: 3600 }
|
161
|
-
|
162
|
-
optional :retry_count, type: :integer, default: 3,
|
163
|
-
numeric: { min: 0, max: 10 }
|
164
|
-
|
165
|
-
def call
|
166
|
-
# All defaults validated against their rules
|
167
|
-
schedule_task(task_name, priority: priority, timeout: timeout)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Invalid default would cause validation error
|
172
|
-
# optional :priority, default: "invalid", inclusion: { in: %w[low medium high] }
|
173
|
-
# → CMDx::ValidationError: priority invalid is not included in the list
|
174
|
-
```
|
175
|
-
|
176
|
-
## Nested Parameter Defaults
|
177
|
-
|
178
|
-
```ruby
|
179
|
-
class ProcessPaymentTask < CMDx::Task
|
180
|
-
required :amount, type: :float
|
181
|
-
required :user_id, type: :integer
|
182
|
-
|
183
|
-
# Nested structure with defaults at multiple levels
|
184
|
-
optional :payment_config, type: :hash, default: {} do
|
185
|
-
optional :method, default: "credit_card"
|
186
|
-
optional :currency, default: "USD"
|
187
|
-
optional :require_cvv, type: :boolean, default: true
|
188
|
-
|
189
|
-
optional :billing_address, type: :hash, default: -> { user_default_address } do
|
190
|
-
optional :country, default: "US"
|
191
|
-
optional :state, default: -> { user_default_state }
|
192
|
-
end
|
193
|
-
|
194
|
-
optional :notification_settings, type: :hash, default: {} do
|
195
|
-
optional :send_receipt, type: :boolean, default: true
|
196
|
-
optional :send_sms, type: :boolean, default: false
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def call
|
201
|
-
# Process payment with defaults applied at each level
|
202
|
-
PaymentProcessor.charge(
|
203
|
-
amount: amount,
|
204
|
-
method: payment_config[:method], # "credit_card"
|
205
|
-
currency: payment_config[:currency], # "USD"
|
206
|
-
billing_address: payment_config[:billing_address],
|
207
|
-
notifications: payment_config[:notification_settings]
|
208
|
-
)
|
209
|
-
end
|
210
|
-
|
211
|
-
private
|
212
|
-
|
213
|
-
def user
|
214
|
-
@user ||= User.find(user_id)
|
215
|
-
end
|
216
|
-
|
217
|
-
def user_default_address
|
218
|
-
user.billing_address&.to_hash || {}
|
219
|
-
end
|
220
|
-
|
221
|
-
def user_default_state
|
222
|
-
user.billing_address&.state || "CA"
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
# Usage with nested defaults
|
227
|
-
ProcessPaymentTask.call(amount: 99.99, user_id: 123)
|
228
|
-
# payment_config automatically gets:
|
229
|
-
# {
|
230
|
-
# method: "credit_card",
|
231
|
-
# currency: "USD",
|
232
|
-
# require_cvv: true,
|
233
|
-
# billing_address: { country: "US", state: "CA" },
|
234
|
-
# notification_settings: { send_receipt: true, send_sms: false }
|
235
|
-
# }
|
236
|
-
```
|
237
|
-
|
238
|
-
## Error Handling
|
239
|
-
|
240
|
-
> [!WARNING]
|
241
|
-
> Default values that fail coercion or validation will cause task execution to fail with detailed error information.
|
242
|
-
|
243
|
-
### Validation Errors with Defaults
|
244
|
-
|
245
|
-
```ruby
|
246
|
-
class BadDefaultsTask < CMDx::Task
|
247
|
-
# This default will fail validation
|
248
|
-
optional :priority, default: "invalid",
|
249
|
-
inclusion: { in: %w[low medium high] }
|
250
|
-
|
251
|
-
# This default will fail coercion
|
252
|
-
optional :count, type: :integer, default: "not-a-number"
|
253
|
-
|
254
|
-
def call
|
255
|
-
# Won't reach here due to validation/coercion failures
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
result = BadDefaultsTask.call
|
260
|
-
result.failed? # → true
|
261
|
-
result.metadata
|
262
|
-
# {
|
263
|
-
# reason: "priority invalid is not included in the list. count could not coerce into an integer.",
|
264
|
-
# messages: {
|
265
|
-
# priority: ["invalid is not included in the list"],
|
266
|
-
# count: ["could not coerce into an integer"]
|
267
|
-
# }
|
268
|
-
# }
|
269
|
-
```
|
270
|
-
|
271
|
-
### Dynamic Default Errors
|
272
|
-
|
273
|
-
```ruby
|
274
|
-
class ProblematicDefaultsTask < CMDx::Task
|
275
|
-
# Method that might raise an error
|
276
|
-
optional :config, default: :load_external_config
|
277
|
-
|
278
|
-
# Proc that might fail
|
279
|
-
optional :api_key, default: -> { fetch_api_key_from_vault }
|
280
|
-
|
281
|
-
def call
|
282
|
-
# Task logic
|
283
|
-
end
|
284
|
-
|
285
|
-
private
|
286
|
-
|
287
|
-
def load_external_config
|
288
|
-
# This might raise if external service is down
|
289
|
-
ExternalConfigService.fetch_config
|
290
|
-
rescue => e
|
291
|
-
raise CMDx::Error, "Failed to load default config: #{e.message}"
|
292
|
-
end
|
293
|
-
|
294
|
-
def fetch_api_key_from_vault
|
295
|
-
# This might raise if vault is unavailable
|
296
|
-
VaultService.get_secret("api_key")
|
297
|
-
rescue => e
|
298
|
-
raise CMDx::Error, "Failed to fetch default API key: #{e.message}"
|
299
|
-
end
|
300
|
-
end
|
301
|
-
```
|
302
|
-
|
303
|
-
### Nil vs Missing Parameters
|
304
|
-
|
305
|
-
```ruby
|
306
|
-
class NilHandlingTask < CMDx::Task
|
307
|
-
optional :status, default: "active"
|
308
|
-
optional :tags, type: :array, default: []
|
309
|
-
|
310
|
-
def call
|
311
|
-
status # Default applied based on input
|
312
|
-
tags # Default applied based on input
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
# Missing parameters use defaults
|
317
|
-
NilHandlingTask.call
|
318
|
-
# status: "active", tags: []
|
319
|
-
|
320
|
-
# Explicitly nil parameters also use defaults
|
321
|
-
NilHandlingTask.call(status: nil, tags: nil)
|
322
|
-
# status: "active", tags: []
|
323
|
-
|
324
|
-
# Empty string is NOT nil - no default applied
|
325
|
-
NilHandlingTask.call(status: "", tags: "")
|
326
|
-
# status: "", tags: "" (string, not array - may cause coercion error)
|
327
|
-
```
|
328
|
-
|
329
|
-
> [!TIP]
|
330
|
-
> Defaults only apply to `nil` values. Empty strings, empty arrays, or false values are considered valid inputs and won't trigger defaults.
|
331
|
-
|
332
|
-
---
|
333
|
-
|
334
|
-
- **Prev:** [Parameters - Validations](validations.md)
|
335
|
-
- **Next:** [Callbacks](../callbacks.md)
|