1package Class::Std; 2 3use version; $VERSION = qv('0.0.8'); 4use strict; 5use warnings; 6use Carp; 7use Scalar::Util; 8 9use overload; 10 11BEGIN { *ID = \&Scalar::Util::refaddr; } 12 13my (%attribute, %cumulative, %anticumulative, %restricted, %private, %overload); 14 15my @exported_subs = qw( 16 new 17 DESTROY 18 AUTOLOAD 19 _DUMP 20); 21 22my @exported_extension_subs = qw( 23 MODIFY_HASH_ATTRIBUTES 24 MODIFY_CODE_ATTRIBUTES 25); 26 27sub import { 28 my $caller = caller; 29 30 no strict 'refs'; 31 *{ $caller . '::ident' } = \&Scalar::Util::refaddr; 32 for my $sub ( @exported_subs ) { 33 *{ $caller . '::' . $sub } = \&{$sub}; 34 } 35 for my $sub ( @exported_extension_subs ) { 36 my $target = $caller . '::' . $sub; 37 my $real_sub = *{ $target }{CODE} || sub { return @_[2..$#_] }; 38 no warnings 'redefine'; 39 *{ $target } = sub { 40 my ($package, $referent, @unhandled) = @_; 41 for my $handler ($sub, $real_sub) { 42 next if !@unhandled; 43 @unhandled = $handler->($package, $referent, @unhandled); 44 } 45 return @unhandled; 46 }; 47 } 48} 49 50sub _find_sub { 51 my ($package, $sub_ref) = @_; 52 no strict 'refs'; 53 for my $name (keys %{$package.'::'}) { 54 my $candidate = *{$package.'::'.$name}{CODE}; 55 return $name if $candidate && $candidate == $sub_ref; 56 } 57 croak q{Can't make anonymous subroutine cumulative}; 58} 59 60sub _raw_str { 61 my ($pat) = @_; 62 return qr{ ('$pat') | ("$pat") 63 | qq? (?: 64 /($pat)/ | \{($pat)\} | \(($pat)\) | \[($pat)\] | <($pat)> 65 ) 66 }xms; 67} 68 69sub _str { 70 my ($pat) = @_; 71 return qr{ '($pat)' | "($pat)" 72 | qq? (?: 73 /($pat)/ | \{($pat)\} | \(($pat)\) | \[($pat)\] | <($pat)> 74 ) 75 }xms; 76} 77 78sub _extractor_for_pair_named { 79 my ($key, $raw) = @_; 80 81 $key = qr{\Q$key\E}; 82 my $str_key = _str($key); 83 84 my $LDAB = "(?:\x{AB})"; 85 my $RDAB = "(?:\x{BB})"; 86 87 my $STR = $raw ? _raw_str( qr{.*?} ) : _str( qr{.*?} ); 88 my $NUM = qr{ ( [-+]? (?:\d+\.?\d*|\.\d+) (?:[eE]\d+)? ) }xms; 89 90 my $matcher = qr{ :$key< \s* ([^>]*) \s* > 91 | :$key$LDAB \s* ([^$RDAB]*) \s* $RDAB 92 | :$key\( \s* (?:$STR | $NUM ) \s* \) 93 | (?: $key | $str_key ) \s* => \s* (?: $STR | $NUM ) 94 }xms; 95 96 return sub { return $_[0] =~ $matcher ? $+ : undef }; 97} 98 99BEGIN { 100 *_extract_default = _extractor_for_pair_named('default','raw'); 101 *_extract_init_arg = _extractor_for_pair_named('init_arg'); 102 *_extract_get = _extractor_for_pair_named('get'); 103 *_extract_set = _extractor_for_pair_named('set'); 104 *_extract_name = _extractor_for_pair_named('name'); 105} 106 107sub MODIFY_HASH_ATTRIBUTES { 108 my ($package, $referent, @attrs) = @_; 109 for my $attr (@attrs) { 110 next if $attr !~ m/\A ATTRS? \s* (?: \( (.*) \) )? \z/xms; 111 my ($default, $init_arg, $getter, $setter, $name); 112 if (my $config = $1) { 113 $default = _extract_default($config); 114 $name = _extract_name($config); 115 $init_arg = _extract_init_arg($config) || $name; 116 117 if ($getter = _extract_get($config) || $name) { 118 no strict 'refs'; 119 *{$package.'::get_'.$getter} = sub { 120 return $referent->{ID($_[0])}; 121 } 122 } 123 if ($setter = _extract_set($config) || $name) { 124 no strict 'refs'; 125 *{$package.'::set_'.$setter} = sub { 126 croak "Missing new value in call to 'set_$setter' method" 127 unless @_ == 2; 128 my ($self, $new_val) = @_; 129 my $old_val = $referent->{ID($self)}; 130 $referent->{ID($self)} = $new_val; 131 return $old_val; 132 } 133 } 134 } 135 undef $attr; 136 push @{$attribute{$package}}, { 137 ref => $referent, 138 default => $default, 139 init_arg => $init_arg, 140 name => $name || $init_arg || $getter || $setter || '????', 141 }; 142 } 143 return grep {defined} @attrs; 144} 145 146sub _DUMP { 147 my ($self) = @_; 148 my $id = ID($self); 149 150 my %dump; 151 for my $package (keys %attribute) { 152 my $attr_list_ref = $attribute{$package}; 153 for my $attr_ref ( @{$attr_list_ref} ) { 154 next if !exists $attr_ref->{ref}{$id}; 155 $dump{$package}{$attr_ref->{name}} = $attr_ref->{ref}{$id}; 156 } 157 } 158 159 require Data::Dumper; 160 my $dump = Data::Dumper::Dumper(\%dump); 161 $dump =~ s/^.{8}//gxms; 162 return $dump; 163} 164 165my $STD_OVERLOADER 166 = q{ package %%s; 167 use overload ( 168 q{%s} => sub { $_[0]->%%s($_[0]->ident()) }, 169 fallback => 1 170 ); 171 }; 172 173my %OVERLOADER_FOR = ( 174 STRINGIFY => sprintf( $STD_OVERLOADER, q{""} ), 175 NUMERIFY => sprintf( $STD_OVERLOADER, q{0+} ), 176 BOOLIFY => sprintf( $STD_OVERLOADER, q{bool} ), 177 SCALARIFY => sprintf( $STD_OVERLOADER, q{${}} ), 178 ARRAYIFY => sprintf( $STD_OVERLOADER, q{@{}} ), 179 HASHIFY => sprintf( $STD_OVERLOADER, q{%%{}} ), # %% to survive sprintf 180 GLOBIFY => sprintf( $STD_OVERLOADER, q{*{}} ), 181 CODIFY => sprintf( $STD_OVERLOADER, q{&{}} ), 182); 183 184sub MODIFY_CODE_ATTRIBUTES { 185 my ($package, $referent, @attrs) = @_; 186 for my $attr (@attrs) { 187 if ($attr eq 'CUMULATIVE') { 188 push @{$cumulative{$package}}, $referent; 189 } 190 elsif ($attr =~ m/\A CUMULATIVE \s* [(] \s* BASE \s* FIRST \s* [)] \z/xms) { 191 push @{$anticumulative{$package}}, $referent; 192 } 193 elsif ($attr =~ m/\A RESTRICTED \z/xms) { 194 push @{$restricted{$package}}, $referent; 195 } 196 elsif ($attr =~ m/\A PRIVATE \z/xms) { 197 push @{$private{$package}}, $referent; 198 } 199 elsif (exists $OVERLOADER_FOR{$attr}) { 200 push @{$overload{$package}}, [$referent, $attr]; 201 } 202 undef $attr; 203 } 204 return grep {defined} @attrs; 205} 206 207my %_hierarchy_of; 208 209sub _hierarchy_of { 210 my ($class) = @_; 211 212 return @{$_hierarchy_of{$class}} if exists $_hierarchy_of{$class}; 213 214 no strict 'refs'; 215 216 my @hierarchy = $class; 217 my @parents = @{$class.'::ISA'}; 218 219 while (defined (my $parent = shift @parents)) { 220 push @hierarchy, $parent; 221 push @parents, @{$parent.'::ISA'}; 222 } 223 224 my %seen; 225 return @{$_hierarchy_of{$class}} 226 = sort { $a->isa($b) ? -1 227 : $b->isa($a) ? +1 228 : 0 229 } grep !$seen{$_}++, @hierarchy; 230} 231 232my %_reverse_hierarchy_of; 233 234sub _reverse_hierarchy_of { 235 my ($class) = @_; 236 237 return @{$_reverse_hierarchy_of{$class}} 238 if exists $_reverse_hierarchy_of{$class}; 239 240 no strict 'refs'; 241 242 my @hierarchy = $class; 243 my @parents = reverse @{$class.'::ISA'}; 244 245 while (defined (my $parent = shift @parents)) { 246 push @hierarchy, $parent; 247 push @parents, reverse @{$parent.'::ISA'}; 248 } 249 250 my %seen; 251 return @{$_reverse_hierarchy_of{$class}} 252 = reverse sort { $a->isa($b) ? -1 253 : $b->isa($a) ? +1 254 : 0 255 } grep !$seen{$_}++, @hierarchy; 256} 257 258{ 259 no warnings qw( void ); 260 CHECK { initialize() } 261} 262 263sub initialize { 264 # Short-circuit if nothing to do... 265 return if keys(%restricted) + keys(%private) 266 + keys(%cumulative) + keys(%anticumulative) 267 + keys(%overload) 268 == 0; 269 270 my (%cumulative_named, %anticumulative_named); 271 272 # Implement restricted methods (only callable within hierarchy)... 273 for my $package (keys %restricted) { 274 for my $sub_ref (@{$restricted{$package}}) { 275 my $name = _find_sub($package, $sub_ref); 276 no warnings 'redefine'; 277 no strict 'refs'; 278 my $sub_name = $package.'::'.$name; 279 my $original = *{$sub_name}{CODE} 280 or croak "Restricted method ${package}::$name() declared ", 281 'but not defined'; 282 *{$sub_name} = sub { 283 my $caller; 284 my $level = 0; 285 while ($caller = caller($level++)) { 286 last if $caller !~ /^(?: Class::Std | attributes )$/xms; 287 } 288 goto &{$original} if !$caller || $caller->isa($package) 289 || $package->isa($caller); 290 croak "Can't call restricted method $sub_name() from class $caller"; 291 } 292 } 293 } 294 295 # Implement private methods (only callable from class itself)... 296 for my $package (keys %private) { 297 for my $sub_ref (@{$private{$package}}) { 298 my $name = _find_sub($package, $sub_ref); 299 no warnings 'redefine'; 300 no strict 'refs'; 301 my $sub_name = $package.'::'.$name; 302 my $original = *{$sub_name}{CODE} 303 or croak "Private method ${package}::$name() declared ", 304 'but not defined'; 305 *{$sub_name} = sub { 306 my $caller = caller; 307 goto &{$original} if $caller eq $package; 308 croak "Can't call private method $sub_name() from class $caller"; 309 } 310 } 311 } 312 313 for my $package (keys %cumulative) { 314 for my $sub_ref (@{$cumulative{$package}}) { 315 my $name = _find_sub($package, $sub_ref); 316 $cumulative_named{$name}{$package} = $sub_ref; 317 no warnings 'redefine'; 318 no strict 'refs'; 319 *{$package.'::'.$name} = sub { 320 my @args = @_; 321 my $class = ref($_[0]) || $_[0]; 322 my $list_context = wantarray; 323 my (@results, @classes); 324 for my $parent (_hierarchy_of($class)) { 325 my $sub_ref = $cumulative_named{$name}{$parent} or next; 326 ${$parent.'::AUTOLOAD'} = our $AUTOLOAD if $name eq 'AUTOLOAD'; 327 if (!defined $list_context) { 328 $sub_ref->(@args); 329 next; 330 } 331 push @classes, $parent; 332 if ($list_context) { 333 push @results, $sub_ref->(@args); 334 } 335 else { 336 push @results, scalar $sub_ref->(@args); 337 } 338 } 339 return if !defined $list_context; 340 return @results if $list_context; 341 return Class::Std::SCR->new({ 342 values => \@results, 343 classes => \@classes, 344 }); 345 }; 346 } 347 } 348 349 for my $package (keys %anticumulative) { 350 for my $sub_ref (@{$anticumulative{$package}}) { 351 my $name = _find_sub($package, $sub_ref); 352 if ($cumulative_named{$name}) { 353 for my $other_package (keys %{$cumulative_named{$name}}) { 354 next unless $other_package->isa($package) 355 || $package->isa($other_package); 356 print STDERR 357 "Conflicting definitions for cumulative method", 358 " '$name'\n", 359 "(specified as :CUMULATIVE in class '$other_package'\n", 360 " but declared :CUMULATIVE(BASE FIRST) in class ", 361 " '$package')\n"; 362 exit(1); 363 } 364 } 365 $anticumulative_named{$name}{$package} = $sub_ref; 366 no warnings 'redefine'; 367 no strict 'refs'; 368 *{$package.'::'.$name} = sub { 369 my $class = ref($_[0]) || $_[0]; 370 my $list_context = wantarray; 371 my (@results, @classes); 372 for my $parent (_reverse_hierarchy_of($class)) { 373 my $sub_ref = $anticumulative_named{$name}{$parent} or next; 374 if (!defined $list_context) { 375 &{$sub_ref}; 376 next; 377 } 378 push @classes, $parent; 379 if ($list_context) { 380 push @results, &{$sub_ref}; 381 } 382 else { 383 push @results, scalar &{$sub_ref}; 384 } 385 } 386 return if !defined $list_context; 387 return @results if $list_context; 388 return Class::Std::SCR->new({ 389 values => \@results, 390 classes => \@classes, 391 }); 392 }; 393 } 394 } 395 396 for my $package (keys %overload) { 397 foreach my $operation (@{ $overload{$package} }) { 398 my ($referent, $attr) = @$operation; 399 local $^W; 400 my $method = _find_sub($package, $referent); 401 eval sprintf $OVERLOADER_FOR{$attr}, $package, $method; 402 die "Internal error: $@" if $@; 403 } 404 } 405 406 # Remove initialization data to prevent re-initializations... 407 %restricted = (); 408 %private = (); 409 %cumulative = (); 410 %anticumulative = (); 411 %overload = (); 412} 413 414sub new { 415 my ($class, $arg_ref) = @_; 416 417 Class::Std::initialize(); # Ensure run-time (and mod_perl) setup is done 418 419 no strict 'refs'; 420 croak "Can't find class $class" if ! keys %{$class.'::'}; 421 422 croak "Argument to $class->new() must be hash reference" 423 if @_ > 1 && ref $arg_ref ne 'HASH'; 424 425 my $new_obj = bless \my($anon_scalar), $class; 426 my $new_obj_id = ID($new_obj); 427 my (@missing_inits, @suss_keys); 428 429 $arg_ref ||= {}; 430 my %arg_set; 431 BUILD: for my $base_class (_reverse_hierarchy_of($class)) { 432 my $arg_set = $arg_set{$base_class} 433 = { %{$arg_ref}, %{$arg_ref->{$base_class}||{}} }; 434 435 # Apply BUILD() methods... 436 { 437 no warnings 'once'; 438 if (my $build_ref = *{$base_class.'::BUILD'}{CODE}) { 439 $build_ref->($new_obj, $new_obj_id, $arg_set); 440 } 441 } 442 443 # Apply init_arg and default for attributes still undefined... 444 INIT: 445 for my $attr_ref ( @{$attribute{$base_class}} ) { 446 next INIT if defined $attr_ref->{ref}{$new_obj_id}; 447 448 # Get arg from initializer list... 449 if (defined $attr_ref->{init_arg} 450 && exists $arg_set->{$attr_ref->{init_arg}}) { 451 $attr_ref->{ref}{$new_obj_id} = $arg_set->{$attr_ref->{init_arg}}; 452 453 next INIT; 454 } 455 elsif (defined $attr_ref->{default}) { 456 # Or use default value specified... 457 $attr_ref->{ref}{$new_obj_id} = eval $attr_ref->{default}; 458 459 if ($@) { 460 $attr_ref->{ref}{$new_obj_id} = $attr_ref->{default}; 461 } 462 463 next INIT; 464 } 465 466 if (defined $attr_ref->{init_arg}) { 467 # Record missing init_arg... 468 push @missing_inits, 469 "Missing initializer label for $base_class: " 470 . "'$attr_ref->{init_arg}'.\n"; 471 push @suss_keys, keys %{$arg_set}; 472 } 473 } 474 } 475 476 croak @missing_inits, _mislabelled(@suss_keys), 477 'Fatal error in constructor call' 478 if @missing_inits; 479 480 # START methods run after all BUILD methods complete... 481 START: 482 for my $base_class (_reverse_hierarchy_of($class)) { 483 my $arg_set = $arg_set{$base_class}; 484 485 # Apply START() methods... 486 { 487 no warnings 'once'; 488 if (my $init_ref = *{$base_class.'::START'}{CODE}) { 489 $init_ref->($new_obj, $new_obj_id, $arg_set); 490 } 491 } 492 } 493 494 return $new_obj; 495} 496 497sub uniq (@) { 498 my %seen; 499 return grep { $seen{$_}++ } @_; 500} 501 502 503sub _mislabelled { 504 my (@names) = map { qq{'$_'} } uniq @_; 505 506 return q{} if @names == 0; 507 508 my $arglist 509 = @names == 1 ? $names[0] 510 : @names == 2 ? join q{ or }, @names 511 : join(q{, }, @names[0..$#names-1]) . ", or $names[-1]" 512 ; 513 return "(Did you mislabel one of the args you passed: $arglist?)\n"; 514} 515 516sub DESTROY { 517 my ($self) = @_; 518 my $id = ID($self); 519 push @_, $id; 520 521 DEMOLISH: for my $base_class (_hierarchy_of(ref $_[0])) { 522 no strict 'refs'; 523 if (my $demolish_ref = *{$base_class.'::DEMOLISH'}{CODE}) { 524 &{$demolish_ref}; 525 } 526 527 for my $attr_ref ( @{$attribute{$base_class}} ) { 528 delete $attr_ref->{ref}{$id}; 529 } 530 } 531} 532 533sub AUTOLOAD { 534 my ($invocant) = @_; 535 my $invocant_class = ref $invocant || $invocant; 536 my ($package_name, $method_name) = our $AUTOLOAD =~ m/ (.*) :: (.*) /xms; 537 538 my $ident = ID($invocant); 539 if (!defined $ident) { $ident = $invocant } 540 541 for my $parent_class ( _hierarchy_of($invocant_class) ) { 542 no strict 'refs'; 543 if (my $automethod_ref = *{$parent_class.'::AUTOMETHOD'}{CODE}) { 544 local $CALLER::_ = $_; 545 local $_ = $method_name; 546 if (my $method_impl 547 = $automethod_ref->($invocant, $ident, @_[1..$#_])) { 548 goto &$method_impl; 549 } 550 } 551 } 552 553 my $type = ref $invocant ? 'object' : 'class'; 554 croak qq{Can't locate $type method "$method_name" via package "$package_name"}; 555} 556 557{ 558 my $real_can = \&UNIVERSAL::can; 559 no warnings 'redefine', 'once'; 560 *UNIVERSAL::can = sub { 561 my ($invocant, $method_name) = @_; 562 563 if (my $sub_ref = $real_can->(@_)) { 564 return $sub_ref; 565 } 566 567 for my $parent_class ( _hierarchy_of(ref $invocant || $invocant) ) { 568 no strict 'refs'; 569 if (my $automethod_ref = *{$parent_class.'::AUTOMETHOD'}{CODE}) { 570 local $CALLER::_ = $_; 571 local $_ = $method_name; 572 if (my $method_impl = $automethod_ref->(@_)) { 573 return sub { my $inv = shift; $inv->$method_name(@_) } 574 } 575 } 576 } 577 578 return; 579 }; 580} 581 582package Class::Std::SCR; 583use base qw( Class::Std ); 584 585BEGIN { *ID = \&Scalar::Util::refaddr; } 586 587my %values_of : ATTR( :init_arg<values> ); 588my %classes_of : ATTR( :init_arg<classes> ); 589 590sub new { 591 my ($class, $opt_ref) = @_; 592 my $new_obj = bless \do{my $scalar}, $class; 593 my $new_obj_id = ID($new_obj); 594 $values_of{$new_obj_id} = $opt_ref->{values}; 595 $classes_of{$new_obj_id} = $opt_ref->{classes}; 596 return $new_obj; 597} 598 599use overload ( 600 q{""} => sub { return join q{}, grep { defined $_ } @{$values_of{ID($_[0])}}; }, 601 q{0+} => sub { return scalar @{$values_of{ID($_[0])}}; }, 602 q{@{}} => sub { return $values_of{ID($_[0])}; }, 603 q{%{}} => sub { 604 my ($self) = @_; 605 my %hash; 606 @hash{@{$classes_of{ID($self)}}} = @{$values_of{ID($self)}}; 607 return \%hash; 608 }, 609 fallback => 1, 610); 611 6121; # Magic true value required at end of module 613__END__ 614 615=head1 NAME 616 617Class::Std - Support for creating standard "inside-out" classes 618 619 620=head1 VERSION 621 622This document describes Class::Std version 0.0.8 623 624 625=head1 SYNOPSIS 626 627 package MyClass; 628 use Class::Std; 629 630 # Create storage for object attributes... 631 my %name : ATTR; 632 my %rank : ATTR; 633 my %snum : ATTR; 634 635 my %public_data : ATTR; 636 637 # Handle initialization of objects of this class... 638 sub BUILD { 639 my ($self, $obj_ID, $arg_ref) = @_; 640 641 $name{$obj_ID} = check_name( $arg_ref->{name} ); 642 $rank{$obj_ID} = check_rank( $arg_ref->{rank} ); 643 $snum{$obj_ID} = _gen_uniq_serial_num(); 644 } 645 646 # Handle cleanup of objects of this class... 647 sub DEMOLISH { 648 my ($self, $obj_ID) = @_; 649 650 _recycle_serial_num( $snum{$obj_ID} ); 651 } 652 653 # Handle unknown method calls... 654 sub AUTOMETHOD { 655 my ($self, $obj_ID, @other_args) = @_; 656 657 # Return any public data... 658 if ( m/\A get_(.*)/ ) { # Method name passed in $_ 659 my $get_what = $1; 660 return sub { 661 return $public_data{$obj_ID}{$get_what}; 662 } 663 } 664 665 warn "Can't call $method_name on ", ref $self, " object"; 666 667 return; # The call is declined by not returning a sub ref 668 } 669 670 671=head1 DESCRIPTION 672 673This module provides tools that help to implement the "inside out object" 674class structure in a convenient and standard way. 675 676I<Portions of the following code and documentation from "Perl Best Practices" 677copyright (c) 2005 by O'Reilly Media, Inc. and reprinted with permission.> 678 679=head2 Introduction 680 681Most programmers who use Perl's object-oriented features construct their 682objects by blessing a hash. But, in doing so, they undermine the 683robustness of the OO approach. Hash-based objects are unencapsulated: 684their entries are open for the world to access and modify. 685 686Objects without effective encapsulation are vulnerable. Instead of 687politely respecting their public interface, some clever client coder 688inevitably will realize that it's marginally faster to interact directly 689with the underlying implementation, pulling out attribute values 690directly from the hash of an object: 691 692 for my $file ( get_file_objs() ) { 693 print $file->{name}, "\n"; 694 } 695 696instead of using the official interface: 697 698 for my $file ( get_file_objs() ) { 699 print $file->get_name(), "\n"; 700 } 701 702From the moment someone does that, your class is no longer cleanly 703decoupled from the code that uses it. You can't be sure that any bugs in 704your class are actually caused by the internals of your class, and not 705the result of some kind of monkeying by the client code. And to make 706matters worse, now you can't ever change those internals without the 707risk of breaking some other part of the system. 708 709There is a simple, convenient, and utterly secure way to prevent client 710code from accessing the internals of the objects you provide. Happily, 711that approach also guards against misspelling attribute names (a common 712error in hash-based classes), as well as being just as fast as--and 713often more memory-efficient than--ordinary hash-based objects. 714 715That approach is referred to by various names--flyweight scalars, 716warehoused attributes, inverted indices--but most commonly it's known 717as: inside-out objects. Consider the following class definitions: 718 719 package File::Hierarchy; 720 { 721 # Objects of this class have the following attributes... 722 my %root_of; # The root directory of the file hierarchy 723 my %files_of; # Array storing object for each file in root directory 724 725 # Constructor takes path of file system root directory... 726 sub new { 727 my ($class, $root) = @_; 728 729 # Bless a scalar to instantiate the new object... 730 my $new_object = bless \do{my $anon_scalar}, $class; 731 732 # Initialize the object's "root" attribute... 733 $root_of{ident $new_object} = $root; 734 735 return $new_object; 736 } 737 738 # Retrieve files from root directory... 739 sub get_files { 740 my ($self) = @_; 741 742 # Load up the "files" attribute, if necessary... 743 if (!exists $files_of{ident $self}) { 744 $files_of{ident $self} 745 = File::System->list_files($root_of{ident $self}); 746 } 747 748 # Flatten the "files" attribute's array to produce a file list... 749 return @{ $files_of{ident $self} }; 750 } 751 } 752 753 package File::Hierarchy::File; 754 { 755 # Objects of this class have the following attributes... 756 my %name_of; # the name of the file 757 758 # Constructor takes name of file... 759 sub new { 760 my ($class, $filename) = @_; 761 762 # Bless a scalar to instantiate the new object... 763 my $new_object = bless \do{my $anon_scalar}, $class; 764 765 # Initialize the object's "name" attribute... 766 $name_of{ident $new_object} = $filename; 767 768 return $new_object; 769 } 770 771 # Retrieve name of file... 772 sub get_name { 773 my ($self) = @_; 774 775 return $name_of{ident $self}; 776 } 777 } 778 779Unlike a hash-based class, each of these inside-out class is specified 780inside a surrounding code block: 781 782 package File::Hierarchy; 783 { 784 # [Class specification here] 785 } 786 787 package File::Hierarchy::File; 788 { 789 # [Class specification here] 790 } 791 792That block is vital, because it creates a limited scope, to which any 793lexical variables that are declared as part of the class will 794automatically be restricted. 795 796The next difference between the two versions of the classes is that each 797attribute of I<all> the objects in the class is now stored in a separate 798single hash: 799 800 # Objects of this class have the following attributes... 801 802 my %root_of; # The root directory of the file hierarchy 803 my %files_of; # Array storing object for each file in root directory 804 805This is 90 degrees to the usual hash-based approach. In hash-based 806classes, all the attributes of one object are stored in a single hash; 807in inside-out classes, one attribute from all objects is stored in a 808single hash. Diagrammatically: 809 810 Hash-based: 811 Attribute 1 Attribute 2 812 813 Object A { attr1 => $valA1, attr2 => $val2 } 814 815 Object B { attr1 => $valB1, attr2 => $val2 } 816 817 Object C { attr1 => $valB1, attr2 => $val2 } 818 819 820 821 Inside-out: 822 Object A Object B Object C 823 824 Attribute 1 { 19817 => $valA1, 172616 => $valB1, 67142 => $valC1 } 825 826 Attribute 2 { 19817 => $valA2, 172616 => $valB2, 67142 => $valC3 } 827 828 Attribute 3 { 19817 => $valA3, 172616 => $valB3, 67142 => $valC3 } 829 830So the attributes belonging to each object are distributed across a set of 831predeclared hashes, rather than being squashed together into one anonymous 832hash. 833 834This is a significant improvement. By telling Perl what attributes you 835expect to use, you enable the compiler to check--via use strict--that 836you do indeed use only those attributes. 837 838That's because of the third difference in the two approaches. Each 839attribute of a hash-based object is stored in an entry in the object's 840hash: C<< $self->{name} >>. In other words, the name of a hash-based attribute 841is symbolic: specified by the string value of a hash key. In contrast, 842each attribute of an inside-out object is stored in an entry of the 843attribute's hash: C<$name_of{ident $self}>. So the name of an inside-out 844attribute isn't symbolic; it's a hard-coded variable name. 845 846With hash-based objects, if an attribute name is accidentally misspelled 847in some method: 848 849 sub set_name { 850 my ($self, $new_name) = @_; 851 852 $self->{naem} = $new_name; # Oops! 853 854 return; 855 } 856 857then the C<$self> hash will obligingly--and silently!--create a new entry 858in the hash, with the key C<'naem'>, then assign the new name to it. But 859since every other method in the class correctly refers to the attribute 860as C<$self->{name}>, assigning the new value to C<$self->{naem}> effectively 861makes that assigned value "vanish". 862 863With inside-out objects, however, an object's "name" attribute is stored 864as an entry in the class's lexical C<%name_of> hash. If the attribute name 865is misspelled then you're attempting to refer to an entirely different 866hash: C<%naem_of>. Like so: 867 868 sub set_name { 869 my ($self, $new_name) = @_; 870 871 $naem_of{ident $self} = $new_name; # Kaboom! 872 873 return; 874 } 875 876But, since there's no such hash declared in the scope, use strict will 877complain (with extreme prejudice): 878 879 Global symbol "%naem_of" requires explicit package name at Hierarchy.pm line 86 880 881Not only is that consistency check now automatic, it's also performed at 882compile time. 883 884The next difference is even more important and beneficial. Instead of 885blessing an empty anonymous hash as the new object: 886 887 my $new_object = bless {}, $class; 888 889the inside-out constructor blesses an empty anonymous scalar: 890 891 my $new_object = bless \do{my $anon_scalar}, $class; 892 893That odd-looking C<\do{my $anon_scalar}> construct is needed because 894there's no built-in syntax in Perl for creating a reference to an 895anonymous scalar; you have to roll-your-own. 896 897The anonymous scalar is immediately passed to bless, which anoints it as 898an object of the appropriate class. The resulting object reference is 899then stored in C<$new_object>. 900 901Once the object exists, it's used to create a unique key 902(C<ident $new_object>) under which each attribute that belongs to the 903object will be stored (e.g. C<$root_of{ident $new_object}> or 904C<$name_of{ident $self}>). The C<ident()> utility that produces this unique 905key is provided by the Class::Std module and is identical in effect to 906the C<refaddr()> function in the standard Scalar::Util module. 907 908To recap: every inside-out object is a blessed scalar, and 909has--intrinsic to it--a unique identifying integer. That integer can be 910obtained from the object reference itself, and then used to access a 911unique entry for the object in each of the class's attribute hashes. 912 913This means that every inside-out object is nothing more than an 914unintialized scalar. When your constructor passes a new inside-out 915object back to the client code, all that comes back is an empty scalar, 916which makes it impossible for that client code to gain direct access to 917the object's internal state. 918 919Of the several popular methods of reliably enforcing encapsulation in 920Perl, inside-out objects are also by far the cheapest. The run-time 921performance of inside-out classes is effectively identical to that of 922regular hash-based classes. In particular, in both schemes, every 923attribute access requires only a single hash look-up. The only 924appreciable difference in speed occurs when an inside-out object is 925destroyed. 926 927Hash-based classes usually don't even have destructors. When the 928object's reference count decrements to zero, the hash is automatically 929reclaimed, and any data structures stored inside the hash are likewise 930cleaned up. This works so well that many OO Perl programmers find they 931never need to write a C<DESTROY()> method; Perl's built-in garbage 932collection handles everything just fine. In fact, the only time a 933destructor is needed is when objects have to manage resources outside 934that are not actually located inside the object, resources that need to 935be separately deallocated. 936 937But the whole point of an inside-out object is that its attributes are 938stored in allocated hashes that are not actually located inside the 939object. That's precisely how it achieves secure encapsulation: by not 940sending the attributes out into the client code. 941 942Unfortunately, that means when an inside-out object is eventually 943garbage collected, the only storage that is reclaimed is the single 944blessed scalar implementing the object. The object's attributes are 945entirely unaffected by the object's deallocation, because the attributes 946are not inside the object, nor are they referred to by it in any way. 947 948Instead, the attributes are referred to by the various attribute hashes 949in which they're stored. And since those hashes will continue to exist 950until the end of the program, the defunct object's orphaned attributes 951will likewise continue to exist, safely nestled inside their respective 952hashes, but now untended by any object. In other words, when an inside- 953out object dies, its associated attribute hashes leak memory. 954 955The solution is simple. Every inside-out class has to provide a 956destructor that "manually" cleans up the attributes of the object being 957destructed: 958 959 package File::Hierarchy; 960 { 961 # Objects of this class have the following attributes... 962 my %root_of; # The root directory of the file hierarchy 963 my %files_of; # Array storing object for each file in root directory 964 965 # Constructor takes path of file system root directory... 966 sub new { 967 # As before 968 } 969 970 # Retrieve files from root directory... 971 sub get_files { 972 # As before 973 } 974 975 # Clean up attributes when object is destroyed... 976 sub DESTROY { 977 my ($self) = @_; 978 979 delete $root_of{ident $self}; 980 delete $files_of{ident $self}; 981 } 982 } 983 984The obligation to provide a destructor like this in every inside-out 985class can be mildly irritating, but it is still a very small price to 986pay for the considerable benefits that the inside-out approach otherwise 987provides for free. And the irritation can easily be eliminated by using 988the appropriate class construction tools. See below. 989 990=head2 Automating Inside-Out Classes 991 992Perhaps the most annoying part about building classes in Perl (no matter how 993the objects are implemented) is that the basic structure of every class is 994more or less identical. For example, the implementation of the 995C<File::Hierarchy::File> class used in C<File::Hierarchy> looks like this: 996 997 package File::Hierarchy::File; 998 { 999 # Objects of this class have the following attributes... 1000 my %name_of; # the name of the file 1001 1002 # Constructor takes name of file... 1003 sub new { 1004 my ($class, $filename) = @_; 1005 1006 # Bless a scalar to instantiate the new object... 1007 my $new_object = bless \do{my $anon_scalar}, $class; 1008 1009 # Initialize the object's "name" attribute... 1010 $name_of{ident $new_object} = $filename; 1011 1012 return $new_object; 1013 } 1014 1015 # Retrieve name of file... 1016 sub get_name { 1017 my ($self) = @_; 1018 1019 return $name_of{ident $self}; 1020 } 1021 1022 # Clean up attributes when object is destroyed... 1023 sub DESTROY { 1024 my ($self) = @_; 1025 1026 delete $name_of{ident $self}; 1027 } 1028 } 1029 1030Apart from the actual names of the attributes, and their accessor methods, 1031that's exactly the same structure, and even the same code, as in the 1032C<File::Hierarchy> class. 1033 1034Indeed, the standard infrastructure of I<every> inside-out class looks 1035exactly the same. So it makes sense not to have to rewrite that standard 1036infrastructure code in every separate class. 1037 1038That's precisely what is module does: it implements the necessary 1039infrastructure for inside-out objects. See below. 1040 1041 1042=head1 INTERFACE 1043 1044=head2 Exported subroutines 1045 1046=over 1047 1048=item C<ident()> 1049 1050Class::Std always exports a subroutine called C<ident()>. This subroutine 1051returns a unique integer ID for any object passed to it. 1052 1053=back 1054 1055=head2 Non-exported subroutines 1056 1057=over 1058 1059=item C<Class::Std::initialize()> 1060 1061This subroutine sets up all the infrastructure to support your Class::Std- 1062based class. It is usually called automatically in a C<CHECK> block, or 1063(if the C<CHECK> block fails to run -- under C<mod_perl> or C<require 1064Class::Std> or C<eval "...">) during the first constructor call made to 1065a Class::Std-based object. 1066 1067In rare circumstances, you may need to call this subroutine directly yourself. 1068Specifically, if you set up cumulative, restricted, private, or automethodical 1069class methods (see below), and call any of them before you create any objects, 1070then you need to call C<Class::Std::initialize()> first. 1071 1072=back 1073 1074=head2 Methods created automatically 1075 1076The following subroutines are installed in any class that uses the 1077Class::Std module. 1078 1079=over 1080 1081=item C<new()> 1082 1083Every class that loads the Class::Std module automatically has a C<new()> 1084constructor, which returns an inside-out object (i.e. a blessed scalar). 1085 1086 $obj = MyClass->new(); 1087 1088The constructor can be passed a single argument to initialize the 1089object. This argument must be a hash reference. 1090 1091 $obj = MyClass->new({ name=>'Foo', location=>'bar' }); 1092 1093See the subsequent descriptions of the C<BUILD()> and C<START()> methods 1094and C<:ATTR()> trait, for an explanation of how the contents of this 1095optional hash can be used to initialize the object. 1096 1097It is almost always an error to implement your own C<new()> in any class 1098that uses Class::Std. You almost certainly want to write a C<BUILD()> or 1099C<START()> method instead. See below. 1100 1101 1102=item C<DESTROY()> 1103 1104Every class that loads the Class::Std module automatically has a C<DESTROY()> 1105destructor, which automatically cleans up any attributes declared with the 1106C<:ATTR()> trait (see below). 1107 1108It is almost always an error to write your own C<DESTROY()> in any class that 1109uses Class::Std. You almost certainly want to write your own C<DEMOLISH()> 1110instead. See below. 1111 1112 1113=item C<AUTOLOAD()> 1114 1115Every class that loads the Class::Std module automatically has an 1116C<AUTOLOAD()> method, which implements the C<AUTOMETHOD()> mechanism 1117described below. 1118 1119It is almost always an error to write your own C<AUTOLOAD()> in any class that 1120uses Class::Std. You almost certainly want to write your own C<AUTOMETHOD()> 1121instead. 1122 1123=item C<_DUMP()> 1124 1125This method returns a string that represents the internal state (i.e. the 1126attribute values) of the object on which it's called. Only those attributes 1127which are marked with an C<:ATTR> (see below) are reported. Attribute names 1128are reported only if they can be ascertained from an C<:init_arg>, C<:get>, or 1129C<:set> option within the C<:ATTR()>. 1130 1131Note that C<_DUMP()> is not designed to support full 1132serialization/deserialization of objects. See the separate 1133Class::Std::Storable module (on CPAN) for that. 1134 1135=back 1136 1137 1138=head2 Methods that can be supplied by the developer 1139 1140The following subroutines can be specified as standard methods of a 1141Class::Std class. 1142 1143=over 1144 1145=item C<BUILD()> 1146 1147When the C<new()> constructor of a Class::Std class is called, it 1148automatically calls every method named C<BUILD()> in I<all> the classes 1149in the new object's hierarchy. That is, when the constructor is called, 1150it walks the class's inheritance tree (from base classes downwards) and 1151calls every C<BUILD()> method it finds along the way. 1152 1153This means that, to initialize any class, you merely need to provide a 1154C<BUILD()> method for that class. You don't have to worry about ensuring 1155that any ancestral C<BUILD()> methods also get called; the constructor 1156will take care of that. 1157 1158Each C<BUILD()> method is called with three arguments: the invocant object, 1159the identifier number of that object, and a reference to (a customized version 1160of) the hash of arguments that was originally passed to the constructor: 1161 1162 sub BUILD { 1163 my ($self, $ident, $args_ref) = @_; 1164 ... 1165 } 1166 1167The argument hash is a "customized version" because the module 1168automatically does some fancy footwork to ensure that the arguments are 1169the ones appropriate to the class itself. That's because there's a 1170potential for collisions when Class::Std classes are used in a 1171hierarchy. 1172 1173One of the great advantages of using inside-out classes instead of hash-based 1174classes is that an inside-out base class and an inside-out derived 1175class can then each have an attribute of exactly the same name, which 1176are stored in separate lexical hashes in separate scopes. In a hash-based 1177object that's impossible, because the single hash can't have two 1178attributes with the same key. 1179 1180But that very advantage also presents something of a problem when 1181constructor arguments are themselves passed by hash. If two or more 1182classes in the name hierarchy do happen to have attributes of the same 1183name, the constructor will need two or more initializers with the name 1184key. Which a single hash can't provide. 1185 1186The solution is to allow initializer values to be partitioned into 1187distinct sets, each uniquely named, and which are then passed to the 1188appropriate base class. The easiest way to accomplish that is to pass 1189in a hash of hashes, where each top level key is the name of one of 1190the base classes, and the corresponding value is a hash of 1191initializers specifically for that base class. 1192 1193For example: 1194 1195 package Client; 1196 use Class::Std::Utils; 1197 { 1198 my %client_num_of :ATTR; # Every client has a basic ID number 1199 my %name_of :ATTR; 1200 1201 sub BUILD { 1202 my ($self, $ident, $arg_ref) = @_; 1203 1204 $client_num_of{$ident} = $arg_ref->{'Client'}{client_num}; 1205 $name_of{$ident} = $arg_ref->{'Client'}{client_name}; 1206 } 1207 } 1208 1209 package Client::Corporate; 1210 use base qw( Client ); 1211 use Class::Std::Utils; 1212 { 1213 my %client_num_of; # Corporate clients have an additional ID number 1214 my %corporation_of; 1215 my %position_of; 1216 1217 sub BUILD { 1218 my ($self, $ident, $arg_ref) = @_; 1219 1220 $client_num_of{$ident} 1221 = $arg_ref->{'Client::Corporate'}{client_num}; 1222 $corporation_of{$ident} 1223 = $arg_ref->{'Client::Corporate'}{corp_name}; 1224 $position_of{$ident} 1225 = $arg_ref->{'Client::Corporate'}{position}; 1226 } 1227 } 1228 1229 # and later... 1230 1231 my $new_client 1232 = Client::Corporate->new( { 1233 'Client' => { 1234 client_num => '124C1', 1235 client_name => 'Humperdinck', 1236 }, 1237 'Client::Corporate' => { 1238 client_num => 'F_1692', 1239 corp_name => 'Florin', 1240 position => 'CEO', 1241 }, 1242 }); 1243 1244Now each class's C<BUILD()> method picks out only the initializer sub-hash 1245whose key is that class's own name. Since every class name is 1246different, the top-level keys of this multi-level initializer hash are 1247guaranteed to be unique. And since no single class can have two 1248identically named attributes, the keys of each second-level hash will be 1249unique as well. If two classes in the hierarchy both need an initializer 1250of the same name (e.g. 'client_num'), those two hash entries will now be 1251in separate sub-hashes, so they will never clash. 1252 1253Class::Std provides an even more sophisticated variation on this 1254functionality, which is generally much more convenient for the users of 1255classes. Classes that use Class::Std infrastructure allow both general 1256and class-specific initializers in the initialization hash. Clients only 1257need to specify classes for those initializers whose names actually are 1258ambiguous. Any other arguments can just be passed directly in the 1259top-level hash: 1260 1261 my $new_client 1262 = Client::Corporate->new( { 1263 client_name => 'Humperdinck', 1264 corp_name => 'Florin', 1265 position => 'CEO', 1266 1267 'Client' => { client_num => '124C1' }, 1268 'Client::Corporate' => { client_num => 'F_1692' }, 1269 }); 1270 1271Class::Std also makes it easy for each class's C<BUILD()> to access 1272these class-specific initializer values. Before each C<BUILD()> is 1273invoked, the nested hash whose key is the same as the class name is 1274flattened back into the initializer hash itself. That is, C<Client::BUILD()> 1275is passed the hash: 1276 1277 { 1278 client_name => 'Humperdinck', 1279 corp_name => 'Florin', 1280 position => 'CEO', 1281 client_num => '124C1', # Flattened from 'Client' nested subhash 1282 1283 'Client' => { client_num => '124C1' }, 1284 'Client::Corporate' => { client_num => 'F_1692' }, 1285 } 1286 1287whereas C<Client::Corporate::BUILD()> is passed the hash: 1288 1289 { 1290 client_name => 'Humperdinck', 1291 corp_name => 'Florin', 1292 position => 'CEO', 1293 client_num => 'F_1692', # Flattened from 'Client::Corporate' subhash 1294 1295 'Client' => { client_num => '124C1' }, 1296 'Client::Corporate' => { client_num => 'F_1692' }, 1297 } 1298 1299This means that the C<BUILD()> method for each class can just assume that the 1300correct class-specific initializer values will available at the top level of 1301the hash. For example: 1302 1303 sub Client::BUILD { 1304 my ($self, $ident, $arg_ref) = @_; 1305 1306 $client_num_of{$ident} = $arg_ref->{client_num}; # '124C1' 1307 $name_of{$ident} = $arg_ref->{client_name}; 1308 } 1309 1310 sub Client::Corporate::BUILD { 1311 my ($self, $ident, $arg_ref) = @_; 1312 1313 $client_num_of{$ident} = $arg_ref->{client_num}; # 'F_1692' 1314 $corporation_of{$ident} = $arg_ref->{corp_name}; 1315 $position_of{$ident} = $arg_ref->{position}; 1316 } 1317 1318Both classes use the C<< $arg_ref->{client_num} >> initializer value, but 1319Class::Std automatically arranges for that value to be the right one for each 1320class. 1321 1322Also see the C<:ATTR()> marker (described below) for a simpler way of 1323initializing attributes. 1324 1325 1326=item C<START()> 1327 1328Once all the C<BUILD()> methods of a class have been called and any 1329initialization values or defaults have been subsequently applied to 1330uninitialized attributes, Class::Std arranges for any C<START()> methods 1331in the class's hierarchy to be called befre the constructor finishes. 1332That is, after the build and default initialization processes are 1333complete, the constructor walks down the class's inheritance tree a 1334second time and calls every C<START()> method it finds along the way. 1335 1336As with C<BUILD()>, each C<START()> method is called with three arguments: 1337the invocant object, the identifier number of that object, and a 1338reference to (a customized version of) the hash of arguments that was 1339originally passed to the constructor. 1340 1341The main difference between a C<BUILD()> method and a C<START()> method 1342is that a C<BUILD()> method runs before any attribute of the class is 1343auto-initialized or default-initialized, whereas a C<START()> method 1344runs after all the attributes of the class (including attributes in derived 1345classes) have been initialized in some way. So if you want to pre-empt 1346the initialization process, write a C<BUILD()>. But if you want to do 1347something with the newly created and fully initialized object, write a 1348C<START()> instead. Of course, any class can define I<both> a C<BUILD()> 1349and a C<START()> method, if that happens to be appropriate. 1350 1351 1352=item C<DEMOLISH()> 1353 1354The C<DESTROY()> method that is automatically provided by Class::Std ensures 1355that all the marked attributes (see the C<:ATTR()> marker below) of an object, 1356from all the classes in its inheritance hierarchy, are automatically cleaned 1357up. 1358 1359But, if a class requires other destructor behaviours (e.g. closing 1360filehandles, decrementing allocation counts, etc.) then you may need to 1361specify those explicitly. 1362 1363Whenever an object of a Class::Std class is destroyed, the C<DESTROY()> 1364method supplied by Class::Std automatically calls every method named 1365C<DEMOLISH()> in I<all> the classes in the new object's hierarchy. That 1366is, when the destructor is called, it walks the class's inheritance 1367tree (from derived classes upwards) and calls every C<DEMOLISH()> method it 1368finds along the way. 1369 1370This means that, to clean up any class, you merely need to provide a 1371C<DEMOLISH()> method for that class. You don't have to worry about ensuring 1372that any ancestral C<DEMOLISH()> methods also get called; the destructor 1373will take care of that. 1374 1375Each C<DEMOLISH()> method is called with two arguments: the invocant object, 1376and the identifier number of that object. For example: 1377 1378 sub DEMOLISH { 1379 my ($self, $ident) = @_; 1380 1381 $filehandle_of{$ident}->flush(); 1382 $filehandle_of{$ident}->close(); 1383 } 1384 1385Note that the attributes of the object are cleaned up I<after> the 1386C<DEMOLISH()> method is complete, so they may still be used within 1387that method. 1388 1389 1390=item C<AUTOMETHOD()> 1391 1392There is a significant problem with Perl's built-in C<AUTOLOAD> mechanism: 1393there's no way for a particular C<AUTOLOAD()> to say "no". 1394 1395If two or more classes in a class hierarchy have separate C<AUTOLOAD()> 1396methods, then the one belonging to the left-most-depth-first class in 1397the inheritance tree will always be invoked in preference to any others. 1398If it can't handle a particular call, the call will probably fail 1399catastrophically. This means that derived classes can't always be used 1400in place of base classes (a feature known as "Liskov substitutability") 1401because their inherited autoloading behaviour may be pre-empted by some 1402other unrelated base class on their left in the hierarchy. 1403 1404Class::Std provides a mechanism that solves this problem: the 1405C<AUTOMETHOD> method. An AUTOMETHOD() is expected to return either a 1406handler subroutine that implements the requested method functionality, 1407or else an C<undef> to indicate that it doesn't know how to handle the 1408request. Class::Std then coordinates every C<AUTOMETHOD()> in an object's 1409hierarchy, trying each one in turn until one of them produces a 1410suitable handler. 1411 1412The advantage of this approach is that the first C<AUTOMETHOD()> that's 1413invoked doesn't have to disenfranchise every other C<AUTOMETHOD()> in the 1414hierarchy. If the first one can't handle a particular method call, it 1415simply declines it and Class::Std tries the next candidate instead. 1416 1417Using C<AUTOMETHOD()> instead of C<AUTOLOAD()> makes a class 1418cleaner, more robust, and less disruptive in class hierarchies. 1419For example: 1420 1421 package Phonebook; 1422 use Class::Std; 1423 { 1424 my %entries_of : ATTR; 1425 1426 # Any method call is someone's name: 1427 # so store their phone number or get it... 1428 sub AUTOMETHOD { 1429 my ($self, $ident, $number) = @_; 1430 1431 my $subname = $_; # Requested subroutine name is passed via $_ 1432 1433 # Return failure if not a get_<name> or set_<name> 1434 # (Next AUTOMETHOD() in hierarchy will then be tried instead)... 1435 my ($mode, $name) = $subname =~ m/\A ([gs]et)_(.*) \z/xms 1436 or return; 1437 1438 # If get_<name>, return a handler that just returns the old number... 1439 return sub { return $entries_of{$ident}->{$name}; } 1440 if $mode eq 'get'; 1441 1442 # Otherwise, set_<name>, so return a handler that 1443 # updates the entry and then returns the old number... 1444 return sub { 1445 $entries_of{$ident}->{$name} = $number; 1446 return; 1447 }; 1448 } 1449 } 1450 1451 # and later... 1452 1453 my $lbb = Phonebook->new(); 1454 1455 $lbb->set_Jenny(867_5309); 1456 $lbb->set_Glenn(736_5000); 1457 1458 print $lbb->get_Jenny(), "\n"; 1459 print $lbb->get_Glenn(), "\n"; 1460 1461Note that, unlike C<AUTOLOAD()>, an C<AUTOMETHOD()> is called with both the 1462invocant and the invocant's unique C<ident> number, followed by the actual 1463arguments that were passed to the method. 1464 1465Note too that the name of the method being called is passed as C<$_> 1466instead of C<$AUTOLOAD>, and does I<not> have the class name prepended 1467to it, so you don't have to strip that name off the front like almost 1468everyone almost always does in their C<AUTOLOAD()>. If your C<AUTOMETHOD()> 1469also needs to access the C<$_> from the caller's scope, that's still 1470available as C<$CALLER::_>. 1471 1472=back 1473 1474 1475=head2 Variable traits that can be ascribed 1476 1477The following markers can be added to the definition of any hash 1478used as an attribute storage within a Class::Std class 1479 1480=over 1481 1482=item C<:ATTR()> 1483 1484This marker can be used to indicate that a lexical hash is being used 1485to store one particular attribute of all the objects of the class. That is: 1486 1487 package File::Hierarchy; 1488 { 1489 my %root_of :ATTR; 1490 my %files_of :ATTR; 1491 1492 # etc. 1493 } 1494 1495 package File::Hierarchy::File; 1496 { 1497 my %name_of; :ATTR; 1498 1499 # etc. 1500 } 1501 1502Adding the C<:ATTR> marker to an attribute hash ensures that the corresponding 1503attribute belonging to each object of the class is automatically cleaned up 1504when the object is destroyed. 1505 1506The C<:ATTR> marker can also be given a number of options which automate 1507other attribute-related behaviours. Each of these options consists of a 1508key/value pair, which may be specified in either Perl 5 "fat comma" syntax 1509( C<< S<< key => 'value' >> >> ) or in one of the Perl 6 option syntaxes 1510( C<< S<< :key<value> >> >> or C<< S<< :key('value') >> >> or 1511C<< S<< :key�value� >> >>). 1512 1513Note that, due to a limitation in Perl itself, the complete C<:ATTR> marker, 1514including its options must appear on a single line. 1515interpolate variables into the option values 1516 1517=over 1518 1519=item C<< :ATTR( :init_arg<initializer_key> ) >> 1520 1521This option tells Class::Std which key in the constructor's initializer hash 1522holds the value with which the marked attribute should be initialized. That 1523is, instead of writing: 1524 1525 my %rank_of :ATTR; 1526 1527 sub BUILD { 1528 my ($self, $ident, $arg_ref) = @_; 1529 1530 $rank_of{$ident} = $arg_ref->{rank}; 1531 } 1532 1533you can achieve the same initialization, by having Class::Std I<automatically> 1534pull that entry out of the hash and store it in the right attribute: 1535 1536 my %rank_of :ATTR( :init_arg<rank> ); 1537 1538 # No BUILD() method required 1539 1540 1541=item C<< :ATTR( :default<compile_time_default_value> ) >> 1542 1543If a marked attribute is not initialized (either directly within a 1544C<BUILD()>, or automatically via an C<:init_arg> option), the constructor 1545supplied by Class::Std checks to see if a default value was specified 1546for that attribute. If so, that value is assigned to the attribute. 1547 1548So you could replace: 1549 1550 my %seen_of :ATTR; 1551 1552 sub BUILD { 1553 my ($self, $ident, $arg_ref) = @_; 1554 1555 $seen_of{$ident} = 0; # Not seen yet 1556 } 1557 1558with: 1559 1560 my %seen_of :ATTR( :default(0) ); 1561 1562 # No BUILD() required 1563 1564Note that only literal strings and numbers can be used as default values. A 1565common mistake is to write: 1566 1567 my %seen_of :ATTR( :default($some_variable) ); 1568 1569But variables like this aren't interpolated into C<:ATTR> markers (this is a 1570limitation of Perl, not Class::Std). 1571 1572If your attribute needs something more complex, you will have to default 1573initialize it in a C<START()> method: 1574 1575 my %seen_of :ATTR; 1576 1577 sub START { 1578 my ($self, $id, $args_ref) = @_; 1579 1580 if (!defined $seen_of{$id}) { 1581 $seen_of{$id} = $some_variable; 1582 } 1583 } 1584 1585=item C<< :ATTR( :get<name> ) >> 1586 1587If the C<:get> option is specified, a read accessor is created for the 1588corresponding attribute. The name of the accessor is C<get_> followed by 1589whatever name is specified as the value of the C<:get> option. For example, 1590instead of: 1591 1592 my %current_count_of :ATTR; 1593 1594 sub get_count { 1595 my ($self) = @_; 1596 1597 return $current_count_of{ident($self)}; 1598 } 1599 1600you can just write: 1601 1602 my %count_of :ATTR( :get<count> ); 1603 1604Note that there is no way to prevent Class::Std adding the initial C<get_> to 1605each accessor name it creates. That's what "standard" means. See Chapter 15 1606of I<Perl Best Practices> (O'Reilly, 2005) for a full discussion on why 1607accessors should be named this way. 1608 1609=item C<< :ATTR( :set<name> ) >> 1610 1611If the C<:set> option is specified, a write accessor is created for the 1612corresponding attribute. The name of the accessor is C<set_> followed by 1613whatever name is specified as the value of the C<:set> option. For example, 1614instead of: 1615 1616 my %current_count_of :ATTR; 1617 1618 sub set_count { 1619 my ($self, $new_value) = @_; 1620 1621 croak "Missing new value in call to 'set_count' method" 1622 unless @_ == 2; 1623 1624 $current_count_of{ident($self)} = $new_value; 1625 } 1626 1627you can just write: 1628 1629 my %count_of :ATTR( :set<count> ); 1630 1631Note that there is no way to prevent Class::Std adding the initial 1632C<set_> to each accessor name it creates. Nor is there any way to create 1633a combined "getter/setter" accessor. See Chapter 15 of I<Perl Best 1634Practices> (O'Reilly, 2005) for a full discussion on why accessors 1635should be named and implemented this way. 1636 1637=item C<< :ATTR( :name<name> ) >> 1638 1639Specifying the C<:name> option is merely a convenient 1640shorthand for specifying all three of C<:get>, C<:set>, and C<:init_arg>. 1641 1642=back 1643 1644You can, of course, specify two or more arguments in a single C<:ATTR()> 1645specification: 1646 1647 my %rank_of : ATTR( :init_arg<starting_rank> :get<rank> :set<rank> ); 1648 1649 1650=item C<:ATTRS()> 1651 1652This is just another name for the C<:ATTR> marker (see above). The plural 1653form is convenient when you want to specify a series of attribute hashes in 1654the same statement: 1655 1656 my ( 1657 %name_of, 1658 %rank_of, 1659 %snum_of, 1660 %age_of, 1661 %unit_of, 1662 %assignment_of, 1663 %medals_of, 1664 ) : ATTRS; 1665 1666=back 1667 1668=head2 Method traits that can be ascribed 1669 1670The following markers can be added to the definition of any subroutine 1671used as a method within a Class::Std class 1672 1673=over 1674 1675=item C<:RESTRICTED()> 1676 1677=item C<:PRIVATE()> 1678 1679Occasionally, it is useful to be able to create subroutines that can only be 1680accessed within a class's own hierarchy (that is, by derived classes). And 1681sometimes it's even more useful to be able to create methods that can only be 1682called within a class itself. 1683 1684Typically these types of methods are I<utility> methods: subroutines 1685that provide some internal service for a class, or a class hierarchy. 1686Class::Std supports the creation of these kinds of methods by providing two 1687special markers: C<:RESTRICTED()> and C<:PRIVATE()>. 1688 1689Methods marked C<:RESTRICTED()> are modified at the end of the 1690compilation phase so that they throw an exception when called from 1691outside a class's hierarchy. Methods marked C<:PRIVATE()> are modified 1692so that they throw an exception when called from outside the class in 1693which they're declared. 1694 1695For example: 1696 1697 package DogTag; 1698 use Class::Std; 1699 { 1700 my %ID_of : ATTR; 1701 my %rank_of : ATTR; 1702 1703 my $ID_num = 0; 1704 1705 sub _allocate_next_ID : RESTRICTED { 1706 my ($self) = @_; 1707 $ID_of{ident $self} = $ID_num++; 1708 return; 1709 } 1710 1711 sub _check_rank : PRIVATE { 1712 my ($rank) = @_; 1713 return $rank if $VALID_RANK{$rank}; 1714 croak "Unknown rank ($rank) specified"; 1715 } 1716 1717 sub BUILD { 1718 my ($self, $ident, $arg_ref) = @_; 1719 1720 $self->_allocate_next_ID(); 1721 $rank_of{$ident} = _check_rank($arg_ref->{rank}); 1722 } 1723 } 1724 1725Of course, this code would run exactly the same without the C<:RESTRICTED()> 1726and C<:PRIVATE()> markers, but they ensure that any attempt to call the two 1727subroutines inappropriately: 1728 1729 package main; 1730 1731 my $dogtag = DogTag->new({ rank => 'PFC' }); 1732 1733 $dogtag->_allocate_next_ID(); 1734 1735is suitably punished: 1736 1737 Can't call restricted method DogTag::_allocate_next_ID() from class main 1738 1739 1740=item C<:CUMULATIVE()> 1741 1742One of the most important advantages of using the C<BUILD()> and C<DEMOLISH()> 1743mechanisms supplied by Class::Std is that those methods don't require 1744nested calls to their ancestral methods, via the C<SUPER> pseudo-class. The 1745constructor and destructor provided by Class::Std take care of the 1746necessary redispatching automatically. Each C<BUILD()> method can focus 1747solely on its own responsibilities; it doesn't have to also help 1748orchestrate the cumulative constructor effects across the class 1749hierarchy by remembering to call C<< $self->SUPER::BUILD() >>. 1750 1751Moreover, calls via C<SUPER> can only ever call the method of exactly one 1752ancestral class, which is not sufficient under multiple inheritance. 1753 1754Class::Std provides a different way of creating methods whose effects 1755accumulate through a class hierarchy, in the same way as those of 1756C<BUILD()> and C<DEMOLISH()> do. Specifically, the module allows you to define 1757your own "cumulative methods". 1758 1759An ordinary non-cumulative method hides any method of the same name 1760inherited from any base class, so when a non-cumulative method is 1761called, only the most-derived version of it is ever invoked. In 1762contrast, a cumulative method doesn't hide ancestral methods of the same 1763name; it assimilates them. When a cumulative method is called, the 1764most-derived version of it is invoked, then any parental versions, then any 1765grandparental versions, etc. etc, until every cumulative method of the 1766same name throughout the entire hierarchy has been called. 1767 1768For example, you could define a cumulative C<describe()> method to the various 1769classes in a simple class hierarchy like so: 1770 1771 package Wax::Floor; 1772 use Class::Std; 1773 { 1774 my %name_of :ATTR( init_arg => 'name' ); 1775 my %patent_of :ATTR( init_arg => 'patent' ); 1776 1777 sub describe :CUMULATIVE { 1778 my ($self) = @_; 1779 1780 print "The floor wax $name_of{ident $self} ", 1781 "(patent: $patent_of{ident $self})\n"; 1782 1783 return; 1784 } 1785 } 1786 1787 package Topping::Dessert; 1788 use Class::Std; 1789 { 1790 my %name_of :ATTR( init_arg => 'name' ); 1791 my %flavour_of :ATTR( init_arg => 'flavour' ); 1792 1793 sub describe :CUMULATIVE { 1794 my ($self) = @_; 1795 1796 print "The dessert topping $name_of{ident $self} ", 1797 "with that great $flavour_of{ident $self} taste!\n"; 1798 1799 return; 1800 } 1801 } 1802 1803 package Shimmer; 1804 use base qw( Wax::Floor Topping::Dessert ); 1805 use Class::Std; 1806 { 1807 my %name_of :ATTR( init_arg => 'name' ); 1808 my %patent_of :ATTR( init_arg => 'patent' ); 1809 1810 sub describe :CUMULATIVE { 1811 my ($self) = @_; 1812 1813 print "New $name_of{ident $self} ", 1814 "(patent: $patent_of{ident $self})\n", 1815 "Combining...\n"; 1816 1817 return; 1818 } 1819 } 1820 1821Because the various C<describe()> methods are marked as being cumulative, a 1822subsequent call to: 1823 1824 my $product 1825 = Shimmer->new({ 1826 name => 'Shimmer', 1827 patent => 1562516251, 1828 flavour => 'Vanilla', 1829 }); 1830 1831 $product->describe(); 1832 1833will work its way up through the classes of Shimmer's inheritance tree 1834(in the same order as a destructor call would), calling each C<describe()> 1835method it finds along the way. So the single call to C<describe()> would 1836invoke the corresponding method in each class, producing: 1837 1838 New Shimmer (patent: 1562516251) 1839 Combining... 1840 The floor wax Shimmer (patent: 1562516251) 1841 The dessert topping Shimmer with that great Vanilla taste! 1842 1843Note that the accumulation of C<describe()> methods is hierarchical, and 1844dynamic in nature. That is, each class only sees those cumulative 1845methods that are defined in its own package or in one of its ancestors. 1846So calling the same C<describe()> on a base class object: 1847 1848 my $wax 1849 = Wax::Floor->new({ name=>'Shimmer ', patent=>1562516251 }); 1850 1851 $wax->describe(); 1852 1853only invokes the corresponding cumulative methods from that point on up 1854the hierarchy, and hence only prints: 1855 1856 The floor wax Shimmer (patent: 1562516251) 1857 1858Cumulative methods also accumulate their return values. In a list 1859context, they return a (flattened) list that accumulates the lists 1860returned by each individual method invoked. 1861 1862In a scalar context, a set of cumulative methods returns an object that, 1863in a string context, concatenates individual scalar returns to produce a 1864single string. When used as an array reference that same scalar-context-return 1865object acts like an array of the list context values. When used as a hash 1866reference, the object acts like a hash whose keys are the classnames from the 1867object's hierarchy, and whose corresponding values are the return values of 1868the cumulative method from that class. 1869 1870For example, if the classes each have a cumulative method that returns 1871their list of sales features: 1872 1873 package Wax::Floor; 1874 use Class::Std; 1875 { 1876 sub feature_list :CUMULATIVE { 1877 return ('Long-lasting', 'Non-toxic', 'Polymer-based'); 1878 } 1879 } 1880 1881 package Topping::Dessert; 1882 use Class::Std; 1883 { 1884 sub feature_list :CUMULATIVE { 1885 return ('Low-carb', 'Non-dairy', 'Sugar-free'); 1886 } 1887 } 1888 1889 package Shimmer; 1890 use Class::Std; 1891 use base qw( Wax::Floor Topping::Dessert ); 1892 { 1893 sub feature_list :CUMULATIVE { 1894 return ('Multi-purpose', 'Time-saving', 'Easy-to-use'); 1895 } 1896 } 1897 1898then calling feature_list() in a list context: 1899 1900 my @features = Shimmer->feature_list(); 1901 print "Shimmer is the @features alternative!\n"; 1902 1903would produce a concatenated list of features, which could then be 1904interpolated into a suitable sales-pitch: 1905 1906 Shimmer is the Multi-purpose Time-saving Easy-to-use 1907 Long-lasting Non-toxic Polymer-based Low-carb Non-dairy 1908 Sugar-free alternative! 1909 1910It's also possible to specify a set of cumulative methods that 1911start at the base class(es) of the hierarchy and work downwards, the way 1912BUILD() does. To get that effect, you simply mark each method with 1913:CUMULATIVE(BASE FIRST), instead of just :CUMULATIVE. For example: 1914 1915 package Wax::Floor; 1916 use Class::Std; 1917 { 1918 sub active_ingredients :CUMULATIVE(BASE FIRST) { 1919 return "\tparadichlorobenzene, cyanoacrylate, peanuts\n"; 1920 } 1921 } 1922 1923 package Topping::Dessert; 1924 use Class::Std; 1925 { 1926 sub active_ingredients :CUMULATIVE(BASE FIRST) { 1927 return "\tsodium hypochlorite, isobutyl ketone, ethylene glycol\n"; 1928 } 1929 } 1930 1931 package Shimmer; 1932 use Class::Std; 1933 use base qw( Wax::Floor Topping::Dessert ); 1934 1935 { 1936 sub active_ingredients :CUMULATIVE(BASE FIRST) { 1937 return "\taromatic hydrocarbons, xylene, methyl mercaptan\n"; 1938 } 1939 } 1940 1941So a scalar-context call to active_ingredients(): 1942 1943 my $ingredients = Shimmer->active_ingredients(); 1944 print "May contain trace amounts of:\n$ingredients"; 1945 1946would start in the base classes and work downwards, concatenating base- 1947class ingredients before those of the derived class, to produce: 1948 1949 May contain trace amounts of: 1950 paradichlorobenzene, cyanoacrylate, peanuts 1951 sodium hypochlorite, isobutyl ketone, ethylene glycol 1952 aromatic hydrocarbons, xylene, methyl mercaptan 1953 1954Or, you could treat the return value as a hash: 1955 1956 print Data::Dumper::Dumper \%{$ingredients}; 1957 1958and see which ingredients came from where: 1959 1960 $VAR1 = { 1961 'Shimmer' 1962 => 'aromatic hydrocarbons, xylene, methyl mercaptan', 1963 1964 'Topping::Dessert' 1965 => 'sodium hypochlorite, isobutyl ketone, ethylene glycol', 1966 1967 'Wax::Floor' 1968 => 'Wax: paradichlorobenzene, hydrogen peroxide, cyanoacrylate', 1969 }; 1970 1971Note that you can't specify both C<:CUMULATIVE> and C<:CUMULATIVE(BASE 1972FIRST)> on methods of the same name in the same hierarchy. The resulting 1973set of methods would have no well-defined invocation order, so 1974Class::Std throws a compile-time exception instead. 1975 1976 1977=item C<:STRINGIFY> 1978 1979If you define a method and add the C<:STRINGIFY> marker then that method 1980is used whenever an object of the corresponding class needs to be 1981coerced to a string. In other words, instead of: 1982 1983 # Convert object to a string... 1984 sub as_str { 1985 ... 1986 } 1987 1988 # Convert object to a string automatically in string contexts... 1989 use overload ( 1990 q{""} => 'as_str', 1991 fallback => 1, 1992 ); 1993 1994you can just write: 1995 1996 # Convert object to a string (automatically in string contexts)... 1997 sub as_str : STRINGIFY { 1998 ... 1999 } 2000 2001 2002=item C<:NUMERIFY> 2003 2004If you define a method and add the C<:NUMERIFY> marker then that method 2005is used whenever an object of the corresponding class needs to be 2006coerced to a number. In other words, instead of: 2007 2008 # Convert object to a number... 2009 sub as_num { 2010 ... 2011 } 2012 2013 # Convert object to a string automatically in string contexts... 2014 use overload ( 2015 q{0+} => 'as_num', 2016 fallback => 1, 2017 ); 2018 2019you can just write: 2020 2021 # Convert object to a number (automatically in numeric contexts)... 2022 sub as_num : NUMERIFY { 2023 ... 2024 } 2025 2026 2027=item C<:BOOLIFY> 2028 2029If you define a method and add the C<:BOOLIFY> marker then that method 2030is used whenever an object of the corresponding class needs to be 2031coerced to a boolean value. In other words, instead of: 2032 2033 # Convert object to a boolean... 2034 sub as_bool { 2035 ... 2036 } 2037 2038 # Convert object to a boolean automatically in boolean contexts... 2039 use overload ( 2040 q{bool} => 'as_bool', 2041 fallback => 1, 2042 ); 2043 2044you can just write: 2045 2046 # Convert object to a boolean (automatically in boolean contexts)... 2047 sub as_bool : BOOLIFY { 2048 ... 2049 } 2050 2051 2052=item C<:SCALARIFY> 2053 2054=item C<:ARRAYIFY> 2055 2056=item C<:HASHIFY> 2057 2058=item C<:GLOBIFY> 2059 2060=item C<:CODIFY> 2061 2062If a method is defined with one of these markers, then it is automatically 2063called whenever an object of that class is treated as a reference of the 2064corresponding type. 2065 2066For example, instead of: 2067 2068 sub as_hash { 2069 my ($self) = @_; 2070 2071 return { 2072 age => $age_of{ident $self}, 2073 shoesize => $shoe_of{ident $self}, 2074 }; 2075 } 2076 2077 use overload ( 2078 '%{}' => 'as_hash', 2079 fallback => 1, 2080 ); 2081 2082you can just write: 2083 2084 sub as_hash : HASHIFY { 2085 my ($self) = @_; 2086 2087 return { 2088 age => $age_of{ident $self}, 2089 shoesize => $shoe_of{ident $self}, 2090 }; 2091 } 2092 2093Likewise for methods that allow an object to be treated as a scalar 2094reference (C<:SCALARIFY>), a array reference (C<:ARRAYIFY>), a 2095subroutine reference (C<:CODIFY>), or a typeglob reference 2096(C<:GLOBIFY>). 2097 2098=back 2099 2100 2101=head1 DIAGNOSTICS 2102 2103=over 2104 2105=item Can't find class %s 2106 2107You tried to call the Class::Std::new() constructor on a class 2108that isn't built using Class::Std. Did you forget to write C<use Class::Std> 2109after the package declaration? 2110 2111=item Argument to %s->new() must be hash reference 2112 2113The constructors created by Class::Std require all initializer values 2114to be passed in a hash, but you passed something that wasn't a hash. 2115Put your constructor arguments in a hash. 2116 2117=item Missing initializer label for %s: %s 2118 2119You specified that one or more attributes had initializer values (using the 2120C<init> argument inside the attribute's C<ATTR> marker), but then failed 2121to pass in the corresponding initialization value. Often this happens because 2122the initialization value I<was> passed, but the key specifying the 2123attribute name was misspelled. 2124 2125=item Can't make anonymous subroutine cumulative 2126 2127You attempted to use the C<:CUMULATIVE> marker on an anonymous subroutine. 2128But that marker can only be applied to the named methods of a class. Convert 2129the anonymous subroutine to a named subroutine, or find some other way to 2130make it interoperate with other methods. 2131 2132=item Conflicting definitions for cumulative method: %s 2133 2134You defined a C<:CUMULATIVE> and a C<:CUMULATIVE(BASE FIRST)> method of the 2135same name in two classes within the same hierarchy. Since methods can only be 2136called going strictly up through the hierarchy or going strictly down 2137through the hierarchy, specifying both directions is obviously a mistake. 2138Either rename one of the methods, or decide whether they should accumulate 2139upwards or downwards. 2140 2141=item Missing new value in call to 'set_%s' method 2142 2143You called an attribute setter method without providing a new value 2144for the attribute. Often this happens because you passed an array that 2145happened to be empty. Make sure you pass an actual value. 2146 2147=item Can't locate %s method "%s" via package %s 2148 2149You attempted to call a method on an object but no such method is defined 2150anywhere in the object's class hierarchy. Did you misspell the method name, or 2151perhaps misunderstand which class the object belongs to? 2152 2153=item %s method %s declared but not defined 2154 2155A method was declared with a C<:RESTRICTED> or C<:PRIVATE>, like so: 2156 2157 sub foo :RESTRICTED; 2158 sub bar :PRIVATE; 2159 2160But the actual subroutine was not defined by the end of the compilation 2161phase, when the module needed it so it could be rewritten to restrict or 2162privatize it. 2163 2164 2165=item Can't call restricted method %s from class %s 2166 2167The specified method was declared with a C<:RESTRICTED> marker but 2168subsequently called from outside its class hierarchy. Did you call the 2169wrong method, or the right method from the wrong place? 2170 2171 2172=item Can't call private method %s from class %s 2173 2174The specified method was declared with a C<:PRIVATE> marker but 2175subsequently called from outside its own class. Did you call the wrong 2176method, or the right method from the wrong place? 2177 2178 2179=item Internal error: %s 2180 2181Your code is okay, but it uncovered a bug in the Class::Std module. 2182L<BUGS AND LIMITATIONS> explains how to report the problem. 2183 2184=back 2185 2186 2187=head1 CONFIGURATION AND ENVIRONMENT 2188 2189Class::Std requires no configuration files or environment variables. 2190 2191 2192=head1 DEPENDENCIES 2193 2194Class::Std depends on the following modules: 2195 2196=over 2197 2198=item * 2199 2200version 2201 2202=item * 2203 2204Scalar::Util 2205 2206=item * 2207 2208Data::Dumper 2209 2210=back 2211 2212 2213=head1 INCOMPATIBILITIES 2214 2215Incompatible with the Attribute::Handlers module, since both define 2216meta-attributes named :ATTR. 2217 2218 2219=head1 BUGS AND LIMITATIONS 2220 2221=over 2222 2223=item * 2224 2225Does not handle threading (including C<fork()> under Windows). 2226 2227=item * 2228 2229C<:ATTR> declarations must all be on the same line (due to a limitation in 2230Perl itself). 2231 2232=item * 2233 2234C<:ATTR> declarations cannot include variables, since these are not 2235interpolated into the declaration (a limitation in Perl itself). 2236 2237=back 2238 2239Please report any bugs or feature requests to 2240C<bug-class-std@rt.cpan.org>, or through the web interface at 2241L<http://rt.cpan.org>. 2242 2243 2244=head1 ALTERNATIVES 2245 2246Inside-out objects are gaining in popularity and there are now many other 2247modules that implement frameworks for building inside-out classes. These 2248include: 2249 2250=over 2251 2252=item Object::InsideOut 2253 2254Array-based objects, with support for threading. Many excellent features 2255(especially thread-safety), but slightly less secure than Class::Std, 2256due to non-encapsulation of attribute data addressing. 2257 2258=item Class::InsideOut 2259 2260A minimalist approach to building inside-out classes. 2261 2262=item Lexical::Attributes 2263 2264Uses source filters to provide a near-Perl 6 approach to declaring inside-out 2265classes. 2266 2267=item Class::Std::Storable 2268 2269Adds serialization/deserialization to Class::Std. 2270 2271=back 2272 2273=head1 AUTHOR 2274 2275Damian Conway C<< <DCONWAY@cpan.org> >> 2276 2277 2278=head1 LICENCE AND COPYRIGHT 2279 2280Copyright (c) 2005, Damian Conway C<< <DCONWAY@cpan.org> >>. All rights reserved. 2281 2282Portions of the documentation from "Perl Best Practices" copyright (c) 22832005 by O'Reilly Media, Inc. and reprinted with permission. 2284 2285This module is free software; you can redistribute it and/or 2286modify it under the same terms as Perl itself. 2287 2288 2289=head1 DISCLAIMER OF WARRANTY 2290 2291BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 2292FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 2293OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 2294PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER 2295EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2296WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 2297ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH 2298YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 2299NECESSARY SERVICING, REPAIR, OR CORRECTION. 2300 2301IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 2302WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 2303REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE 2304LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, 2305OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE 2306THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 2307RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 2308FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 2309SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 2310SUCH DAMAGES. 2311