joshbuddy/jsonpath

Feature: Pass accessor path to gsub

greena13 opened this issue · 6 comments

Hi @Skarlso,

Thanks for the great library! My particular application uses the gsub function and I am really missing the ability to record or operate on the path to the matched attribute. It would be great if this was passed as a second parameter to the handler function. For example:

modified_attributes = []

JsonPath.for('{"candy":"lollipop"}').gsub('$..candy')  do |value, path| 
  modified_attributes.push(path) # E.g. foo.bar[1].baz
  "big turks"
end.to_hash

Thanks.

Hey!

Sure thing. :)

That's great! Is there any way I can assist or help speed up when this might be available?

It looks like it's a case of passing down and maintaining an additional parameter to the enumerable#each method, but I don't yet know JSONPath well enough to be exactly sure what the appropriate operation is to the the accessor path, for each JSONPath token.

Dunno yet. I need to take a closer look first. :)

sorry, I'm going to a new workplace so I'm swamp at the moment.

I took a quick look and I'm unsure yet how to do this properly. :) any suggestion is welcomed. :D

That's quite alright, @Skarlso. I certainly know how it is to be swamped at work.

My understanding is #each is called recursively with the current key value. I was thinking an additional 4th attribute would be added to the method that would receive the path value:

 def each(context = @object, key = nil, pos = 0, path = '', &blk)

It would then be a case of ensure all references to #each were updated (if necessary - I think the above is actually backwards-compatible) and then figuring out for each time #each calls itself, it does so with the correct concatenation of the existing value of path plus the next segment.

I'm aware this is where it gets tricky - reliably establishing the correct way to join the string based on object types: a.b.c vs a[b].c.

Does this sound in line with your expectations (or does it have an immediate and obvious flaw)?

@greena13 Sounds good! I'll try to implement it. :)