Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use array path when delimiter is false #29

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

grey-stripe
Copy link

@grey-stripe grey-stripe commented Jan 11, 2017

Addresses #19 and #25.

I went through some effort to make this backwards compatible - no external-facing behavior should be different using default options. This could be made simpler by breaking the default behavior, so let me know which you would prefer.

User-facing changes:

  • The :delimiter option now takes false, in which case paths are returned as arrays rather than strings (Key that includes delimiter errors on patch! #19).
  • Added a new option :stringify_keys, defaulting to true.
    • When false, object keys will not be converted to strings in array paths.
    • This should allow for diffing of objects where symbol keys have meaning (Patch problem whit symbol as key #25).
    • This only applies if :delimiter is false.
  • patch! and unpatch! work automatically with array paths, no option necessary.
  • Added README.md description of new option values.

Internal changes:

  • :prefix is now maintained in all relevant functions (most notably missing was diff_array).
    • When a change is added to the result set, it contains the fully qualified path and does not need an extra step to finalize it.
  • Paths are now maintained internally as array paths rather than string paths.
    • When :delimiter is in effect, these paths will be translated to string paths at the API boundaries.
    • '[*]' in string paths is now -1 in array paths (only exposed in comparison callbacks).
  • Broke diff_object out of diff, similarly to diff_array.
  • diff is now a wrapper for diff_internal
    • Primarily, this was to provide the API boundary for translating back to string paths.
    • Option default values are now applied once here, not every recursive call to diff_internal.
  • Removed several default values on options (most weren't used except in tests).
    • Let me know if this is too intrusive, I may have gotten carried away.
  • Added tests for the new behavior.

@liufengyun
Copy link
Owner

Thanks @grey-stripe , it looks great 👍 Sorry I somehow missed the PR notification.

You mentioned we it could be simpler by breaking the default behavior. I think I'm now happy to make a major release to break backward-compatibility, and make array diff the default. Could you update the PR?

@grey-stripe
Copy link
Author

grey-stripe commented Feb 23, 2017

@liufengyun - thanks for taking a look! I removed the delimiter option so it no longer needs to translate array paths to string paths at the library boundaries. I left patch backwards compatible because it did not complicate any of the rest of the implementation, and (at least in my case) I have old patch diffs stored, and would like them to keep working when I upgrade.

Let me know if you'd like any other changes made.

Copy link
Owner

@liufengyun liufengyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @grey-stripe, this is awesome 🍷 !

In addition to some comments in the code, I have two more comments below.

First, a lot of examples and contents in README are irrelevant with this PR. Could you please also update or remove obsolete contents in README?

Second, I see now an implicit design decision is to just represent array change as an integer in the prefix. I think this is an important knowledge for people using the library. I think it's worth documenting it in the README and potential problems with it.

Otherwise, it looks good to me.

@@ -48,12 +48,12 @@ def self.count_nodes(obj)

# @private
#
# decode property path into an array
# decode a property path into an array
# @param [String] path Property-string
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine to remove this as we are moving to array representation, this is no longer relevant.

# @param [Hash] options supports following keys:
# * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array
# * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array, ignored for array paths
#
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just remove the delimiter and break compatibility.


opts[:prefix] = "#{opts[:prefix]}[*]"
def self.lcs(a, b, options)
options = options.merge({:prefix => options[:prefix] + [-1]})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment here why plus -1?

# @param [Hash] options supports following keys:
# * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array
# * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array, ignored for array paths
#
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine just to remove delimiter.

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.

2 participants