-
Notifications
You must be signed in to change notification settings - Fork 170
Open
Description
Description
When using Dentaku::Calculator#solve with a block to handle errors, the recipient_variable attribute on the exception object is intermittently nil for unbound variables in versions 3.5.4 through 3.5.7. This worked correctly in version 3.5.3.
Root Cause
The regression was introduced in version 3.5.4 during the refactoring of BulkExpressionSolver to use Evaluator classes. In PermissiveEvaluator#evaluate, the block passed during evaluation is ignored:
# lib/dentaku/bulk_expression_solver.rb
class PermissiveEvaluator
def initialize(calculator, block)
@calculator = calculator
@block = block || ->(*) { :undefined }
end
def evaluate(*args)
@calculator.evaluate(*args) { |expr, ex|
@block.call(ex) # <--- This uses the @block from initialization,
# ignoring any block passed to #evaluate
}
end
endHowever, BulkExpressionSolver#load_results attempts to pass a block that sets the recipient_variable:
# lib/dentaku/bulk_expression_solver.rb
variables_in_resolve_order.each_with_object({}) do |var_name, results|
# ...
with_rescues(var_name, results, block) do
results[var_name] = evaluated_facts[var_name] || evaluator.evaluate(
expressions[var_name],
context.merge(results),
&expression_with_exception_handler(var_name, &block) # <--- This block is ignored
)
end
endReproduction Script
require 'dentaku'
calculator = Dentaku::Calculator.new
to_compute = { result: 'unknown_variable * 2' }
errors = {}
calculator.solve(to_compute) do |e|
errors[e.recipient_variable] = e.class.name
end
puts "Errors: #{errors.inspect}"
# Expected (3.5.3): {"result"=>"Dentaku::UnboundVariableError"}
# Actual (3.5.4+): {nil=>"Dentaku::UnboundVariableError"}Suggested Fix
Modify PermissiveEvaluator#evaluate to accept and prefer the passed block:
def evaluate(*args, &block)
@calculator.evaluate(*args, &(block || @block))
endReactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels