home *** CD-ROM | disk | FTP | other *** search
-
- <HTML>
- <HEAD>
- <TITLE>Class::Struct - declare struct-like datatypes as Perl classes</TITLE>
- <LINK REL="stylesheet" HREF="../../Active.css" TYPE="text/css">
- <LINK REV="made" HREF="mailto:">
- </HEAD>
-
- <BODY>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Class::Struct - declare struct-like datatypes as Perl classes</P></STRONG>
- </TD></TR>
- </TABLE>
-
- <A NAME="__index__"></A>
- <!-- INDEX BEGIN -->
-
- <UL>
-
- <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
-
- <LI><A HREF="#synopsis">SYNOPSIS</A></LI>
- <LI><A HREF="#description">DESCRIPTION</A></LI>
- <UL>
-
- <LI><A HREF="#the struct() function">The <CODE>struct()</CODE> function</A></LI>
- <LI><A HREF="#element types and accessor methods">Element Types and Accessor Methods</A></LI>
- <LI><A HREF="#initializing with new">Initializing with <CODE>new</CODE></A></LI>
- </UL>
-
- <LI><A HREF="#examples">EXAMPLES</A></LI>
- <LI><A HREF="#author and modification history">Author and Modification History</A></LI>
- </UL>
- <!-- INDEX END -->
-
- <HR>
- <P>
- <H1><A NAME="name">NAME</A></H1>
- <P>Class::Struct - declare struct-like datatypes as Perl classes</P>
- <P>
- <HR>
- <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
- <UL>
- <LI>Linux</LI>
- <LI>Solaris</LI>
- <LI>Windows</LI>
- </UL>
- <HR>
- <H1><A NAME="synopsis">SYNOPSIS</A></H1>
- <PRE>
- use Class::Struct;
- # declare struct, based on array:
- struct( CLASS_NAME => [ ELEMENT_NAME => ELEMENT_TYPE, ... ]);
- # declare struct, based on hash:
- struct( CLASS_NAME => { ELEMENT_NAME => ELEMENT_TYPE, ... });</PRE>
- <PRE>
- package CLASS_NAME;
- use Class::Struct;
- # declare struct, based on array, implicit class name:
- struct( ELEMENT_NAME => ELEMENT_TYPE, ... );</PRE>
- <PRE>
- package Myobj;
- use Class::Struct;
- # declare struct with four types of elements:
- struct( s => '$', a => '@', h => '%', c => 'My_Other_Class' );</PRE>
- <PRE>
- $obj = new Myobj; # constructor</PRE>
- <PRE>
- # scalar type accessor:
- $element_value = $obj->s; # element value
- $obj->s('new value'); # assign to element</PRE>
- <PRE>
- # array type accessor:
- $ary_ref = $obj->a; # reference to whole array
- $ary_element_value = $obj->a(2); # array element value
- $obj->a(2, 'new value'); # assign to array element</PRE>
- <PRE>
- # hash type accessor:
- $hash_ref = $obj->h; # reference to whole hash
- $hash_element_value = $obj->h('x'); # hash element value
- $obj->h('x', 'new value'); # assign to hash element</PRE>
- <PRE>
- # class type accessor:
- $element_value = $obj->c; # object reference
- $obj->c->method(...); # call method of object
- $obj->c(new My_Other_Class); # assign a new object</PRE>
- <P>
- <HR>
- <H1><A NAME="description">DESCRIPTION</A></H1>
- <P><CODE>Class::Struct</CODE> exports a single function, <CODE>struct</CODE>.
- Given a list of element names and types, and optionally
- a class name, <CODE>struct</CODE> creates a Perl 5 class that implements
- a ``struct-like'' data structure.</P>
- <P>The new class is given a constructor method, <CODE>new</CODE>, for creating
- struct objects.</P>
- <P>Each element in the struct data has an accessor method, which is
- used to assign to the element and to fetch its value. The
- default accessor can be overridden by declaring a <A HREF="../../lib/Pod/perlfunc.html#item_sub"><CODE>sub</CODE></A> of the
- same name in the package. (See Example 2.)</P>
- <P>Each element's type can be scalar, array, hash, or class.</P>
- <P>
- <H2><A NAME="the struct() function">The <CODE>struct()</CODE> function</A></H2>
- <P>The <CODE>struct</CODE> function has three forms of parameter-list.</P>
- <PRE>
- struct( CLASS_NAME => [ ELEMENT_LIST ]);
- struct( CLASS_NAME => { ELEMENT_LIST });
- struct( ELEMENT_LIST );</PRE>
- <P>The first and second forms explicitly identify the name of the
- class being created. The third form assumes the current package
- name as the class name.</P>
- <P>An object of a class created by the first and third forms is
- based on an array, whereas an object of a class created by the
- second form is based on a hash. The array-based forms will be
- somewhat faster and smaller; the hash-based forms are more
- flexible.</P>
- <P>The class created by <CODE>struct</CODE> must not be a subclass of another
- class other than <CODE>UNIVERSAL</CODE>.</P>
- <P>It can, however, be used as a superclass for other classes. To facilitate
- this, the generated constructor method uses a two-argument blessing.
- Furthermore, if the class is hash-based, the key of each element is
- prefixed with the class name (see <EM>Perl Cookbook</EM>, Recipe 13.12).</P>
- <P>A function named <CODE>new</CODE> must not be explicitly defined in a class
- created by <CODE>struct</CODE>.</P>
- <P>The <EM>ELEMENT_LIST</EM> has the form</P>
- <PRE>
- NAME => TYPE, ...</PRE>
- <P>Each name-type pair declares one element of the struct. Each
- element name will be defined as an accessor method unless a
- method by that name is explicitly defined; in the latter case, a
- warning is issued if the warning flag (<STRONG>-w</STRONG>) is set.</P>
- <P>
- <H2><A NAME="element types and accessor methods">Element Types and Accessor Methods</A></H2>
- <P>The four element types -- scalar, array, hash, and class -- are
- represented by strings -- <CODE>'$'</CODE>, <CODE>'@'</CODE>, <CODE>'%'</CODE>, and a class name --
- optionally preceded by a <CODE>'*'</CODE>.</P>
- <P>The accessor method provided by <CODE>struct</CODE> for an element depends
- on the declared type of the element.</P>
- <DL>
- <DT><STRONG><A NAME="item_Scalar">Scalar (<CODE>'$'</CODE> or <CODE>'*$'</CODE>)</A></STRONG><BR>
- <DD>
- The element is a scalar, and by default is initialized to <A HREF="../../lib/Pod/perlfunc.html#item_undef"><CODE>undef</CODE></A>
- (but see <A HREF="#initializing with new">Initializing with new</A>).
- <P>The accessor's argument, if any, is assigned to the element.</P>
- <P>If the element type is <CODE>'$'</CODE>, the value of the element (after
- assignment) is returned. If the element type is <CODE>'*$'</CODE>, a reference
- to the element is returned.</P>
- <P></P>
- <DT><STRONG><A NAME="item_Array">Array (<CODE>'@'</CODE> or <CODE>'*@'</CODE>)</A></STRONG><BR>
- <DD>
- The element is an array, initialized by default to <CODE>()</CODE>.
- <P>With no argument, the accessor returns a reference to the
- element's whole array (whether or not the element was
- specified as <CODE>'@'</CODE> or <CODE>'*@'</CODE>).</P>
- <P>With one or two arguments, the first argument is an index
- specifying one element of the array; the second argument, if
- present, is assigned to the array element. If the element type
- is <CODE>'@'</CODE>, the accessor returns the array element value. If the
- element type is <CODE>'*@'</CODE>, a reference to the array element is
- returned.</P>
- <P></P>
- <DT><STRONG><A NAME="item_Hash">Hash (<CODE>'%'</CODE> or <CODE>'*%'</CODE>)</A></STRONG><BR>
- <DD>
- The element is a hash, initialized by default to <CODE>()</CODE>.
- <P>With no argument, the accessor returns a reference to the
- element's whole hash (whether or not the element was
- specified as <CODE>'%'</CODE> or <CODE>'*%'</CODE>).</P>
- <P>With one or two arguments, the first argument is a key specifying
- one element of the hash; the second argument, if present, is
- assigned to the hash element. If the element type is <CODE>'%'</CODE>, the
- accessor returns the hash element value. If the element type is
- <CODE>'*%'</CODE>, a reference to the hash element is returned.</P>
- <P></P>
- <DT><STRONG><A NAME="item_Class">Class (<CODE>'Class_Name'</CODE> or <CODE>'*Class_Name'</CODE>)</A></STRONG><BR>
- <DD>
- The element's value must be a reference blessed to the named
- class or to one of its subclasses. The element is initialized to
- the result of calling the <CODE>new</CODE> constructor of the named class.
- <P>The accessor's argument, if any, is assigned to the element. The
- accessor will <CODE>croak</CODE> if this is not an appropriate object
- reference.</P>
- <P>If the element type does not start with a <CODE>'*'</CODE>, the accessor
- returns the element value (after assignment). If the element type
- starts with a <CODE>'*'</CODE>, a reference to the element itself is returned.</P>
- <P></P></DL>
- <P>
- <H2><A NAME="initializing with new">Initializing with <CODE>new</CODE></A></H2>
- <P><CODE>struct</CODE> always creates a constructor called <CODE>new</CODE>. That constructor
- may take a list of initializers for the various elements of the new
- struct.</P>
- <P>Each initializer is a pair of values: <EM>element name</EM><CODE> => </CODE><EM>value</EM>.
- The initializer value for a scalar element is just a scalar value. The
- initializer for an array element is an array reference. The initializer
- for a hash is a hash reference.</P>
- <P>The initializer for a class element is also a hash reference, and the
- contents of that hash are passed to the element's own constructor.</P>
- <P>See Example 3 below for an example of initialization.</P>
- <P>
- <HR>
- <H1><A NAME="examples">EXAMPLES</A></H1>
- <DL>
- <DT><STRONG><A NAME="item_Example_1">Example 1</A></STRONG><BR>
- <DD>
- Giving a struct element a class type that is also a struct is how
- structs are nested. Here, <CODE>timeval</CODE> represents a time (seconds and
- microseconds), and <CODE>rusage</CODE> has two elements, each of which is of
- type <CODE>timeval</CODE>.
- <PRE>
- use Class::Struct;</PRE>
- <PRE>
- struct( rusage => {
- ru_utime => timeval, # seconds
- ru_stime => timeval, # microseconds
- });</PRE>
- <PRE>
- struct( timeval => [
- tv_secs => '$',
- tv_usecs => '$',
- ]);</PRE>
- <PRE>
- # create an object:
- my $t = new rusage;</PRE>
- <PRE>
- # $t->ru_utime and $t->ru_stime are objects of type timeval.
- # set $t->ru_utime to 100.0 sec and $t->ru_stime to 5.0 sec.
- $t->ru_utime->tv_secs(100);
- $t->ru_utime->tv_usecs(0);
- $t->ru_stime->tv_secs(5);
- $t->ru_stime->tv_usecs(0);</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Example_2">Example 2</A></STRONG><BR>
- <DD>
- An accessor function can be redefined in order to provide
- additional checking of values, etc. Here, we want the <CODE>count</CODE>
- element always to be nonnegative, so we redefine the <CODE>count</CODE>
- accessor accordingly.
- <PRE>
- package MyObj;
- use Class::Struct;</PRE>
- <PRE>
- # declare the struct
- struct ( 'MyObj', { count => '$', stuff => '%' } );</PRE>
- <PRE>
- # override the default accessor method for 'count'
- sub count {
- my $self = shift;
- if ( @_ ) {
- die 'count must be nonnegative' if $_[0] < 0;
- $self->{'count'} = shift;
- warn "Too many args to count" if @_;
- }
- return $self->{'count'};
- }</PRE>
- <PRE>
- package main;
- $x = new MyObj;
- print "\$x->count(5) = ", $x->count(5), "\n";
- # prints '$x->count(5) = 5'</PRE>
- <PRE>
- print "\$x->count = ", $x->count, "\n";
- # prints '$x->count = 5'</PRE>
- <PRE>
- print "\$x->count(-5) = ", $x->count(-5), "\n";
- # dies due to negative argument!</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Example_3">Example 3</A></STRONG><BR>
- <DD>
- The constructor of a generated class can be passed a list
- of <EM>element</EM>=><EM>value</EM> 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.
- <P>Note that the initializer for a nested struct is specified
- as an anonymous hash of initializers, which is passed on to the nested
- struct's constructor.</P>
- <PRE>
- use Class::Struct;</PRE>
- <PRE>
- struct Breed =>
- {
- name => '$',
- cross => '$',
- };</PRE>
- <PRE>
- struct Cat =>
- [
- name => '$',
- kittens => '@',
- markings => '%',
- breed => 'Breed',
- ];</PRE>
- <PRE>
- my $cat = Cat->new( name => 'Socks',
- kittens => ['Monica', 'Kenneth'],
- markings => { socks=>1, blaze=>"white" },
- breed => { name=>'short-hair', cross=>1 },
- );</PRE>
- <PRE>
- print "Once a cat called ", $cat->name, "\n";
- print "(which was a ", $cat->breed->name, ")\n";
- print "had two kittens: ", join(' and ', @{$cat->kittens}), "\n";</PRE>
- <P></P></DL>
- <P>
- <HR>
- <H1><A NAME="author and modification history">Author and Modification History</A></H1>
- <P>Modified by Damian Conway, 1999-03-05, v0.58.</P>
- <PRE>
- Added handling of hash-like arg list to class ctor.</PRE>
- <PRE>
- Changed to two-argument blessing in ctor to support
- derivation from created classes.</PRE>
- <PRE>
- Added classname prefixes to keys in hash-based classes
- (refer to "Perl Cookbook", Recipe 13.12 for rationale).</PRE>
- <PRE>
- Corrected behaviour of accessors for '*@' and '*%' struct
- elements. Package now implements documented behaviour when
- returning a reference to an entire hash or array element.
- Previously these were returned as a reference to a reference
- to the element.</PRE>
- <P>Renamed to <CODE>Class::Struct</CODE> and modified by Jim Miner, 1997-04-02.</P>
- <PRE>
- members() function removed.
- Documentation corrected and extended.
- Use of struct() in a subclass prohibited.
- User definition of accessor allowed.
- Treatment of '*' in element types corrected.
- Treatment of classes as element types corrected.
- Class name to struct() made optional.
- Diagnostic checks added.</PRE>
- <P>Originally <CODE>Class::Template</CODE> by Dean Roehrich.</P>
- <PRE>
- # Template.pm --- struct/member template builder
- # 12mar95
- # Dean Roehrich
- #
- # changes/bugs fixed since 28nov94 version:
- # - podified
- # changes/bugs fixed since 21nov94 version:
- # - Fixed examples.
- # changes/bugs fixed since 02sep94 version:
- # - Moved to Class::Template.
- # changes/bugs fixed since 20feb94 version:
- # - Updated to be a more proper module.
- # - Added "use strict".
- # - Bug in build_methods, was using @var when @$var needed.
- # - Now using my() rather than local().
- #
- # Uses perl5 classes to create nested data types.
- # This is offered as one implementation of Tom Christiansen's "structs.pl"
- # idea.</PRE>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Class::Struct - declare struct-like datatypes as Perl classes</P></STRONG>
- </TD></TR>
- </TABLE>
-
- </BODY>
-
- </HTML>
-