Define behavior when paths continue through non-container values #32
Labels
No labels
bug
duplicate
enhancement/documentation
enhancement/feature
enhancement/organization
question
rejected
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
UserCurt/mpath#32
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Behavior is currently defined when a path continues through a container value but the requested child is missing:
MissingPolicy="omit": omit that missing branch from the resolved resultMissingPolicy="missing": replace the would-be path with missingmpath.PointerMissingPolicy="retain": keep the would-be pathMissingPolicy="error": throw an errorBehavior is less clearly defined when a path tries to continue through a non-container value.
Compare:
Ais a container type so hypothetically could have had the childXbut did not in this circumstance. In contrast,Bis not a container type so could not have ever had the childXto begin with.Ais traversable, whileBis not. In some sense, the path includingBis ill-defined because the path is "physically" impossible.The design question is whether the behavior for non-traversable paths should be controlled by
MissingPolicy, or whether non-traversable continuation deserves a separate policy.Using the same
MissingPolicytreatment would keep the API simpler. Havingretaininclude would-be non-traversable paths can help with debugging. However, it can be misleading as one may think/B/Xis a possible path even though it cannot exist whileAis a non-container. Additionally,mpath.setwithMissingPolicy="create"will require a set of traversable paths and require the more strict interpretation where non-traversable paths give an error.Introduction of a new parallel policy for handling non-traversable paths (e.g.,
NonTraversablePolicy) could distinguish this case from ordinary missing children. Possible values would be similar toMissingPolicyand could include"error","omit","missing", and"retain". This certainly adds complexity and possible confusion to the API, and users may need to remember to modify both policies in tandem.Alternatively, an orthogonal policy could be introduced (e.g.,
NonTraversablePolicy) could act as a modifier toMissingPolicyand could include"error"and"allow". Perhaps a"missing"could be valuable in some circumstances: UsingMissingPolicy="retain"withNonTraversablePolicy="missing"would keep the shape while making non-traversable paths missing but non-existing but traversable paths still retained.Regardless of the solution,
mpath.setwill need an additional constructibility check (when enabled), either ignoring or erroring when candidate paths are not possible due to non-traversability.It is worth highlighting that non-container values are valid terminal results (
/B), but only become problematic when later path operations require them to act as parents (/B/X).This also relates to whether field-matching dot operations (e.g.,
DotGlobandDotRegexin the future) should match children locally or look ahead to the remaining path. For example,mpath.resolve(data, "/*/X")could be interpreted in two ways:*matches all children, then/Xis attempted on each branch (current implementation)*matches only children for which the remaining descendant path/Xcan be traversedThe lookahead approach would automatically exclude non-containers. The current implementation gets around the need for lookahead through
MissingPolicy. This is not perfect, as indicated by this issue. Future support for filtering (#33) could improve the situation by making lookahead explicit:/*[has:/X]/Xwould have*match only fields that have the childX).Addressed by
af551a2primarily, and also2cbf33ffor a small follow-up on yet-widely supportedDotIndex.Traversal through a non-container now uses the existing missing-policy model rather than introducing a separate non-traversable policy.
From a user’s perspective, resolving a branching path should be consistent in that when some branches not valid from non-container items should not give an error under
MissingPolicyfor anything but"error". So it was decided to have matching members of non-containers are treated just like failing to match any members, acting like a missing path.