Module: StrictLazy
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/strict_lazy.rb,
lib/strict_lazy/batch.rb,
lib/strict_lazy/errors.rb,
lib/strict_lazy/facade.rb,
lib/strict_lazy/loader.rb,
lib/strict_lazy/railtie.rb,
lib/strict_lazy/version.rb
Overview
strict_lazy applies the spirit of Rails’ strict_loading to computed values. Include it in a model, declare values with lazy_load, prepare them in the controller with StrictLazy.preload, and read them via record.lazy.x. Reading without a preceding preload raises in development/test.
Defined Under Namespace
Classes: Batch, Error, Facade, Loader, Railtie, UnloadedError
Constant Summary collapse
- VALID_VIOLATIONS =
The accepted violation policies.
%i[raise log ignore].freeze
- READER_FORMAT =
A valid reader is a bare name, optionally a ‘?` predicate. Setter (`=`), bang (`!`), and operator readers are rejected: the `.lazy` namespace is read-only, and any other form has no valid ivar to back it.
/\A[A-Za-z_][A-Za-z0-9_]*\??\z/- VERSION =
"0.3.0"
Class Method Summary collapse
-
.preload(records, *readers) ⇒ Object
Prepare lazy values for a group of records.
-
.violation ⇒ Object
The effective policy for the current execution context: the innermost with_violation override if any, otherwise the global baseline.
-
.violation=(mode) ⇒ Object
Backward-compatible global setter.
-
.with_violation(mode) ⇒ Object
Run the block with
modeas the effective policy, restoring the previous state afterward (exception-safe).
Instance Method Summary collapse
-
#lazy ⇒ Object
The
.lazynamespace facade (memoized per record).
Class Method Details
.preload(records, *readers) ⇒ Object
Prepare lazy values for a group of records. With no readers, prepares every declared loader. sync: true loaders resolve immediately; others on first read.
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/strict_lazy.rb', line 135 def self.preload(records, *readers) records = Array(records) return records if records.empty? model = records.first.class loaders_for(model, readers).each do |loader| batch = Batch.new(model, records, loader) records.each { |record| record.instance_variable_set(loader.batch_ivar, batch) } batch.resolve! if loader.sync? end records end |
.violation ⇒ Object
The effective policy for the current execution context: the innermost with_violation override if any, otherwise the global baseline. The facade consults this — never read default_violation directly.
96 97 98 |
# File 'lib/strict_lazy.rb', line 96 def self.violation (violation_overrides || []).last || default_violation end |
.violation=(mode) ⇒ Object
Backward-compatible global setter. Sets the baseline only; it does not touch any active with_violation override. Existing callers (and the Railtie) keep working unchanged.
103 104 105 |
# File 'lib/strict_lazy.rb', line 103 def self.violation=(mode) self.default_violation = validate_violation!(mode) end |
.with_violation(mode) ⇒ Object
Run the block with mode as the effective policy, restoring the previous state afterward (exception-safe). Overrides nest; an inner call shadows an outer one and unwinds cleanly. Scoped to the current Fiber/Thread, so parallel test processes never interfere.
StrictLazy.with_violation(:ignore) { ... } # never raises inside
113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/strict_lazy.rb', line 113 def self.with_violation(mode) # Validate first: an invalid mode raises here, before the stack is touched, # so the begin/ensure only ever runs against a successfully pushed frame. validated = validate_violation!(mode) begin pushed = (violation_overrides || []) + [validated] self.violation_overrides = pushed yield ensure self.violation_overrides = pushed[0...-1] end end |