55
66module Async
77 module Service
8+ # Represents a service configuration with lazy evaluation and module composition.
9+ #
10+ # Environments store configuration as methods that can be overridden and composed using Ruby modules. They support lazy evaluation through evaluators.
811 class Environment
12+ # A builder for constructing environments using a DSL.
913 class Builder < BasicObject
14+ # Create a new environment with facets and values.
15+ # @parameter facets [Array(Module)] Modules to include in the environment.
16+ # @parameter values [Hash] Key-value pairs to define as methods.
17+ # @parameter block [Proc] A block for additional configuration.
18+ # @returns [Module] The constructed environment module.
1019 def self . for ( *facets , **values , &block )
1120 top = ::Module . new
1221
@@ -46,10 +55,14 @@ def self.for(*facets, **values, &block)
4655 return top
4756 end
4857
58+ # Initialize a new builder.
59+ # @parameter facet [Module] The module to build into, defaults to a new `Module`.
4960 def initialize ( facet = ::Module . new )
5061 @facet = facet
5162 end
5263
64+ # Include a module or other includable object into the environment.
65+ # @parameter target [Module] The module to include.
5366 def include ( target )
5467 if target . class == ::Module
5568 @facet . include ( target )
@@ -60,6 +73,10 @@ def include(target)
6073 end
6174 end
6275
76+ # Define methods dynamically on the environment.
77+ # @parameter name [Symbol] The method name to define.
78+ # @parameter argument [Object] The value to return from the method.
79+ # @parameter block [Proc] A block to use as the method implementation.
6380 def method_missing ( name , argument = nil , &block )
6481 if block
6582 @facet . define_method ( name , &block )
@@ -68,15 +85,25 @@ def method_missing(name, argument = nil, &block)
6885 end
6986 end
7087
88+ # Always respond to missing methods for dynamic method definition.
89+ # @parameter name [Symbol] The method name.
90+ # @parameter include_private [Boolean] Whether to include private methods.
91+ # @returns [Boolean] Always true to enable dynamic method definition.
7192 def respond_to_missing? ( name , include_private = false )
7293 true
7394 end
7495 end
7596
97+ # Build a new environment using the builder DSL.
98+ # @parameter arguments [Array] Arguments passed to Builder.for
99+ # @returns [Environment] A new environment instance.
76100 def self . build ( ...)
77101 Environment . new ( Builder . for ( ...) )
78102 end
79103
104+ # Initialize a new environment.
105+ # @parameter facet [Module] The facet module containing the configuration methods.
106+ # @parameter parent [Environment | Nil] The parent environment for inheritance.
80107 def initialize ( facet = ::Module . new , parent = nil )
81108 unless facet . class == ::Module
82109 raise ArgumentError , "Facet must be a module!"
@@ -92,21 +119,32 @@ def initialize(facet = ::Module.new, parent = nil)
92119 # @attribute [Environment | Nil] The parent environment, if any.
93120 attr :parent
94121
122+ # Include this environment's facet into a target module.
123+ # @parameter target [Module] The target module to include into.
95124 def included ( target )
96125 @parent &.included ( target )
97126 target . include ( @facet )
98127 end
99128
129+ # Create a new environment with additional configuration.
130+ # @parameter arguments [Array] Arguments passed to Environment.build.
131+ # @returns [Environment] A new environment with this as parent.
100132 def with ( ...)
101133 return self . class . new ( Builder . for ( ...) , self )
102134 end
103135
136+ # Check if this environment implements a given interface.
137+ # @parameter interface [Module] The interface to check.
138+ # @returns [Boolean] True if this environment implements the interface.
104139 def implements? ( interface )
105140 @facet <= interface
106141 end
107142
108143 # An evaluator is lazy read-only view of an environment. It memoizes all method calls.
109144 class Evaluator
145+ # Create an evaluator wrapper for an environment.
146+ # @parameter environment [Environment] The environment to wrap.
147+ # @returns [Evaluator] A new evaluator instance.
110148 def self . wrap ( environment )
111149 evaluator = ::Class . new ( self )
112150
@@ -137,14 +175,19 @@ def self.wrap(environment)
137175 return evaluator . new
138176 end
139177
178+ # Initialize a new evaluator.
140179 def initialize
141180 @cache = { }
142181 end
143182
183+ # Inspect representation of the evaluator.
184+ # @returns [String] A string representation of the evaluator with its keys.
144185 def inspect
145186 "#<#{ Evaluator } #{ self . keys } >"
146187 end
147188
189+ # Convert the evaluator to a hash.
190+ # @returns [Hash] A hash with all evaluated keys and values.
148191 def to_h
149192 # Ensure all keys are evaluated:
150193 self . keys . each do |name |
@@ -154,25 +197,38 @@ def to_h
154197 return @cache
155198 end
156199
200+ # Convert the evaluator to JSON.
201+ # @parameter arguments [Array] Arguments passed to to_json.
202+ # @returns [String] A JSON representation of the evaluator.
157203 def to_json ( ...)
158204 self . to_h . to_json ( ...)
159205 end
160206
207+ # Get value for a given key.
208+ # @parameter key [Symbol] The key to look up.
209+ # @returns [Object, nil] The value for the key, or nil if not found.
161210 def []( key )
162211 if self . key? ( key )
163212 self . __send__ ( key )
164213 end
165214 end
166215
216+ # Check if a key is available.
217+ # @parameter key [Symbol] The key to check.
218+ # @returns [Boolean] True if the key exists.
167219 def key? ( key )
168220 self . keys . include? ( key )
169221 end
170222 end
171223
224+ # Create an evaluator for this environment.
225+ # @returns [Evaluator] A lazy evaluator for this environment.
172226 def evaluator
173227 return Evaluator . wrap ( self )
174228 end
175229
230+ # Convert the environment to a hash.
231+ # @returns [Hash] A hash representation of the environment.
176232 def to_h
177233 evaluator . to_h
178234 end
0 commit comments