############################################################################### # # Package: NaturalDocs::DefineMembers # ############################################################################### # # A custom Perl pragma to define member constants and accessors for use in Natural Docs objects while supporting inheritance. # # Each member will be defined as a numeric constant which should be used as that variable's index into the object arrayref. # They will be assigned sequentially from zero, and take into account any members defined this way in parent classes. Note # that you can *not* use multiple inheritance with this method. # # If a parameter ends in parenthesis, it will be generated as an accessor for the previous member. If it also starts with "Set", # the accessor will accept a single parameter to replace the value with. If it's followed with "duparrayref", it will assume the # parameter is either an arrayref or undef, and if the former, will duplicate it to set the value. # # Example: # # > package MyPackage; # > # > use NaturalDocs::DefineMembers 'VAR_A', 'VarA()', 'SetVarA()', # > 'VAR_B', 'VarB()', # > 'VAR_C', # > 'VAR_D', 'VarD()', 'SetVarD() duparrayref'; # > # > sub SetC #(C) # > { # > my ($self, $c) = @_; # > $self->[VAR_C] = $c; # > }; # ############################################################################### # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure # Natural Docs is licensed under the GPL package NaturalDocs::DefineMembers; sub import #(member, member, ...) { my ($self, @parameters) = @_; my $package = caller(); no strict 'refs'; my $parent = ${$package . '::ISA'}[0]; use strict 'refs'; my $memberConstant = 0; my $lastMemberName; if (defined $parent && $parent->can('END_OF_MEMBERS')) { $memberConstant = $parent->END_OF_MEMBERS(); }; my $code = '{ package ' . $package . ";\n"; foreach my $parameter (@parameters) { if ($parameter =~ /^(.+)\(\) *(duparrayref)?$/i) { my ($functionName, $pragma) = ($1, lc($2)); if ($functionName =~ /^Set/) { if ($pragma eq 'duparrayref') { $code .= 'sub ' . $functionName . ' { if (defined $_[1]) { $_[0]->[' . $lastMemberName . '] = [ @{$_[1]} ]; } else { $_[0]->[' . $lastMemberName . '] = undef; }; };' . "\n"; } else { $code .= 'sub ' . $functionName . ' { $_[0]->[' . $lastMemberName . '] = $_[1]; };' . "\n"; }; } else { $code .= 'sub ' . $functionName . ' { return $_[0]->[' . $lastMemberName . ']; };' . "\n"; }; } else { $code .= 'use constant ' . $parameter . ' => ' . $memberConstant . ";\n"; $memberConstant++; $lastMemberName = $parameter; }; }; $code .= 'use constant END_OF_MEMBERS => ' . $memberConstant . ";\n"; $code .= '};'; eval $code; }; 1;