{
    "mode": "perldoc",
    "parameter": "Specio::Library::Structured",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Specio%3A%3ALibrary%3A%3AStructured/json",
    "generated": "2026-06-11T01:09:41Z",
    "synopsis": "use Specio::Library::Builtins;\nuse Specio::Library::String;\nuse Specio::Library::Structured;\nmy $map = t(\n'Map',\nof => {\nkey   => t('NonEmptyStr'),\nvalue => t('Int'),\n},\n);\nmy $tuple = t(\n'Tuple',\nof => [ t('Str'), t('Num') ],\n);\nmy $dict = t(\n'Dict',\nof => {\nkv => {\nname => t('Str'),\nage  => t('Int'),\n},\n},\n);",
    "sections": {
        "NAME": {
            "content": "Specio::Library::Structured - Structured types for Specio (Dict, Map, Tuple)\n",
            "subsections": []
        },
        "VERSION": {
            "content": "version 0.47\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "use Specio::Library::Builtins;\nuse Specio::Library::String;\nuse Specio::Library::Structured;\n\nmy $map = t(\n'Map',\nof => {\nkey   => t('NonEmptyStr'),\nvalue => t('Int'),\n},\n);\nmy $tuple = t(\n'Tuple',\nof => [ t('Str'), t('Num') ],\n);\nmy $dict = t(\n'Dict',\nof => {\nkv => {\nname => t('Str'),\nage  => t('Int'),\n},\n},\n);\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "This particular library should be considered in an alpha state. The syntax for defining\nstructured types may change, as well as some of the internals of its implementation.\n\nThis library provides a set of structured types for Specio, \"Dict\", \"Map\", and \"Tuple\". This\nlibrary also exports two helper subs used for some types, \"optional\" and \"slurpy\".\n\nAll structured types are parameterized by calling \"t( 'Type Name', of => ... )\". The arguments\npassed after \"of\" vary for each type.\n",
            "subsections": [
                {
                    "name": "Dict",
                    "content": "A \"Dict\" is a hashref with a well-defined set of keys and types for those key.\n\nThe argument passed to \"of\" should be a single hashref. That hashref must contain a \"kv\" key\ndefining the expected keys and the types for their values. This \"kv\" value is itself a hashref.\nIf a key/value pair is optional, use \"optional\" around the *type* for that key:\n\nmy $person = t(\n'Dict',\nof => {\nkv => {\nfirst  => t('NonEmptyStr'),\nmiddle => optional( t('NonEmptyStr') ),\nlast   => t('NonEmptyStr'),\n},\n},\n);\n\nIf a key is optional, then it can be omitted entirely, but if it passed then it's type will be\nchecked, so it cannot just be set to \"undef\".\n\nYou can also pass a \"slurpy\" key. If this is passed, then the \"Dict\" will allow other, unknown\nkeys, as long as they match the specified type:\n\nmy $person = t(\n'Dict',\nof => {\nkv => {\nfirst  => t('NonEmptyStr'),\nmiddle => optional( t('NonEmptyStr') ),\nlast   => t('NonEmptyStr'),\n},\nslurpy => t('Int'),\n},\n);\n"
                },
                {
                    "name": "Map",
                    "content": "A \"Map\" is a hashref with specified types for its keys and values, but no well-defined key\nnames.\n\nThe argument passed to \"of\" should be a single hashref with two keys, \"key\" and \"value\". The\ntype for the \"key\" will typically be some sort of key, but if you're using a tied hash or an\nobject with hash overloading it could conceivably be any sort of value.\n"
                },
                {
                    "name": "Tuple",
                    "content": "A \"Tuple\" is an arrayref with a fixed set of members in a specific order.\n\nThe argument passed to \"of\" should be a single arrayref consisting of types. You can mark a slot\nin the \"Tuple\" as optional by wrapping the type in a call to \"optional\":\n\nmy $record = t(\n'Tuple',\nof => [\nt('PositiveInt'),\nt('Str'),\noptional( t('Num') ),\noptional( t('Num') ),\n],\n);\n\nYou can have as many \"optional\" elements as you want, but they must always come in sequence at\nthe end of the tuple definition. You cannot interleave required and optional elements.\n\nYou can also make the Tuple accept an arbitrary number of values by wrapping the last type in a\ncall to \"slurpy\":\n\nmy $record = t(\n'Tuple',\nof => [\nt('PositiveInt'),\nt('Str'),\nslurpy( t('Num') ),\n],\n);\n\nIn this case, the \"Tuple\" will require the first two elements and then allow any number\n(including zero) of \"Num\" elements.\n\nYou cannot mix \"optional\" and \"slurpy\" in a \"Tuple\" definition.\n"
                }
            ]
        },
        "LIMITATIONS": {
            "content": "Currently all structured types require that the types they are structured with can be inlined.\nThis may change in the future, but inlining all your types is a really good idea, so you should\ndo that anyway.\n",
            "subsections": []
        },
        "SUPPORT": {
            "content": "Bugs may be submitted at <https://github.com/houseabsolute/Specio/issues>.\n\nI am also usually active on IRC as 'autarch' on \"irc://irc.perl.org\".\n",
            "subsections": []
        },
        "SOURCE": {
            "content": "The source code repository for Specio can be found at <https://github.com/houseabsolute/Specio>.\n",
            "subsections": []
        },
        "AUTHOR": {
            "content": "Dave Rolsky <autarch@urth.org>\n",
            "subsections": []
        },
        "COPYRIGHT AND LICENSE": {
            "content": "This software is Copyright (c) 2012 - 2021 by Dave Rolsky.\n\nThis is free software, licensed under:\n\nThe Artistic License 2.0 (GPL Compatible)\n\nThe full text of the license can be found in the LICENSE file included with this distribution.\n",
            "subsections": []
        }
    },
    "summary": "Specio::Library::Structured - Structured types for Specio (Dict, Map, Tuple)",
    "flags": [],
    "examples": [],
    "see_also": []
}