The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MetaPOD::JSON - The JSON Formatted MetaPOD Spec

VERSION

version v0.5.0

SYNOPSIS

This is mostly a documentation stub, documenting the JSON Formatted version of MetaPOD

The Actual Implementation is stored in ::Format::JSON

Using MetaPOD::JSON in your documentation

    =begin MetaPOD::JSON

    {  "valid_json_data":"goes_here" }

    =end

or

    =for MetaPOD::JSON { valid_json_data }

    =cut

You can also declare a version for which semantics to imbue into the declaration.

    =begin MetaPOD::JSON v1.0.0

as Per ::Spec, the "v" is required, and the version semantics are always dotted decimal.

Note: As Per ::Spec, the version is NOT a minimum version requirement, but a declaration of the versions semantics the containing declaration is encoded in. Given implementations MAY support multiple versions, or they MAY NOT support multiple versions.

It is ENCOURAGED that wherever possible to support the WIDEST variety of versions.

SPEC VERSION v1.2.1

This version of the spec is mostly identical to "SPEC VERSION v1.2.0", and it is bi-directionally compatible with it.

However, v1.2.0 made the omission of the definition of sub.entry, and this spec revision simply corrects that defect.

sub.entry

In v1.2.1, a sub.entry is a simple HASH, with only 1 supported key.

name

    { "name":"SomeName" }

This field should describe the name of the sub symbol it pertains to.

At the time of this spec, there is no way to declare multiple facets of a single sub description in separate declarations.

The following POD code

    =begin MetaPOD::JSON v1.2.1

    { "subs": [ { "name":"Foo" } ] }

    =end MetaPOD::JSON

    =begin MetaPOD::JSON v1.2.1

    { "subs": [ { "name":"Foo" } ] }

    =end MetaPOD::JSON

is equivalent to

    =begin MetaPOD::JSON v1.2.1

    { "subs": [ { "name":"Foo" }, { "name":"Foo" } ] }

    =end MetaPOD::JSON

Which simply communicates that although it is only possible for there to be one physical Perl sub Foo, some internal dispatch magic differences means they're effectively two separate sub's from the context of calling code.

( For instance, when signature support is added, they may have different signatures and different signatures have different behaviours, and its clearer to simply document each kind of behaviour as a separate method than to try codify the complex logic of how the internal signature conditions work )

SPEC VERSION v1.2.0

This version of the spec is mostly identical to "SPEC VERSION v1.1.0", and it MUST support all features of that version, with the following additions.

subs

subs, are a low-level critical component of any Perl Module. A sub may manifest in various forms, some being exported, others being inherited or composed. Some subs are methods, other subs are functions. Some subs are dynamically generated from attribute declarations, or are delegates for attribute methods.

The distinction between all these types will be improved upon in a future release of MetaPOD::Spec

So, with that said, any sub declaration in this version of MetaPOD::JSON simply indicates that a coderef of some description is accessible to calling code at the name namespace::sub.

This include, but is not limited to, things like BUILD, BUILDARGS and import.

It is important to understand that this data is intended to articulate ONLY subs that are declared IN and BY the given namespace.

Thus, documenting subs that are inherited, composed, or imported into the namespace is considered an ERROR, as observing that data is intended to require observing the inheritance model.

Method Modifiers such as override, around, etc, for the purposes of this feature, should be considered the same as simply having re-declared the sub by the same name.

subs as a single token

Supporting this version of the spec MUST implement support for this notation:

    { "subs" : "BUILD" }

This should be interpreted the same as

    { "subs" : [ "BUILD" ] }

Which is the same as

    { "subs" : [ { "name" : "BUILD" } ] }

See also Multiple Declaration

subs as a single hash

Supporting this version of the spec MUST implement support for this notation:

    { "subs" : { "name":"BUILD" } }

This should be interpreted the same as

    { "subs" : [ { "name" : "BUILD" } ] }

See also Multiple Declaration

subs as a list of tokens

Supporting this version of the spec MUST implement support for this notation:

    { "subs": [ "BUILD", "import", "add_foo" ] }

This logic should be interpreted as a declaration of a list of ambiguously defined subs, and identical to

    { "subs": [
        { "name": "BUILD" },
        { "name": "import" },
        { "name": "add_foo" }
    ] }

As such, duplicate tokens SHOULD be supported. ( This proviso is to add scope for multiple dispatch with a list of identically named methods with different signatures and behaviours )

subs as a list of HASH entries.

Supporting this version of the spec MUST implement support for this notation:

    { "subs": [ {entry}, {entry}, {entry} ] }

Each entry should be interpreted as an individual sub declaration, as specified by sub.entry. Duplicates permitted.

subs as a list of mixed tokens and HASH entries.

Supporting this version of the spec MUST implement support for this notation:

    { "subs": [ "BUILD", { "name":"import" } ] }

As with the list of tokens, non HASH entries should be inflated to HASH entries by transforming as

    "entry" => { "name": "entry" }

Multiple Declaration

Implementations SHOULD support multiple declarations for this field similar to how interface works.

So:

    { "subs": "foo" }
    { "subs": [ "foo" ] }

Should be equivalent.

    { "subs": "foo" } +  { "subs": "foo" }
    { "subs": [ "foo", "foo" ] }

And

    { "subs": [ "foo"  ] } +  { "subs": [ "bar" ] }
    { "subs": [ "foo", "bar" ] }

sub.entry

This field was not formally designed in the release of v1.2.0 spec, and although the definition of the field seems obvious enough when looking at the sub specification, it is not formally described.

This should be resolved in the v1.2.1 spec.

Though consuming MetaPOD documentation should be usable with either.

SPEC VERSION v1.1.0

This version of the spec is mostly identical to "SPEC VERSION v1.0.0", and it MUST support all features of that version, with the following additions.

interface

There are many ways for Perl Name spaces to behave, and this property indicates what style of interfaces a given name space supports.

SPEC VERSION v1.1.0 Supports 6 interface types:

  • class - Indicating the given name space has a constructor of some kind, which returns a bless'ed object.

    For instance, if your synopsis looks like this:

        use Foo;
        my $instance = Foo->new();
        $instance->();

    Then you should include class in your "interface" list.

  • role - Indicating the given namespace is a "role" of some kind, and cannot be instantiated, only composed into other classes.

    For instance, if your synopsis looks like this:

        package Foo;
        use Moo;
        with "YourNameSpace";

    You should include role in your "interface" list.

  • exporter - Indicating the given namespace exports things into the caller

    For instance, if your synopsis looks like this:

        use Foo qw( func );
        use Foo;
        bar(); # Exported by Foo

    Then you should include exporter in your "interface" list.

    This includes things like Moo and Moose which export functions like has into the calling namespace.

  • functions - Indicating a namespace which has functions intended to be called via fully qualified names.

    For instance, if your synopsis looks like this:

        use Foo;
        Foo::bar();

    Then you should include functions in your "interface" list.

  • single_class - A Hybrid between functions and class, a namespace which has methods, but no constructor, and the namespace itself behaves much like a singleton.

    For instance, if your synopsis looks like this:

        use Foo;
        Foo->set_thing( 1 );

    Then you should include singleclass in your "interface" list.

    These usages are also candidates for singleclass "interface"es.

        Foo->copy( $a , $b ); # a and/or b is modified, but no object is returned
        my $result = Foo->bar(); # $result is not an object

    However, this is not an example of the single_class interface:

        use Foo;
        my $instance = Foo->writer( $bar );
        $instance->method();

    Because here, writer doesn't modify the state of Foo, and writer could be seen as simply an alternative constructor.

  • type_library - A Type Library of some kind.

    For instance, if your class uses Moose::Util::TypeConstraints to create a named type of some kind, and that type is accessible via

        has Foo => (
            isa => 'TypeName'
        );

    Then you want to include type_library in your "interface" list.

    Note: Some type libraries, notably MooseX::Types perform type creation in addition to exporting, and for such libraries, you should include both type_library and exporter

Name spaces that meet above definitions SHOULD document such interfaces as such:

    { "interface": [ "class", "exporter" ]}

interface can be in one of 2 forms.

    { "interface" : $string }
    { "interface" : [ $string, $string, $string ] }

Both will perform logically appending either the string, or the list of elements, to an internal list which is deduplicated.

So that

    { "interface" : [ $a ]}
    { "interface" : [ $b ]}

And

    { "interface" : $a }
    { "interface" : $b }

Have the same effect, the result being the same as if you had specified

    { "interface" : [ $a, $b ] }

SPEC VERSION v1.0.0

Data collection

Spec version 1.0.0 is such that multiple declarations should be merged to form an aggregate

e.g.:

    =for MetaPOD::JSON v1.0.0 { "a":"b" }

    =for MetaPOD::JSON v1.0.0 { "c":"d" }

this should be the same as if one had done

    =begin MetaPOD::JSON v1.0.0

    {
        "a" : "b"
        "c" : "d"
    }

    =end MetaPOD::JSON

With the observation that latter keys may clobber preceding keys.

Scope

Because of the Data Collection design, it is not supported to declare multiple name-spaces within the same file at present.

This is mostly a practical consideration, as without this consideration, all declarations of class members would require re-stating the class, and that would quickly become tiresome.

KEYS

namespace

All MetaPOD::JSON containing documents SHOULD contain at least one namespace declaration.

Example:

    { "namespace": "My::Library" }

inherits

Any MetaPOD::JSON containing document that is known to inherit from another class, SHOULD document their inheritance as such:

    { "inherits": [ "Moose::Object" ]}

inherits can be in one of 2 forms.

    { "inherits" : $string }
    { "inherits" : [ $string, $string, $string ] }

Both will perform logically appending either the string, or the list of elements, to an internal list which is deduplicated.

So that

    { "inherits" : [ $a ]}
    { "inherits" : [ $b ]}

And

    { "inherits" : $a }
    { "inherits" : $b }

Have the same effect, the result being the same as if you had specified

    { "inherits" : [ $a, $b ] }

does

Any MetaPOD::JSON containing document that is known to "do" another role, SHOULD document their inheritance as such:

    { "does": [ "Some::Role" ]}

does can be in one of 2 forms.

    { "does" : $string }
    { "does" : [ $string, $string, $string ] }

Both will perform logically appending either the string, or the list of elements, to an internal list which is deduplicated.

So that

    { "does" : [ $a ]}
    { "does" : [ $b ]}

And

    { "does" : $a }
    { "does" : $b }

Have the same effect, the result being the same as if you had specified

    { "does" : [ $a, $b ] }

AUTHOR

Kent Fredric <kentnl@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.