Skip Menu |

This queue is for tickets about the Config-Any CPAN distribution.

Report information
The Basics
Id: 70779
Status: open
Priority: 0/
Queue: Config-Any

People
Owner: Nobody in particular
Requestors: LGODDARD [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.23
Fixed in: (no value)



Subject: JSON 'dirver_args' ineffective
If I am reading the documentation correctly, the following is the API for configuring the underlying parser: my $cfg = Config::Any->load_files({ driver_args => { JSON => { driver_args => 1, } }, use_ext => 1, files => [$CONFIG_FILE_PATH] }); I have not delved into the code, but I presume the driver_args are passed to the JSON parser, which I found to be JSON::XS (is there an API call to get that info, btw?). The problem with JSON::XS is that it requires configuration by method calls or by the setting of variables in its namespace. The problem with the default configuration of JSON::XS is that it does not accept what it calls 'relaxed' JSON - that is JSON with trailing commas: { one: 1, }, The outcome is that Config::Any::JSON using the (very common) JSON::XS does not accept the JSON files I use across my JavaScript and Java and Perl libraries. Would it be possible to extend the system to either provide access to the underlying parser object prior to calling 'load_files', or via a callback argument to 'load_files'? Thanks for reading, and an otherwise beautiful module. Lee
On Wed Sep 07 04:52:37 2011, LGODDARD wrote: Show quoted text
> If I am reading the documentation correctly, the following is the API > for configuring the underlying parser: > > my $cfg = Config::Any->load_files({ > driver_args => { > JSON => { > driver_args => 1, > } > }, > use_ext => 1, > files => [$CONFIG_FILE_PATH] > });
Almost -- for it to be useful, driver_args should point to another hashref: driver_args => { foo => 'bar' } Show quoted text
> I have not delved into the code, but I presume the driver_args are > passed to the JSON parser, which I found to be JSON::XS (is there an
API Show quoted text
> call to get that info, btw?).
Unfortunately, the JSON loader doesn't currently do anything with driver_args. Also, no, there isn't currently an API to see what parser will be used. Show quoted text
> The problem with the default configuration of JSON::XS is that it does > not accept what it calls 'relaxed' JSON - that is JSON with trailing
commas: This is odd, because as it turns out, "relaxed" is enabled already: https://metacpan.org/source/BRICAS/Config-Any- 0.23/lib/Config/Any/JSON.pm#L62 Show quoted text
> Would it be possible to extend the system to either provide access to > the underlying parser object prior to calling 'load_files', or via a > callback argument to 'load_files'?
I think it would be good to extend the loader to handle config options, however, I think the issue you're reporting is unrelated due to the default enabling of the "relaxed" setting. FYI, the order of JSON plugins is: 1) JSON::DWIW 2) JSON::XS 3) JSON::Syck 4) JSON So, please check to see if you have JSON::DWIW installed. As an aside, here's a potential patch to handle args in the JSON loader: diff --git a/lib/Config/Any/JSON.pm b/lib/Config/Any/JSON.pm index ca2da3e..9774ca9 100644 --- a/lib/Config/Any/JSON.pm +++ b/lib/Config/Any/JSON.pm @@ -44,6 +44,7 @@ Attempts to load C<$file> as a JSON file. sub load { my $class = shift; my $file = shift; + my $args = shift || {}; open( my $fh, $file ) or die $!; my $content = do { local $/; <$fh> }; @@ -51,7 +52,7 @@ sub load { eval { require JSON::DWIW; }; unless( $@ ) { - my $decoder = JSON::DWIW->new; + my $decoder = JSON::DWIW->new( $args ); my ( $data, $error ) = $decoder->from_json( $content ); die $error if $error; return $data; @@ -60,6 +61,8 @@ sub load { eval { require JSON::XS; }; unless( $@ ) { my $decoder = JSON::XS->new->relaxed; + $decoder = $decoder->$_( $args->{ $_ } ) for keys %$args; + return $decoder->decode( $content ); } @@ -70,7 +73,7 @@ sub load { require JSON; eval { JSON->VERSION( 2 ); }; - return $@ ? JSON::jsonToObj( $content ) : JSON::from_json( $content ); + return $@ ? JSON::jsonToObj( $content, $args ) : JSON::from_json( $content, $args ); } =head2 requires_any_of( )
Show quoted text
> > The problem with the default configuration of JSON::XS is that it does > > not accept what it calls 'relaxed' JSON - that is JSON with trailing
> commas: > > This is odd, because as it turns out, "relaxed" is enabled already: > > https://metacpan.org/source/BRICAS/Config-Any- > 0.23/lib/Config/Any/JSON.pm#L62
That lines seems to read: my $decoder = JSON::XS->new->relaxed; That seems to de-reference to a line in the XS file: '#define F_RELAXED 0x00001000UL', which the docs describe: $enabled = $json->get_relaxed ...If $enable is false (the default), then decode will only accept valid JSON texts.... -- http://search.cpan.org/~mlehmann/JSON-XS-2.32/XS.pm which is the latest version: Show quoted text
> > Would it be possible to extend the system to either provide access to > > the underlying parser object prior to calling 'load_files', or via a > > callback argument to 'load_files'?
> > I think it would be good to extend the loader to handle config options, > however, I think the issue you're reporting is unrelated due to the > default enabling of the "relaxed" setting.
Please see above. I can supply you with a test case as proof, if required. Show quoted text
> FYI, the order of JSON plugins is: > > 1) JSON::DWIW > 2) JSON::XS > 3) JSON::Syck > 4) JSON > > So, please check to see if you have JSON::DWIW installed.
As I reported, I hacked the code to see which parser I am using, and it is JSON::XS. Show quoted text
> As an aside, here's a potential patch to handle args in the JSON loader:
Thanks very much. Sadly, I'll have to wait for a release, as the client is not competent to handle patched modules. If you would like me to extend the *::JSON module, please let me know me. Cheers lee
On Wed Sep 07 10:21:17 2011, LGODDARD wrote: Show quoted text
> That lines seems to read: > > my $decoder = JSON::XS->new->relaxed; > > That seems to de-reference to a line in the XS file: '#define
F_RELAXED Show quoted text
> 0x00001000UL', which the docs describe: > > $enabled = $json->get_relaxed > > ...If $enable is false (the default), then decode will only > accept valid JSON texts.... > > -- http://search.cpan.org/~mlehmann/JSON-XS-2.32/XS.pm which is
the Show quoted text
> latest version:
A small test: perl -MJSON::XS -e '$d=JSON::XS->new->relaxed; print $d->get_relaxed;' 1 That seems to show that it is enabled. Show quoted text
> Please see above. I can supply you with a test case as proof, if
required. I modified the t/conf/conf.json file and added an extra comma, after confirming that JSON::XS would be used, the tests still passed. If you can provide me with your test case, i'd appreciate it. Show quoted text
> Thanks very much. Sadly, I'll have to wait for a release, as the
client Show quoted text
> is not competent to handle patched modules.
Hopefully I'll get it integrated and released soon.
Show quoted text
> A small test: > > perl -MJSON::XS -e '$d=JSON::XS->new->relaxed; print $d->get_relaxed;' > 1 > > That seems to show that it is enabled.
Ah. When I do that, I get no output. Then, perl -MJSON::XS -e 'print JSON::XS->VERSION'; Returns 2.3 Show quoted text
> If you can provide me with your test case, i'd appreciate it.
Please see attached. Thanks very much for your attention. Cheers Lee
Subject: config2.t
use strict; use warnings; use Test::More 'no_plan'; use File::Temp; BEGIN { use_ok('Config::Any'); } sub Config::Any::JSON::requires_all_of { return ['JSON::XS']; } foreach my $test_str ( '{ "foo": "bar" }', '{ foo: "bar"}', '{ "foo": "bar",}' ){ my $fh = File::Temp->new( SUFFIX => '.json' ); my $config_file = $fh->filename; warn $config_file; $fh->print( $test_str ); $fh->close; my $cfg = Config::Any->load_files({ use_ext => 1, files => [$config_file], }); use Data::Dumper; warn $test_str; warn Dumper $cfg; is( $cfg->[0]->{$config_file}->{foo}, 'bar' ); }
On Wed Sep 07 11:07:56 2011, LGODDARD wrote: Show quoted text
> Ah. When I do that, I get no output.
Strange. :/ How about explicitly using a true value? perl -MJSON::XS -e '$d=JSON::XS->new->relaxed(1); print $d- Show quoted text
>get_relaxed;'
Show quoted text
> > If you can provide me with your test case, i'd appreciate it.
> > Please see attached.
As far as that test is concerned, it failed on the second test due to the fact that the "foo" key was not properly quoted. This is invalid, and "relaxed" parsing will not help you there as "relaxed" only allows trailing commas and shell-style comments. Omitting that case, I get all passes: $ prove -v config2.t config2.t .. ok 1 - use Config::Any; /tmp/rqN1f_FuTV.json at config2.t line 21. { "foo": "bar" } at config2.t line 31. $VAR1 = [ { '/tmp/rqN1f_FuTV.json' => { 'foo' => 'bar' } } ]; ok 2 /tmp/QM71uVhRaX.json at config2.t line 21. { "foo": "bar",} at config2.t line 31. $VAR1 = [ { '/tmp/QM71uVhRaX.json' => { 'foo' => 'bar' } } ]; ok 3 1..3 ok All tests successful. Files=1, Tests=3, 0 wallclock secs ( 0.03 usr 0.01 sys + 0.08 cusr 0.00 csys = 0.12 CPU) Result: PASS
Subject: Re: [rt.cpan.org #70779] JSON 'dirver_args' ineffective
Date: Wed, 07 Sep 2011 16:47:51 +0100
To: bug-Config-Any [...] rt.cpan.org
From: Lee Goddard <lee [...] leegoddard.net>
Thanks for looking into this. My major problem seems to be with JSON::XS no reading real JSON in 'relaxed' mode -- I'm actually using Javascript to read this JavaScript Object Notation, and it is darned frustrating to have Perl tell me it is no valid..! Which version of JSON::XS are you running, please/? Thanks Lee Brian Cassidy via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=70779 > > > On Wed Sep 07 11:07:56 2011, LGODDARD wrote: >
>> Ah. When I do that, I get no output. >>
> > Strange. :/ > > How about explicitly using a true value? > > perl -MJSON::XS -e '$d=JSON::XS->new->relaxed(1); print $d- >
>> get_relaxed;' >>
> >
>>> If you can provide me with your test case, i'd appreciate it. >>>
>> Please see attached. >>
> > As far as that test is concerned, it failed on the second test due to > the fact that the "foo" key was not properly quoted. This is invalid, > and "relaxed" parsing will not help you there as "relaxed" only allows > trailing commas and shell-style comments. > > Omitting that case, I get all passes: > > $ prove -v config2.t > config2.t .. > ok 1 - use Config::Any; > /tmp/rqN1f_FuTV.json at config2.t line 21. > { "foo": "bar" } at config2.t line 31. > $VAR1 = [ > { > '/tmp/rqN1f_FuTV.json' => { > 'foo' => 'bar' > } > } > ]; > ok 2 > /tmp/QM71uVhRaX.json at config2.t line 21. > { "foo": "bar",} at config2.t line 31. > $VAR1 = [ > { > '/tmp/QM71uVhRaX.json' => { > 'foo' => 'bar' > } > } > ]; > ok 3 > 1..3 > ok > All tests successful. > Files=1, Tests=3, 0 wallclock secs ( 0.03 usr 0.01 sys + 0.08 cusr > 0.00 csys = 0.12 CPU) > Result: PASS > > >
On Wed Sep 07 12:55:13 2011, lee@leegoddard.net wrote: Show quoted text
> Which version of JSON::XS are you running, please/?
I have version 2.32 installed.