{
    "content": [
        {
            "type": "text",
            "text": "# Class::Struct (perldoc)\n\n## NAME\n\nClass::Struct - declare struct-like datatypes as Perl classes\n\n## SYNOPSIS\n\nuse Class::Struct;\n# declare struct, based on array:\nstruct( CLASSNAME => [ ELEMENTNAME => ELEMENTTYPE, ... ]);\n# declare struct, based on hash:\nstruct( CLASSNAME => { ELEMENTNAME => ELEMENTTYPE, ... });\npackage CLASSNAME;\nuse Class::Struct;\n# declare struct, based on array, implicit class name:\nstruct( ELEMENTNAME => ELEMENTTYPE, ... );\n# Declare struct at compile time\nuse Class::Struct CLASSNAME => [ELEMENTNAME => ELEMENTTYPE, ...];\nuse Class::Struct CLASSNAME => {ELEMENTNAME => ELEMENTTYPE, ...};\n# declare struct at compile time, based on array, implicit\n# class name:\npackage CLASSNAME;\nuse Class::Struct ELEMENTNAME => ELEMENTTYPE, ... ;\npackage Myobj;\nuse Class::Struct;\n# declare struct with four types of elements:\nstruct( s => '$', a => '@', h => '%', c => 'MyOtherClass' );\n$obj = new Myobj;               # constructor\n# scalar type accessor:\n$elementvalue = $obj->s;           # element value\n$obj->s('new value');               # assign to element\n# array type accessor:\n$aryref = $obj->a;                 # reference to whole array\n$aryelementvalue = $obj->a(2);    # array element value\n$obj->a(2, 'new value');            # assign to array element\n# hash type accessor:\n$hashref = $obj->h;                # reference to whole hash\n$hashelementvalue = $obj->h('x'); # hash element value\n$obj->h('x', 'new value');          # assign to hash element\n# class type accessor:\n$elementvalue = $obj->c;           # object reference\n$obj->c->method(...);               # call method of object\n$obj->c(new MyOtherClass);        # assign a new object\n\n## DESCRIPTION\n\n\"Class::Struct\" exports a single function, \"struct\". Given a list of element names and types,\nand optionally a class name, \"struct\" creates a Perl 5 class that implements a \"struct-like\"\ndata structure.\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION** (2 subsections)\n- **EXAMPLES**\n- **Author and Modification History**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "Class::Struct",
        "section": "",
        "mode": "perldoc",
        "summary": "Class::Struct - declare struct-like datatypes as Perl classes",
        "synopsis": "use Class::Struct;\n# declare struct, based on array:\nstruct( CLASSNAME => [ ELEMENTNAME => ELEMENTTYPE, ... ]);\n# declare struct, based on hash:\nstruct( CLASSNAME => { ELEMENTNAME => ELEMENTTYPE, ... });\npackage CLASSNAME;\nuse Class::Struct;\n# declare struct, based on array, implicit class name:\nstruct( ELEMENTNAME => ELEMENTTYPE, ... );\n# Declare struct at compile time\nuse Class::Struct CLASSNAME => [ELEMENTNAME => ELEMENTTYPE, ...];\nuse Class::Struct CLASSNAME => {ELEMENTNAME => ELEMENTTYPE, ...};\n# declare struct at compile time, based on array, implicit\n# class name:\npackage CLASSNAME;\nuse Class::Struct ELEMENTNAME => ELEMENTTYPE, ... ;\npackage Myobj;\nuse Class::Struct;\n# declare struct with four types of elements:\nstruct( s => '$', a => '@', h => '%', c => 'MyOtherClass' );\n$obj = new Myobj;               # constructor\n# scalar type accessor:\n$elementvalue = $obj->s;           # element value\n$obj->s('new value');               # assign to element\n# array type accessor:\n$aryref = $obj->a;                 # reference to whole array\n$aryelementvalue = $obj->a(2);    # array element value\n$obj->a(2, 'new value');            # assign to array element\n# hash type accessor:\n$hashref = $obj->h;                # reference to whole hash\n$hashelementvalue = $obj->h('x'); # hash element value\n$obj->h('x', 'new value');          # assign to hash element\n# class type accessor:\n$elementvalue = $obj->c;           # object reference\n$obj->c->method(...);               # call method of object\n$obj->c(new MyOtherClass);        # assign a new object",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [
            "Example 1",
            "Giving a struct element a class type that is also a struct is how structs are nested. Here,",
            "\"Timeval\" represents a time (seconds and microseconds), and \"Rusage\" has two elements, each",
            "of which is of type \"Timeval\".",
            "use Class::Struct;",
            "struct( Rusage => {",
            "ruutime => 'Timeval',  # user time used",
            "rustime => 'Timeval',  # system time used",
            "});",
            "struct( Timeval => [",
            "tvsecs  => '$',        # seconds",
            "tvusecs => '$',        # microseconds",
            "]);",
            "# create an object:",
            "my $t = Rusage->new(ruutime=>Timeval->new(),",
            "rustime=>Timeval->new());",
            "# $t->ruutime and $t->rustime are objects of type Timeval.",
            "# set $t->ruutime to 100.0 sec and $t->rustime to 5.0 sec.",
            "$t->ruutime->tvsecs(100);",
            "$t->ruutime->tvusecs(0);",
            "$t->rustime->tvsecs(5);",
            "$t->rustime->tvusecs(0);",
            "Example 2",
            "An accessor function can be redefined in order to provide additional checking of values,",
            "etc. Here, we want the \"count\" element always to be nonnegative, so we redefine the \"count\"",
            "accessor accordingly.",
            "package MyObj;",
            "use Class::Struct;",
            "# declare the struct",
            "struct ( 'MyObj', { count => '$', stuff => '%' } );",
            "# override the default accessor method for 'count'",
            "sub count {",
            "my $self = shift;",
            "if ( @ ) {",
            "die 'count must be nonnegative' if $[0] < 0;",
            "$self->{'MyObj::count'} = shift;",
            "warn \"Too many args to count\" if @;",
            "return $self->{'MyObj::count'};",
            "package main;",
            "$x = new MyObj;",
            "print \"\\$x->count(5) = \", $x->count(5), \"\\n\";",
            "# prints '$x->count(5) = 5'",
            "print \"\\$x->count = \", $x->count, \"\\n\";",
            "# prints '$x->count = 5'",
            "print \"\\$x->count(-5) = \", $x->count(-5), \"\\n\";",
            "# dies due to negative argument!",
            "Example 3",
            "The constructor of a generated class can be passed a list of *element*=>*value* pairs, with",
            "which to initialize the struct. If no initializer is specified for a particular element, its",
            "default initialization is performed instead. Initializers for non-existent elements are",
            "silently ignored.",
            "Note that the initializer for a nested class may be specified as an object of that class, or",
            "as a reference to a hash of initializers that are passed on to the nested struct's",
            "constructor.",
            "use Class::Struct;",
            "struct Breed =>",
            "name  => '$',",
            "cross => '$',",
            "};",
            "struct Cat =>",
            "name     => '$',",
            "kittens  => '@',",
            "markings => '%',",
            "breed    => 'Breed',",
            "];",
            "my $cat = Cat->new( name => 'Socks',",
            "kittens  => ['Monica', 'Kenneth'],",
            "markings => { socks=>1, blaze=>\"white\" },",
            "breed    => Breed->new(name=>'short-hair', cross=>1),",
            "or:  breed    => {name=>'short-hair', cross=>1},",
            ");",
            "print \"Once a cat called \", $cat->name, \"\\n\";",
            "print \"(which was a \", $cat->breed->name, \")\\n\";",
            "print \"had 2 kittens: \", join(' and ', @{$cat->kittens}), \"\\n\";"
        ],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 46,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 42,
                "subsections": [
                    {
                        "name": "Class Creation at Compile Time",
                        "lines": 7
                    },
                    {
                        "name": "Element Types and Accessor Methods",
                        "lines": 68
                    }
                ]
            },
            {
                "name": "EXAMPLES",
                "lines": 99,
                "subsections": []
            },
            {
                "name": "Author and Modification History",
                "lines": 67,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "Class::Struct - declare struct-like datatypes as Perl classes\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use Class::Struct;\n# declare struct, based on array:\nstruct( CLASSNAME => [ ELEMENTNAME => ELEMENTTYPE, ... ]);\n# declare struct, based on hash:\nstruct( CLASSNAME => { ELEMENTNAME => ELEMENTTYPE, ... });\n\npackage CLASSNAME;\nuse Class::Struct;\n# declare struct, based on array, implicit class name:\nstruct( ELEMENTNAME => ELEMENTTYPE, ... );\n\n# Declare struct at compile time\nuse Class::Struct CLASSNAME => [ELEMENTNAME => ELEMENTTYPE, ...];\nuse Class::Struct CLASSNAME => {ELEMENTNAME => ELEMENTTYPE, ...};\n\n# declare struct at compile time, based on array, implicit\n# class name:\npackage CLASSNAME;\nuse Class::Struct ELEMENTNAME => ELEMENTTYPE, ... ;\n\npackage Myobj;\nuse Class::Struct;\n# declare struct with four types of elements:\nstruct( s => '$', a => '@', h => '%', c => 'MyOtherClass' );\n\n$obj = new Myobj;               # constructor\n\n# scalar type accessor:\n$elementvalue = $obj->s;           # element value\n$obj->s('new value');               # assign to element\n\n# array type accessor:\n$aryref = $obj->a;                 # reference to whole array\n$aryelementvalue = $obj->a(2);    # array element value\n$obj->a(2, 'new value');            # assign to array element\n\n# hash type accessor:\n$hashref = $obj->h;                # reference to whole hash\n$hashelementvalue = $obj->h('x'); # hash element value\n$obj->h('x', 'new value');          # assign to hash element\n\n# class type accessor:\n$elementvalue = $obj->c;           # object reference\n$obj->c->method(...);               # call method of object\n$obj->c(new MyOtherClass);        # assign a new object\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "\"Class::Struct\" exports a single function, \"struct\". Given a list of element names and types,\nand optionally a class name, \"struct\" creates a Perl 5 class that implements a \"struct-like\"\ndata structure.\n\nThe new class is given a constructor method, \"new\", for creating struct objects.\n\nEach element in the struct data has an accessor method, which is used to assign to the element\nand to fetch its value. The default accessor can be overridden by declaring a \"sub\" of the same\nname in the package. (See Example 2.)\n\nEach element's type can be scalar, array, hash, or class.\n\nThe \"struct()\" function\nThe \"struct\" function has three forms of parameter-list.\n\nstruct( CLASSNAME => [ ELEMENTLIST ]);\nstruct( CLASSNAME => { ELEMENTLIST });\nstruct( ELEMENTLIST );\n\nThe first and second forms explicitly identify the name of the class being created. The third\nform assumes the current package name as the class name.\n\nAn object of a class created by the first and third forms is based on an array, whereas an\nobject of a class created by the second form is based on a hash. The array-based forms will be\nsomewhat faster and smaller; the hash-based forms are more flexible.\n\nThe class created by \"struct\" must not be a subclass of another class other than \"UNIVERSAL\".\n\nIt can, however, be used as a superclass for other classes. To facilitate this, the generated\nconstructor method uses a two-argument blessing. Furthermore, if the class is hash-based, the\nkey of each element is prefixed with the class name (see *Perl Cookbook*, Recipe 13.12).\n\nA function named \"new\" must not be explicitly defined in a class created by \"struct\".\n\nThe *ELEMENTLIST* has the form\n\nNAME => TYPE, ...\n\nEach name-type pair declares one element of the struct. Each element name will be defined as an\naccessor method unless a method by that name is explicitly defined; in the latter case, a\nwarning is issued if the warning flag (-w) is set.\n",
                "subsections": [
                    {
                        "name": "Class Creation at Compile Time",
                        "content": "\"Class::Struct\" can create your class at compile time. The main reason for doing this is\nobvious, so your class acts like every other class in Perl. Creating your class at compile time\nwill make the order of events similar to using any other class ( or Perl module ).\n\nThere is no significant speed gain between compile time and run time class creation, there is\njust a new, more standard order of events.\n"
                    },
                    {
                        "name": "Element Types and Accessor Methods",
                        "content": "The four element types -- scalar, array, hash, and class -- are represented by strings -- '$',\n'@', '%', and a class name -- optionally preceded by a '*'.\n\nThe accessor method provided by \"struct\" for an element depends on the declared type of the\nelement.\n\nScalar ('$' or '*$')\nThe element is a scalar, and by default is initialized to \"undef\" (but see \"Initializing\nwith new\").\n\nThe accessor's argument, if any, is assigned to the element.\n\nIf the element type is '$', the value of the element (after assignment) is returned. If the\nelement type is '*$', a reference to the element is returned.\n\nArray ('@' or '*@')\nThe element is an array, initialized by default to \"()\".\n\nWith no argument, the accessor returns a reference to the element's whole array (whether or\nnot the element was specified as '@' or '*@').\n\nWith one or two arguments, the first argument is an index specifying one element of the\narray; the second argument, if present, is assigned to the array element. If the element\ntype is '@', the accessor returns the array element value. If the element type is '*@', a\nreference to the array element is returned.\n\nAs a special case, when the accessor is called with an array reference as the sole argument,\nthis causes an assignment of the whole array element. The object reference is returned.\n\nHash ('%' or '*%')\nThe element is a hash, initialized by default to \"()\".\n\nWith no argument, the accessor returns a reference to the element's whole hash (whether or\nnot the element was specified as '%' or '*%').\n\nWith one or two arguments, the first argument is a key specifying one element of the hash;\nthe second argument, if present, is assigned to the hash element. If the element type is\n'%', the accessor returns the hash element value. If the element type is '*%', a reference\nto the hash element is returned.\n\nAs a special case, when the accessor is called with a hash reference as the sole argument,\nthis causes an assignment of the whole hash element. The object reference is returned.\n\nClass ('ClassName' or '*ClassName')\nThe element's value must be a reference blessed to the named class or to one of its\nsubclasses. The element is not initialized by default.\n\nThe accessor's argument, if any, is assigned to the element. The accessor will \"croak\" if\nthis is not an appropriate object reference.\n\nIf the element type does not start with a '*', the accessor returns the element value (after\nassignment). If the element type starts with a '*', a reference to the element itself is\nreturned.\n\nInitializing with \"new\"\n\"struct\" always creates a constructor called \"new\". That constructor may take a list of\ninitializers for the various elements of the new struct.\n\nEach initializer is a pair of values: *element name*\" => \"*value*. The initializer value for a\nscalar element is just a scalar value. The initializer for an array element is an array\nreference. The initializer for a hash is a hash reference.\n\nThe initializer for a class element is an object of the corresponding class, or of one of it's\nsubclasses, or a reference to a hash containing named arguments to be passed to the element's\nconstructor.\n\nSee Example 3 below for an example of initialization.\n"
                    }
                ]
            },
            "EXAMPLES": {
                "content": "Example 1\nGiving a struct element a class type that is also a struct is how structs are nested. Here,\n\"Timeval\" represents a time (seconds and microseconds), and \"Rusage\" has two elements, each\nof which is of type \"Timeval\".\n\nuse Class::Struct;\n\nstruct( Rusage => {\nruutime => 'Timeval',  # user time used\nrustime => 'Timeval',  # system time used\n});\n\nstruct( Timeval => [\ntvsecs  => '$',        # seconds\ntvusecs => '$',        # microseconds\n]);\n\n# create an object:\nmy $t = Rusage->new(ruutime=>Timeval->new(),\nrustime=>Timeval->new());\n\n# $t->ruutime and $t->rustime are objects of type Timeval.\n# set $t->ruutime to 100.0 sec and $t->rustime to 5.0 sec.\n$t->ruutime->tvsecs(100);\n$t->ruutime->tvusecs(0);\n$t->rustime->tvsecs(5);\n$t->rustime->tvusecs(0);\n\nExample 2\nAn accessor function can be redefined in order to provide additional checking of values,\netc. Here, we want the \"count\" element always to be nonnegative, so we redefine the \"count\"\naccessor accordingly.\n\npackage MyObj;\nuse Class::Struct;\n\n# declare the struct\nstruct ( 'MyObj', { count => '$', stuff => '%' } );\n\n# override the default accessor method for 'count'\nsub count {\nmy $self = shift;\nif ( @ ) {\ndie 'count must be nonnegative' if $[0] < 0;\n$self->{'MyObj::count'} = shift;\nwarn \"Too many args to count\" if @;\n}\nreturn $self->{'MyObj::count'};\n}\n\npackage main;\n$x = new MyObj;\nprint \"\\$x->count(5) = \", $x->count(5), \"\\n\";\n# prints '$x->count(5) = 5'\n\nprint \"\\$x->count = \", $x->count, \"\\n\";\n# prints '$x->count = 5'\n\nprint \"\\$x->count(-5) = \", $x->count(-5), \"\\n\";\n# dies due to negative argument!\n\nExample 3\nThe constructor of a generated class can be passed a list of *element*=>*value* pairs, with\nwhich to initialize the struct. If no initializer is specified for a particular element, its\ndefault initialization is performed instead. Initializers for non-existent elements are\nsilently ignored.\n\nNote that the initializer for a nested class may be specified as an object of that class, or\nas a reference to a hash of initializers that are passed on to the nested struct's\nconstructor.\n\nuse Class::Struct;\n\nstruct Breed =>\n{\nname  => '$',\ncross => '$',\n};\n\nstruct Cat =>\n[\nname     => '$',\nkittens  => '@',\nmarkings => '%',\nbreed    => 'Breed',\n];\n\n\nmy $cat = Cat->new( name => 'Socks',\nkittens  => ['Monica', 'Kenneth'],\nmarkings => { socks=>1, blaze=>\"white\" },\nbreed    => Breed->new(name=>'short-hair', cross=>1),\nor:  breed    => {name=>'short-hair', cross=>1},\n);\n\nprint \"Once a cat called \", $cat->name, \"\\n\";\nprint \"(which was a \", $cat->breed->name, \")\\n\";\nprint \"had 2 kittens: \", join(' and ', @{$cat->kittens}), \"\\n\";\n",
                "subsections": []
            },
            "Author and Modification History": {
                "content": "Modified by Damian Conway, 2001-09-10, v0.62.\n\nModified implicit construction of nested objects.\nNow will also take an object ref instead of requiring a hash ref.\nAlso default initializes nested object attributes to undef, rather\nthan calling object constructor without args\nOriginal over-helpfulness was fraught with problems:\n* the class's constructor might not be called 'new'\n* the class might not have a hash-like-arguments constructor\n* the class might not have a no-argument constructor\n* \"recursive\" data structures didn't work well:\npackage Person;\nstruct { mother => 'Person', father => 'Person'};\n\nModified by Casey West, 2000-11-08, v0.59.\n\nAdded the ability for compile time class creation.\n\nModified by Damian Conway, 1999-03-05, v0.58.\n\nAdded handling of hash-like arg list to class ctor.\n\nChanged to two-argument blessing in ctor to support\nderivation from created classes.\n\nAdded classname prefixes to keys in hash-based classes\n(refer to \"Perl Cookbook\", Recipe 13.12 for rationale).\n\nCorrected behaviour of accessors for '*@' and '*%' struct\nelements.  Package now implements documented behaviour when\nreturning a reference to an entire hash or array element.\nPreviously these were returned as a reference to a reference\nto the element.\n\nRenamed to \"Class::Struct\" and modified by Jim Miner, 1997-04-02.\n\nmembers() function removed.\nDocumentation corrected and extended.\nUse of struct() in a subclass prohibited.\nUser definition of accessor allowed.\nTreatment of '*' in element types corrected.\nTreatment of classes as element types corrected.\nClass name to struct() made optional.\nDiagnostic checks added.\n\nOriginally \"Class::Template\" by Dean Roehrich.\n\n# Template.pm   --- struct/member template builder\n#   12mar95\n#   Dean Roehrich\n#\n# changes/bugs fixed since 28nov94 version:\n#  - podified\n# changes/bugs fixed since 21nov94 version:\n#  - Fixed examples.\n# changes/bugs fixed since 02sep94 version:\n#  - Moved to Class::Template.\n# changes/bugs fixed since 20feb94 version:\n#  - Updated to be a more proper module.\n#  - Added \"use strict\".\n#  - Bug in buildmethods, was using @var when @$var needed.\n#  - Now using my() rather than local().\n#\n# Uses perl5 classes to create nested data types.\n# This is offered as one implementation of Tom Christiansen's\n# \"structs.pl\" idea.\n",
                "subsections": []
            }
        }
    }
}