Class: Musa::Extension::SmartProcBinder::SmartProcBinder
- Defined in:
- lib/musa-dsl/core-ext/smart-proc-binder.rb
Overview
Wrapper for Proc objects that provides intelligent parameter matching and binding.
This class introspects a Proc's parameter list and provides methods to:
- Determine which parameters the Proc accepts
- Filter provided arguments to match the Proc's signature
- Call the Proc with properly matched arguments
- Optionally rescue and handle exceptions
Parameter Types Handled
- :req, :opt: Required and optional positional parameters
- :rest: Splat parameter (*args)
- :key, :keyreq: Optional and required keyword parameters
- :keyrest: Double splat parameter (**kwargs)
Use Cases
- DSL methods that need flexible parameter passing
- Builder patterns with variable block signatures
- Wrapper methods that forward arguments intelligently
- Error handling for DSL block execution
Instance Method Summary collapse
-
#_apply(value_parameters, key_parameters) ⇒ Object
private
Internal implementation of argument filtering.
-
#_call(value_parameters, key_parameters = {}, block = nil) ⇒ Object
private
Internal call implementation with error handling.
-
#apply(*value_parameters, **key_parameters) ⇒ Array<Array, Hash>
Filters arguments to match the Proc's signature.
-
#call(*value_parameters, **key_parameters, &block) ⇒ Object
Calls the wrapped Proc with smart parameter matching.
-
#initialize(block, on_rescue: nil) ⇒ SmartProcBinder
constructor
Creates a new SmartProcBinder wrapping the given block.
-
#inspect ⇒ String
(also: #to_s)
Returns a string representation of the SmartProcBinder for debugging.
-
#key?(key) ⇒ Boolean
(also: #has_key?)
Checks if the wrapped Proc accepts a specific keyword parameter.
-
#parameters ⇒ Array<Array>
Returns the parameter signature of the wrapped Proc.
-
#proc ⇒ Proc
Returns the wrapped Proc.
Constructor Details
#initialize(block, on_rescue: nil) ⇒ SmartProcBinder
Creates a new SmartProcBinder wrapping the given block.
Introspects the block's parameters and categorizes them for later matching.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 60 def initialize(block, on_rescue: nil) @block = block @on_rescue = on_rescue # Track keyword parameters by name @key_parameters = {} @has_key_rest = false # Track positional parameter count @value_parameters_count = 0 @has_value_rest = false # Introspect block's parameter signature block.parameters.each do |parameter| @key_parameters[parameter[1]] = nil if parameter[0] == :key || parameter[0] == :keyreq @has_key_rest = true if parameter[0] == :keyrest @value_parameters_count += 1 if parameter[0] == :req || parameter[0] == :opt @has_value_rest = true if parameter[0] == :rest end end |
Instance Method Details
#_apply(value_parameters, key_parameters) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Internal implementation of argument filtering.
Logic:
- Positional: takes first N values (or all if *rest present)
- Keywords: includes only expected keys (or all if **rest present)
- Pads positional with nils if needed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 191 def _apply(value_parameters, key_parameters) value_parameters ||= [] key_parameters ||= {} if @has_value_rest values_result = value_parameters.clone else values_result = value_parameters.first(@value_parameters_count) values_result += Array.new(@value_parameters_count - values_result.size) end hash_result = @key_parameters.clone @key_parameters.each_key do |parameter_name| hash_result[parameter_name] = key_parameters[parameter_name] end if @has_key_rest key_parameters.each do |key, value| hash_result[key] = value unless hash_result.key?(key) end end return values_result, hash_result end |
#_call(value_parameters, key_parameters = {}, block = nil) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Internal call implementation with error handling.
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 123 def _call(value_parameters, key_parameters = {}, block = nil) if @on_rescue begin __call value_parameters, key_parameters, block rescue StandardError, ScriptError => e @on_rescue.call e end else __call value_parameters, key_parameters, block end end |
#apply(*value_parameters, **key_parameters) ⇒ Array<Array, Hash>
Filters arguments to match the Proc's signature.
179 180 181 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 179 def apply(*value_parameters, **key_parameters) _apply(value_parameters, key_parameters) end |
#call(*value_parameters, **key_parameters, &block) ⇒ Object
Calls the wrapped Proc with smart parameter matching.
116 117 118 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 116 def call(*value_parameters, **key_parameters, &block) _call value_parameters, key_parameters, block end |
#inspect ⇒ String Also known as: to_s
Returns a string representation of the SmartProcBinder for debugging.
Shows the wrapped Proc's parameter signature and internal state, making it easy to understand what parameters the binder expects and how it will match arguments.
231 232 233 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 231 def inspect "SmartProcBinder: parameters = #{parameters} key_parameters = #{@key_parameters} has_rest = #{@has_key_rest}" end |
#key?(key) ⇒ Boolean Also known as: has_key?
Checks if the wrapped Proc accepts a specific keyword parameter.
Returns true if the Proc has a keyword parameter with the given name, or if it has a **kwargs rest parameter that accepts any keyword.
167 168 169 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 167 def key?(key) @has_key_rest || @key_parameters.include?(key) end |
#parameters ⇒ Array<Array>
The positional types differ between a proc and a lambda -- :opt
and :req respectively -- because a proc tolerates being called with
the wrong number of arguments and a lambda does not. A keyword without
a default is :keyreq in both.
Returns the parameter signature of the wrapped Proc.
105 106 107 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 105 def parameters @block.parameters end |
#proc ⇒ Proc
Returns the wrapped Proc.
85 86 87 |
# File 'lib/musa-dsl/core-ext/smart-proc-binder.rb', line 85 def proc @block end |