Skip to content

Conversation

@bene-tyler
Copy link

Add opt-in feature to treat undefined variables as false in conditional statements instead of throwing errors. This provides a more convenient syntax similar to JavaScript/Python where missing properties can be checked directly.

Usage:
env.set_implicit_false_for_missing_vars(true);
// Now: {% if entity.Person %} works even if Person doesn't exist
// Instead of: {% if existsIn(entity, "Person") %}

Key implementation details:

  • Added RenderConfig::implicit_false_for_missing_vars flag (defaults to false)
  • Modified eval_expression_list() to accept allow_missing parameter
  • Extended logical operators (and, or, not) to handle missing variables
  • Feature only applies to conditionals, not expressions or loops
  • Thread-safe: config is const member copied per render call

Testing:

  • 21 new test assertions covering all subcases
  • Tests default behavior, missing variables, existing variables, logical operators, else-if chains, loops, and deep nesting
  • All 279 assertions pass (21 new + 258 existing)
  • No regressions in existing functionality

Documentation:

  • Comprehensive guide in IMPLICIT_FALSE_FEATURE.md
  • Brief usage example added to README.md

This feature is 100% backward compatible as it defaults to disabled.

Add opt-in feature to treat undefined variables as false in conditional
statements instead of throwing errors. This provides a more convenient
syntax similar to JavaScript/Python where missing properties can be
checked directly.

Usage:
  env.set_implicit_false_for_missing_vars(true);
  // Now: {% if entity.Person %} works even if Person doesn't exist
  // Instead of: {% if existsIn(entity, "Person") %}

Key implementation details:
- Added RenderConfig::implicit_false_for_missing_vars flag (defaults to false)
- Modified eval_expression_list() to accept allow_missing parameter
- Extended logical operators (and, or, not) to handle missing variables
- Feature only applies to conditionals, not expressions or loops
- Thread-safe: config is const member copied per render call

Testing:
- 21 new test assertions covering all subcases
- Tests default behavior, missing variables, existing variables,
  logical operators, else-if chains, loops, and deep nesting
- All 279 assertions pass (21 new + 258 existing)
- No regressions in existing functionality

Documentation:
- Comprehensive guide in IMPLICIT_FALSE_FEATURE.md
- Brief usage example added to README.md

This feature is 100% backward compatible as it defaults to disabled.
Add opt-in environment flag to automatically wrap non-array values in arrays
when used in for loops. This solves the common XML-to-JSON cardinality problem
where single items are objects but multiple items are arrays.

Problem solved:
- XML with one <person> converts to object: {"person": {...}}
- XML with multiple <person> converts to array: {"person": [{...}, {...}]}
- Previously required different templates or custom ensureArray() callback
- Now no custom code is needed to use a for loop with json objects that change cardinality per request.

Usage:
  env.set_ensure_array_for_loops(true);
  // {% for p in person %} now works whether person is object or array

Implementation:
- Added RenderConfig::ensure_array_for_loops flag (defaults to false)
- Added Environment::set_ensure_array_for_loops() method
- Created ensure_array() helper function that wraps non-arrays:
  * Arrays: returned unchanged
  * Null: becomes empty array []
  * Objects/primitives: wrapped in single-item array [value]
- Modified ForArrayStatementNode::visit() to call ensure_array() when enabled

Testing:
- 26 new test assertions in test-ensure-array.cpp
- Tests single objects, arrays, null, primitives, nested loops
- Tests default behavior, enabled behavior, and disabled flag
- All 284 assertions pass (26 new + 258 existing)
- No regressions in existing functionality
- Stress tested with 10,000 iterations

Backward compatibility:
- 100% backward compatible - flag defaults to false
- Without explicit enablement, behavior is identical to previous versions
- Non-arrays still throw errors by default
- Existing code requires zero changes

Documentation:
- Added usage example to README.md
- Comprehensive test suite demonstrates all use cases
Add ensure_array_for_loops feature for XML-to-JSON compatibility
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant