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

"traverse" json_file #204

Closed
jacopo-chevallard opened this issue Jun 10, 2016 · 7 comments
Closed

"traverse" json_file #204

jacopo-chevallard opened this issue Jun 10, 2016 · 7 comments
Assignees

Comments

@jacopo-chevallard
Copy link

First thing, fantastic library, thanks for releasing it !!

I'm in a situation where I need to "traverse" the node in a json structure. Following the example in jf_test_14.f90, I can do it by using the following syntax

    type(json_core) :: json
    type(json_value),pointer  :: p

    call json%initialize() !initialize the module

    call json%parse(p, '{"option1" : real, '//&
                       '"option2" : bool', //&
                       '"option3" : string')

    call json%traverse(p, check_options) !traverse all nodes in the structure 

Where check_options is a custom routine. It would be useful being able to traverse the structure from the higher level json_file class, since this would save me the need of passing around both json_core and json_value, or to call each time the json_core methods explicitly.

In other words: is there a way to use

  type(json_file) :: json

  call json%load_from_string('{"option1" : real, '//&
                       '"option2" : bool', //&
                       '"option3" : string')

  call json%traverse(check_options)

?

@jacobwilliams
Copy link
Owner

Yes, I can certainly add this (there are various routines that are not included in json_file but could be). I'll try to do it later today or tomorrow.

@jacopo-chevallard
Copy link
Author

(To give some more context: the main motivation is being able to pass optional arguments to subroutines in a way similar to python **kwargs. For now I'm using the FPL "dictionary", but using json instead has a number of advantages...)

@jacobwilliams
Copy link
Owner

I was thinking, in order for this to work, I'd need to give access to the json_core instance within json_file, otherwise, you'd still have to declare your own in order to do anything with the json_value variables that are being traversed.

So, if I just made it public, then I think you could do what you wanted like this:

  type(json_file) :: json

  call json%load_from_string('{"option1" : real, '//&
                       '"option2" : bool', //&
                       '"option3" : string')

  call json%json%traverse(check_options)

(Maybe I would rename it from json to core or something like that).

Need to think about this some more... are there any adverse consequences to making this public? It might be OK.

@zbeekman
Copy link
Contributor

So the core object would be public within json_file, but the json_core class is itself only has private members, using the exposed methods to interact with it yes? If that's the case I can't think of a downside off the top of my head, other than consistency with data hiding.

The alternative is just a thin traverse wrapper that calls this%json%traverse(), right?

(I am not current on all your latest changes, so I could be wrong here...)

@jacobwilliams
Copy link
Owner

Yes, that is correct.

The problem with the thin wrapper function is that you can't really do anything with json_value pointers that you are traversing without a json_core. So, you would have to just declare your own in your traverse routine, which seems clunky since there's already one in the json_file class that you are using.

An alternate would be to have another method that returns the json_core within the json_file class (or a pointer to it). But that's kind of clunky too.

So, I think making core public might be the best way to go.

@jacobwilliams
Copy link
Owner

Actually, turns out it's not necessary to make json_file%core public, since it will be passed into the traverse function, so the caller will have access to it. I had forgotten that...guess I should have looked at my own code first! I have a working solution over at #206. It will be in the next release. The syntax is exactly what @jacopo-chevallard proposed above.

@jacopo-chevallard
Copy link
Author

Brilliant! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants