feat: match array properties element-wise for non-set operators#92
Merged
Conversation
1 task
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Negation operators on arrays use wrong quantifier
- Changed match_strings_non_set to use all? for negation operators (IS_NOT, DOES_NOT_CONTAIN, REGEX_DOES_NOT_MATCH) instead of any?, ensuring correct 'no element matches' semantics.
Or push these changes by commenting:
@cursor push 130164c824
Preview (130164c824)
diff --git a/lib/experiment/evaluation/evaluation.rb b/lib/experiment/evaluation/evaluation.rb
--- a/lib/experiment/evaluation/evaluation.rb
+++ b/lib/experiment/evaluation/evaluation.rb
@@ -82,9 +82,22 @@
end
def match_strings_non_set(prop_values, op, filter_values)
- prop_values.any? { |v| match_string(v, op, filter_values) }
+ if negation_operator?(op)
+ prop_values.all? { |v| match_string(v, op, filter_values) }
+ else
+ prop_values.any? { |v| match_string(v, op, filter_values) }
+ end
end
+ def negation_operator?(op)
+ case op
+ when Operator::IS_NOT, Operator::DOES_NOT_CONTAIN, Operator::REGEX_DOES_NOT_MATCH
+ true
+ else
+ false
+ end
+ end
+
def get_hash(key)
Murmur3.hash32x86(key)
endYou can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit c9f7cb1. Configure here.
vaibhav-jain-exp
approved these changes
Apr 27, 2026
github-actions Bot
pushed a commit
that referenced
this pull request
Apr 29, 2026
# [1.10.0](v1.9.0...v1.10.0) (2026-04-29) ### Features * match array properties element-wise for non-set operators ([#92](#92)) ([51a9738](51a9738))
|
🎉 This PR is included in version 1.10.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Adds element-wise (any-match) evaluation for multi-valued user properties when paired with non-set operators (
is,contains,greater, etc.), aligning the local evaluation engine with Amplitude analytics/charts behavior.Previously, non-set operators always stringified the whole property value via
coerce_string— so an array property like["a","b"]would never satisfyis "a". Now:match_conditioncallscoerce_string_arrayfor every non-null value. If the value is multi-valued (native array or JSON array string) and the operator is non-set, it delegates to a newmatch_strings_non_sethelper that returns true if any element satisfies the operator.is not,does not contain) also use any-match semantics —is not "A"on["A","B"]istruebecause"B"is not"A".coerce_string→match_stringpath unchanged.Also fixes two issues in
coerce_string_array:start_with?('[')pre-check so scalar strings skipJSON.parseand avoid exception-driven control flow on every evaluation.[value]instead ofnil, which caused set operators to spuriously match single-string properties.Tests
spec/experiment/evaluation/evaluation_spec.rbwith an inline test harness (flag_with_condition,context_with_prop,evaluate,assert_match,assert_no_match) and 14 unit cases covering scalars, native arrays, JSON array strings, malformed JSON, and leading-whitespace edge cases.operator testsblock; the deployment key is consolidated toserver-VVhLULXCxxY0xqmszXouXxiEzoeJWmSh(a superset of the prior key, containing all existing flags plus the new multi-value flags).Full suite: 271 examples, 0 failures. Rubocop: clean.
Checklist
Note
Medium Risk
Changes core flag targeting semantics when a property is an array/JSON array string, which can alter which users qualify for segments. Also tightens
coerce_string_arrayparsing behavior, potentially changing outcomes for previously mis-coerced scalar values.Overview
The evaluation engine now treats multi-valued properties (native arrays or JSON array strings) as element-wise inputs for non-set operators like
is,contains, and comparisons, matching if any element satisfies the operator (via newmatch_strings_non_set).coerce_string_arrayis tightened to only parse JSON when the string looks like an array (starts with'[') and to returnnilfor non-array/malformed JSON instead of coercing scalars into single-element arrays, reducing accidental set-operator matches. Tests are expanded with new unit coverage and additional integration cases, plus the integration spec caches the flags URI and updates the deployment key.Reviewed by Cursor Bugbot for commit c73b5c6. Bugbot is set up for automated code reviews on this repo. Configure here.