Class-Struct-FIELDS
view release on metacpan or search on metacpan
&some_other_sub (@_);
}
If you do not declare the user override prior to the "use" statement, a
warning is issued if the warning flag (-w) is set.
Notice that we changed the default sub signature for *ff* from "($;$)"
to "($;$$)". Normally, this might generate a warning if we redefine the
sub, but declaring the sub ahead of time keeps "strict" and "warnings"
happy. You might prefer this construction:
{ package Bob; }
sub Bob::ff ($;$$) {
my Bob $self = shift;
&some_other_sub (@_);
}
use Class::Struct::FIELDS Bob => { ff => '$' };
You might still want the advantages of the the constructed accessor
methods, even with user overrides (for example, checking that an
assigned value is the right type or package). "Class::Struct::FIELDS"
constructs the accessor with a special name, so that you may use it
yourself in the user override. That special name is the regular field
name prepended by a double underscore, "__". You can access these so:
use strict;
use warnings;
sub Bob::ff ($;$); # declare sub so Class::Struct::FIELDS can see
sub Bob::gg ($;$); # declare sub so Class::Struct::FIELDS can see
use Class::Struct::FIELDS Bob => { ff => '$', gg => '$' };
# This example is identical to having no user override.
sub Bob::ff ($;$) {
my Bob $self = shift;
$self->__ff (@_);
}
# This example illustrates a workaround for v5.6.0.
sub Bob::gg ($;$) {
# This silliness is due to a bug in 5.6.0: it thinks you can't
# fiddle with @_ if you've given it a prototype. XXX
my @args = @_;
$args[1] *= 2 if @args == 2 and defined $args[1];
@_ = @args;
goto &Bob::__gg;
}
Private fields
Fields starting with a leading underscore, "_", are private: they are
still valid fields, but "Class::Struct::FIELDS" does not create
subroutines to access them. Instead, you should access them the usual
way for hash members:
$self->{_private_key}; # ok
$self->_private_key; # Compilation error
See the fields manpage for more details.
Extra magic: auto-stringify
If there exists a subroutine named "as_string" at the time you invoke
"struct" (or, equivalently, during the call to "use"), then
"Class::Struct::FIELDS" will glue that into auto-stringification with
"overload" for you.
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::FIELDS;
struct (rusage => {
ru_utime => timeval, # seconds
ru_stime => timeval, # microseconds
});
struct (timeval => {
tv_secs => '$',
tv_usecs => '$',
});
# create an object:
my $t = new rusage;
# $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);
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::FIELDS;
# declare the struct
struct (MyObj => {count => '$', stuff => '%'});
# override the default accessor method for 'count'
sub count {
my MyObj $self = shift;
if (@_) {
die 'count must be nonnegative' if $_[0] < 0;
$self->{count} = shift;
warn "Too many args to count" if @_;
}
( run in 1.923 second using v1.01-cache-2.11-cpan-39bf76dae61 )