NAME

JSON::WithComments - Parse JSON content with embedded comments

VERSION

version 0.003

SYNOPSIS

    use JSON::WithComments;
    
    my $content = <<JSON;
    /*
     * This is a block-comment in the JavaScript style, the default.
     */
    {
        // Line comments are also recognized
        "username" : "rjray",  // As are side-comments
        // This should probably be hashed:
        "password" : "C0mputer!"
    }
    JSON
    
    my $json = JSON::WithComments->new;
    my $hashref = $json->decode($content);

DESCRIPTION

NOTE: This is an early release, and should be considered alpha-quality. The interface is subject to change in future versions.

JSON::WithComments is a simple wrapper around the JSON module that pre-processes any JSON input before decoding it. The pre-processing is simple: based on the style of comments that the object is configured for, it strips all comments of that style it finds, before passing the remaining content to the decode method of the parent class.

The motivation for this was simple: with JSON becoming more and more popular as a configuration format, some tools have started adding as-hoc support for comments into their JSON parsers. This allows documentation to be a part of these (sometimes quite large) JSON files. This module slightly extends the concept by allowing you to opt for different styles of comments.

The JSON module itself allows for shell-style (Perl-style) comments via use of the relaxed method. IF YOU ONLY NEED PERL-STYLE COMMENTS, you can get that from JSON directly. The advantage that this module offers is the flexibility of also recognizing JavaScript-style comments.

Comment Styles

The JSON::WithComments module will support the following named styles of comments:

javascript

This is the default, and recognizes both line comments denoted by //, and block comments denoted by /* followed at some point by */. This is also the style used by C/C++, but as JSON itself is based in the JavaScript world, this style is referred to as javascript.

perl

This is an optional style that can be specified either by setting the default style perl via the -default_comment_style import option, or by using the comment_style method. This style recognizes line comments delimited by a # character, and does not have a block-style comment.

JavaScript comment delimiters may be prefixed with a backslash character (\) to prevent their removal. This may be needed if the delimiter character(s) appear in a string, for example. Perl comments do not need this when appearing in a string.

IMPORT OPTIONS

The class provides an import method which will process any arguments specific to this class, before passing everything else to the parent class. Currently, there is only one option recognized:

-default_comment_style style

Set a different default comment style. If not given, the default is javascript. Must be one of perl or javascript, otherwise it dies via croak.

SUBROUTINES/METHODS

This class provides the following methods:

new

This method is the class constructor. It simply allocates an object of the class, then calls comment_style with the default style to set that property on the object. It returns the new object reference.

comment_style

This method takes a single value and sets it to be the new comment style for the calling object. The new value must be one of the named styles listed above. If an unknown style is specified, the method dies using croak. The return value is the object reference itself.

get_comment_style

Returns the object's comment style.

decode

This method takes one argument, the JSON text to parse. For comment styles other than perl, the text is scrubbed of the comments. Then the superclass decode method is called on the text.

At present, this module does not facilitate the import of the non-method functions that JSON provides.

COMMENTS WITHIN STRINGS

If a comment appears within a string, it should not be removed. If the comment style for the object is perl, it will not be removed and it will not affect the parsing of the JSON.

However, if the comment style is javascript then the leading / character of the comment needs to be escaped using the backslash (\) character. This conforms to the JSON specification for escaping characters, and will result in just the / character appearing in the string post-parsing.

For example, given the following JSON text:

    {
       "key1" : "\// scalar value",
       "key2" : "\/* start",
       "key3" : "end */"
    }

Upon parsing, the resulting hash reference will have the string // scalar value in slot key1, and /* start in slot key2. Slot key3 will have end */ because there is nothing in it that needed to be escaped.

DIAGNOSTICS

The JSON module reports parsing errors by throwing an exception (dying) and reporting the character offset within the string at which the error occurred. This module attempts to preserve that behavior by replacing comments with an equal-length string of spaces. As such, if you see a parsing error that refers to character 1023, the comments should not interfere with your ability to go to character 1023 via your preferred text editor and see the actual source of the error.

Additionally, trying to set the comment-style to an unknown value (either in the comment_style method or at import time) will result in an exception.

CAVEATS

Comments are not an official feature of JSON, so by using comments with JSON data you are limiting the range of tools that you can use with that data. If in the future a new JSON standard is published that supports comments, this module will have to be updated (or deprecated) accordingly.

Perl comments are handled by setting the relaxed property on the object. This allows the comments, but also allows another extension to the JSON syntax. This means that when using perl comments, your parsing is more lax than when using javascript comments. See the entry for relaxed in the JSON module's manual page.

Using the property method from the JSON class will not include the comment_style property.

BUGS

As this is alpha software, the likelihood of bugs is pretty close to 100%. Please report any issues you find to either the CPAN RT instance or to the GitHub issues page:

SUPPORT

LICENSE AND COPYRIGHT

This file and the code within are copyright (c) 2017 by Randy J. Ray.

Copying and distribution are permitted under the terms of the Artistic License 1.0 or the GNU GPL 1. See the file LICENSE in the distribution of this module.

AUTHOR

Randy J. Ray <rjray@blackperl.com>