<P>It's common for a class to have a debugging mechanism. For example,
you might want to see when objects are created or destroyed. To do that,
add a debugging variable as a file-scoped lexical. For this, we'll pull
in the standard Carp module to emit our warnings and fatal messages.
That way messages will come out with the caller's filename and
line number instead of our own; if we wanted them to be from our own
perspective, we'd just use <A HREF="../../lib/Pod/perlfunc.html#item_die"><CODE>die()</CODE></A> and <A HREF="../../lib/Pod/perlfunc.html#item_warn"><CODE>warn()</CODE></A> directly instead of <CODE>croak()</CODE>
and <CODE>carp()</CODE> respectively.</P>
<PRE>
use Carp;
my $Debugging = 0;</PRE>
<P>Now add a new class method to access the variable.</P>
<PRE>
sub debug {
my $class = shift;
if (ref $class) { confess "Class method called as object method" }
<P>One of the older ones is Class::Struct. In fact, its syntax and
interface were sketched out long before perl5 even solidified into a
real thing. What it does is provide you a way to ``declare'' a class
as having objects whose fields are of a specific type. The function
that does this is called, not surprisingly enough, struct(). Because
structures or records are not base types in Perl, each time you want to
create a class to provide a record-like data object, you yourself have
to define a <CODE>new()</CODE> method, plus separate data-access methods for each of
that record's fields. You'll quickly become bored with this process.
The Class::Struct::struct() function alleviates this tedium.</P>
<P>Here's a simple example of using it:</P>
<PRE>
use Class::Struct qw(struct);
use Jobbie; # user-defined; see below</PRE>
<PRE>
struct 'Fred' => {
one => '$',
many => '@',
profession => Jobbie, # calls Jobbie->new()
};</PRE>
<PRE>
$ob = Fred->new;
$ob->one("hmmmm");</PRE>
<PRE>
$ob->many(0, "here");
$ob->many(1, "you");
$ob->many(2, "go");
print "Just set: ", $ob->many(2), "\n";</PRE>
<PRE>
$ob->profession->salary(10_000);</PRE>
<P>You can declare types in the struct to be basic Perl types, or
user-defined types (classes). User types will be initialized by calling
that class's <CODE>new()</CODE> method.</P>
<P>Here's a real-world example of using struct generation. Let's say you
wanted to override Perl's idea of <A HREF="../../lib/Pod/perlfunc.html#item_gethostbyname"><CODE>gethostbyname()</CODE></A> and <A HREF="../../lib/Pod/perlfunc.html#item_gethostbyaddr"><CODE>gethostbyaddr()</CODE></A> so
that they would return objects that acted like C structures. We don't
care about high-falutin' OO gunk. All we want is for these objects to
act like structs in the C sense.</P>
<PRE>
use Socket;
use Net::hostent;
$h = gethostbyname("perl.com"); # object return
printf "perl.com's real name is %s, address %s\n",
$h->name, inet_ntoa($h->addr);</PRE>
<P>Here's how to do this using the Class::Struct module.
The crux is going to be this call:</P>
<PRE>
struct 'Net::hostent' => [ # note bracket
name => '$',
aliases => '@',
addrtype => '$',
'length' => '$',
addr_list => '@',
];</PRE>
<P>Which creates object methods of those names and types.
It even creates a <CODE>new()</CODE> method for us.</P>
<P>We could also have implemented our object this way:</P>
<PRE>
struct 'Net::hostent' => { # note brace
name => '$',
aliases => '@',
addrtype => '$',
'length' => '$',
addr_list => '@',
};</PRE>
<P>and then Class::Struct would have used an anonymous hash as the object
type, instead of an anonymous array. The array is faster and smaller,
but the hash works out better if you eventually want to do inheritance.
Since for this struct-like object we aren't planning on inheritance,
this time we'll opt for better speed and size over better flexibility.</P>