home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Stash.pm < prev    next >
Encoding:
Perl POD Document  |  2004-01-30  |  35.0 KB  |  1,041 lines

  1. #============================================================= -*-Perl-*-
  2. #
  3. # Template::Stash
  4. #
  5. # DESCRIPTION
  6. #   Definition of an object class which stores and manages access to 
  7. #   variables for the Template Toolkit. 
  8. #
  9. # AUTHOR
  10. #   Andy Wardley   <abw@wardley.org>
  11. #
  12. # COPYRIGHT
  13. #   Copyright (C) 1996-2003 Andy Wardley.  All Rights Reserved.
  14. #   Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
  15. #
  16. #   This module is free software; you can redistribute it and/or
  17. #   modify it under the same terms as Perl itself.
  18. #
  19. #----------------------------------------------------------------------------
  20. #
  21. # $Id: Stash.pm,v 2.85 2004/01/30 17:51:01 abw Exp $
  22. #
  23. #============================================================================
  24.  
  25. package Template::Stash;
  26.  
  27. require 5.004;
  28.  
  29. use strict;
  30. use vars qw( $VERSION $DEBUG $ROOT_OPS $SCALAR_OPS $HASH_OPS $LIST_OPS );
  31.  
  32. $VERSION = sprintf("%d.%02d", q$Revision: 2.85 $ =~ /(\d+)\.(\d+)/);
  33.  
  34.  
  35. #========================================================================
  36. #                    -- PACKAGE VARIABLES AND SUBS --
  37. #========================================================================
  38.  
  39. #------------------------------------------------------------------------
  40. # Definitions of various pseudo-methods.  ROOT_OPS are merged into all
  41. # new Template::Stash objects, and are thus default global functions.
  42. # SCALAR_OPS are methods that can be called on a scalar, and ditto 
  43. # respectively for LIST_OPS and HASH_OPS
  44. #------------------------------------------------------------------------
  45.  
  46. $ROOT_OPS = {
  47.     'inc'  => sub { local $^W = 0; my $item = shift; ++$item }, 
  48.     'dec'  => sub { local $^W = 0; my $item = shift; --$item }, 
  49. #    import => \&hash_import,
  50.     defined $ROOT_OPS ? %$ROOT_OPS : (),
  51. };
  52.  
  53. $SCALAR_OPS = {
  54.     'item'    => sub {   $_[0] },
  55.     'list'    => sub { [ $_[0] ] },
  56.     'hash'    => sub { { value => $_[0] } },
  57.     'length'  => sub { length $_[0] },
  58.     'size'    => sub { return 1 },
  59.     'defined' => sub { return 1 },
  60.     'repeat'  => sub { 
  61.         my ($str, $count) = @_;
  62.         $str = '' unless defined $str;  
  63.         return '' unless $count;
  64.         $count ||= 1;
  65.         return $str x $count;
  66.     },
  67.     'search'  => sub { 
  68.         my ($str, $pattern) = @_;
  69.         return $str unless defined $str and defined $pattern;
  70.         return $str =~ /$pattern/;
  71.     },
  72.     'replace'  => sub { 
  73.         my ($str, $search, $replace) = @_;
  74.         $replace = '' unless defined $replace;
  75.         return $str unless defined $str and defined $search;
  76.         $str =~ s/$search/$replace/g;
  77. #       print STDERR "s [ $search ] [ $replace ] g\n";
  78. #       eval "\$str =~ s$search$replaceg";
  79.         return $str;
  80.     },
  81.     'match' => sub {
  82.         my ($str, $search) = @_;
  83.         return $str unless defined $str and defined $search;
  84.         my @matches = ($str =~ /$search/);
  85.         return @matches ? \@matches : '';
  86.     },
  87.     'split'   => sub { 
  88.         my ($str, $split, @args) = @_;
  89.         $str = '' unless defined $str;
  90.         return [ defined $split ? split($split, $str, @args)
  91.                                 : split(' ', $str, @args) ];
  92.     },
  93.     'chunk' => sub {
  94.         my ($string, $size) = @_;
  95.         my @list;
  96.         $size ||= 1;
  97.         if ($size < 0) {
  98.             # sexeger!  It's faster to reverse the string, search
  99.             # it from the front and then reverse the output than to 
  100.             # search it from the end, believe it nor not!
  101.             $string = reverse $string;
  102.             $size = -$size;
  103.             unshift(@list, scalar reverse $1) 
  104.                 while ($string =~ /((.{$size})|(.+))/g);
  105.         }
  106.         else {
  107.             push(@list, $1) while ($string =~ /((.{$size})|(.+))/g);
  108.         }
  109.         return \@list;
  110.     },
  111.     
  112.  
  113.     defined $SCALAR_OPS ? %$SCALAR_OPS : (),
  114. };
  115.  
  116. $HASH_OPS = {
  117.     'item'   => sub { 
  118.         my ($hash, $item) = @_; 
  119.         $item = '' unless defined $item;
  120.         return if $item =~ /^[_.]/;
  121.         $hash->{ $item };
  122.     },
  123.     'hash'   => sub { $_[0] },
  124.     'size'   => sub { scalar keys %{$_[0]} },
  125.     'keys'   => sub { [ keys   %{ $_[0] } ] },
  126.     'values' => sub { [ values %{ $_[0] } ] },
  127.     'each'   => sub { [        %{ $_[0] } ] },
  128.     'list'   => sub { 
  129.         my ($hash, $what) = @_;  $what ||= '';
  130.         return ($what eq 'keys')   ? [   keys %$hash ]
  131.             : ($what eq 'values') ? [ values %$hash ]
  132.             : ($what eq 'each')   ? [        %$hash ]
  133.             : [ map { { key => $_ , value => $hash->{ $_ } } }
  134.                 keys %$hash ];
  135.     },
  136.     'exists'  => sub { exists $_[0]->{ $_[1] } },
  137.     'defined' => sub { defined $_[0]->{ $_[1] } },
  138.     'import'  => \&hash_import,
  139.     'sort'    => sub {
  140.         my ($hash) = @_;
  141.         [ sort { lc $hash->{$a} cmp lc $hash->{$b} } (keys %$hash) ];
  142.     },
  143.     'nsort'    => sub {
  144.         my ($hash) = @_;
  145.         [ sort { $hash->{$a} <=> $hash->{$b} } (keys %$hash) ];
  146.     },
  147.     defined $HASH_OPS ? %$HASH_OPS : (),
  148. };
  149.  
  150. $LIST_OPS = {
  151.     'item'    => sub { $_[0]->[ $_[1] || 0 ] },
  152.     'list'    => sub { $_[0] },
  153.     'hash'    => sub { my $list = shift; my $n = 0; 
  154.                        return { map { ($n++, $_) } @$list }; },
  155.     'push'    => sub { my $list = shift; push(@$list, shift); return '' },
  156.     'pop'     => sub { my $list = shift; pop(@$list) },
  157.     'unshift' => sub { my $list = shift; unshift(@$list, shift); return '' },
  158.     'shift'   => sub { my $list = shift; shift(@$list) },
  159.     'max'     => sub { local $^W = 0; my $list = shift; $#$list; },
  160.     'size'    => sub { local $^W = 0; my $list = shift; $#$list + 1; },
  161.     'first'   => sub {
  162.         my $list = shift;
  163.         return $list->[0] unless @_;
  164.         return [ @$list[0..$_[0]-1] ];
  165.     },
  166.     'last'    => sub {
  167.         my $list = shift;
  168.         return $list->[-1] unless @_;
  169.         return [ @$list[-$_[0]..-1] ];
  170.     },
  171.     'reverse' => sub { my $list = shift; [ reverse @$list ] },
  172.     'grep'    => sub { 
  173.         my ($list, $pattern) = @_;
  174.         $pattern ||= '';
  175.         return [ grep /$pattern/, @$list ];
  176.     },
  177.     'join'    => sub { 
  178.         my ($list, $joint) = @_; 
  179.         join(defined $joint ? $joint : ' ', 
  180.              map { defined $_ ? $_ : '' } @$list) 
  181.         },
  182.     'sort'    => sub {
  183.         $^W = 0;
  184.         my ($list, $field) = @_;
  185.         return $list unless @$list > 1;     # no need to sort 1 item lists
  186.         return $field                       # Schwartzian Transform 
  187.             ?  map  { $_->[0] }             # for case insensitivity
  188.                sort { $a->[1] cmp $b->[1] }
  189.                map  { [ $_, lc(ref($_) eq 'HASH' 
  190.                    ? $_->{ $field } : 
  191.                    UNIVERSAL::can($_, $field)
  192.                    ? $_->$field() : $_) ] } 
  193.                @$list 
  194.             :  map  { $_->[0] }
  195.                sort { $a->[1] cmp $b->[1] }
  196.                map  { [ $_, lc $_ ] } 
  197.                @$list
  198.    },
  199.    'nsort'    => sub {
  200.         my ($list, $field) = @_;
  201.         return $list unless $#$list;        # no need to sort 1 item lists
  202.         return $field                       # Schwartzian Transform 
  203.             ?  map  { $_->[0] }             # for case insensitivity
  204.                sort { $a->[1] <=> $b->[1] }
  205.                map  { [ $_, lc(ref($_) eq 'HASH' 
  206.                    ? $_->{ $field } : 
  207.                    UNIVERSAL::can($_, $field)
  208.                    ? $_->$field() : $_) ] } 
  209.                @$list 
  210.             :  map  { $_->[0] }
  211.                sort { $a->[1] <=> $b->[1] }
  212.                map  { [ $_, lc $_ ] } 
  213.                @$list
  214.     },
  215.     'unique'  => sub { my %u; [ grep { ++$u{$_} == 1 } @{$_[0]} ] },
  216.     'merge'   => sub {
  217.         my $list = shift;
  218.         return [ @$list, grep defined, map ref eq 'ARRAY' ? @$_ : undef, @_ ];
  219.     },
  220.     'slice' => sub {
  221.         my ($list, $from, $to) = @_;
  222.         $from ||= 0;
  223.         $to = $#$list unless defined $to;
  224.         return [ @$list[$from..$to] ];
  225.     },
  226.     'splice'  => sub {
  227.         my ($list, $offset, $length, @replace) = @_;
  228.         if (@replace) {
  229.             # @replace can contain a list of multiple replace items, or 
  230.             # be a single reference to a list
  231.             @replace = @{ $replace[0] }
  232.             if @replace == 1 && ref $replace[0] eq 'ARRAY';
  233.             return [ splice @$list, $offset, $length, @replace ];
  234.         }
  235.         elsif (defined $length) {
  236.             return [ splice @$list, $offset, $length ];
  237.         }
  238.         elsif (defined $offset) {
  239.             return [ splice @$list, $offset ];
  240.         }
  241.         else {
  242.             return [ splice(@$list) ];
  243.         }
  244.     },
  245.  
  246.     defined $LIST_OPS ? %$LIST_OPS : (),
  247. };
  248.  
  249. sub hash_import { 
  250.     my ($hash, $imp) = @_;
  251.     $imp = {} unless ref $imp eq 'HASH';
  252.     @$hash{ keys %$imp } = values %$imp;
  253.     return '';
  254. }
  255.  
  256.  
  257. #------------------------------------------------------------------------
  258. # define_vmethod($type, $name, \&sub)
  259. #
  260. # Defines a virtual method of type $type (SCALAR, HASH, or LIST), with
  261. # name $name, that invokes &sub when called.  It is expected that &sub
  262. # be able to handle the type that it will be called upon.
  263. #------------------------------------------------------------------------
  264.  
  265. sub define_vmethod {
  266.     my ($class, $type, $name, $sub) = @_;
  267.     my $op;
  268.     $type = lc $type;
  269.  
  270.     if ($type =~ /^scalar|item$/) {
  271.         $op = $SCALAR_OPS;
  272.     }
  273.     elsif ($type eq 'hash') {
  274.         $op = $HASH_OPS;
  275.     }
  276.     elsif ($type =~ /^list|array$/) {
  277.         $op = $LIST_OPS;
  278.     }
  279.     else {
  280.         die "invalid vmethod type: $type\n";
  281.     }
  282.  
  283.     $op->{ $name } = $sub;
  284.  
  285.     return 1;
  286. }
  287.  
  288.  
  289. #========================================================================
  290. #                      -----  CLASS METHODS -----
  291. #========================================================================
  292.  
  293. #------------------------------------------------------------------------
  294. # new(\%params)
  295. #
  296. # Constructor method which creates a new Template::Stash object.
  297. # An optional hash reference may be passed containing variable 
  298. # definitions that will be used to initialise the stash.
  299. #
  300. # Returns a reference to a newly created Template::Stash.
  301. #------------------------------------------------------------------------
  302.  
  303. sub new {
  304.     my $class  = shift;
  305.     my $params = ref $_[0] eq 'HASH' ? shift(@_) : { @_ };
  306.  
  307.     my $self   = {
  308.         global  => { },
  309.         %$params,
  310.         %$ROOT_OPS,
  311.         '_PARENT' => undef,
  312.     };
  313.  
  314.     bless $self, $class;
  315. }
  316.  
  317.  
  318. #========================================================================
  319. #                   -----  PUBLIC OBJECT METHODS -----
  320. #========================================================================
  321.  
  322. #------------------------------------------------------------------------
  323. # clone(\%params)
  324. #
  325. # Creates a copy of the current stash object to effect localisation 
  326. # of variables.  The new stash is blessed into the same class as the 
  327. # parent (which may be a derived class) and has a '_PARENT' member added
  328. # which contains a reference to the parent stash that created it
  329. # ($self).  This member is used in a successive declone() method call to
  330. # return the reference to the parent.
  331. # A parameter may be provided which should reference a hash of 
  332. # variable/values which should be defined in the new stash.  The 
  333. # update() method is called to define these new variables in the cloned
  334. # stash.
  335. #
  336. # Returns a reference to a cloned Template::Stash.
  337. #------------------------------------------------------------------------
  338.  
  339. sub clone {
  340.     my ($self, $params) = @_;
  341.     $params ||= { };
  342.  
  343.     # look out for magical 'import' argument which imports another hash
  344.     my $import = $params->{ import };
  345.     if (defined $import && UNIVERSAL::isa($import, 'HASH')) {
  346.         delete $params->{ import };
  347.     }
  348.     else {
  349.         undef $import;
  350.     }
  351.  
  352.     my $clone = bless { 
  353.         %$self,         # copy all parent members
  354.         %$params,       # copy all new data
  355.         '_PARENT' => $self,     # link to parent
  356.     }, ref $self;
  357.     
  358.     # perform hash import if defined
  359.     &{ $HASH_OPS->{ import }}($clone, $import)
  360.         if defined $import;
  361.  
  362.     return $clone;
  363. }
  364.  
  365.     
  366. #------------------------------------------------------------------------
  367. # declone($export) 
  368. #
  369. # Returns a reference to the PARENT stash.  When called in the following
  370. # manner:
  371. #    $stash = $stash->declone();
  372. # the reference count on the current stash will drop to 0 and be "freed"
  373. # and the caller will be left with a reference to the parent.  This 
  374. # contains the state of the stash before it was cloned.  
  375. #------------------------------------------------------------------------
  376.  
  377. sub declone {
  378.     my $self = shift;
  379.     $self->{ _PARENT } || $self;
  380. }
  381.  
  382.  
  383. #------------------------------------------------------------------------
  384. # get($ident)
  385. # Returns the value for an variable stored in the stash.  The variable
  386. # may be specified as a simple string, e.g. 'foo', or as an array 
  387. # reference representing compound variables.  In the latter case, each
  388. # pair of successive elements in the list represent a node in the 
  389. # compound variable.  The first is the variable name, the second a 
  390. # list reference of arguments or 0 if undefined.  So, the compound 
  391. # variable [% foo.bar('foo').baz %] would be represented as the list
  392. # [ 'foo', 0, 'bar', ['foo'], 'baz', 0 ].  Returns the value of the
  393. # identifier or an empty string if undefined.  Errors are thrown via
  394. # die().
  395. #------------------------------------------------------------------------
  396.  
  397. sub get {
  398.     my ($self, $ident, $args) = @_;
  399.     my ($root, $result);
  400.     $root = $self;
  401.  
  402.     if (ref $ident eq 'ARRAY'
  403.         || ($ident =~ /\./) 
  404.         && ($ident = [ map { s/\(.*$//; ($_, 0) } split(/\./, $ident) ])) {
  405.         my $size = $#$ident;
  406.  
  407.         # if $ident is a list reference, then we evaluate each item in the 
  408.         # identifier against the previous result, using the root stash 
  409.         # ($self) as the first implicit 'result'...
  410.         
  411.         foreach (my $i = 0; $i <= $size; $i += 2) {
  412.             $result = $self->_dotop($root, @$ident[$i, $i+1]);
  413.             last unless defined $result;
  414.             $root = $result;
  415.         }
  416.     }
  417.     else {
  418.         $result = $self->_dotop($root, $ident, $args);
  419.     }
  420.  
  421.     return defined $result ? $result : $self->undefined($ident, $args);
  422. }
  423.  
  424.  
  425. #------------------------------------------------------------------------
  426. # set($ident, $value, $default)
  427. #
  428. # Updates the value for a variable in the stash.  The first parameter
  429. # should be the variable name or array, as per get().  The second 
  430. # parameter should be the intended value for the variable.  The third,
  431. # optional parameter is a flag which may be set to indicate 'default'
  432. # mode.  When set true, the variable will only be updated if it is
  433. # currently undefined or has a false value.  The magical 'IMPORT'
  434. # variable identifier may be used to indicate that $value is a hash
  435. # reference whose values should be imported.  Returns the value set,
  436. # or an empty string if not set (e.g. default mode).  In the case of 
  437. # IMPORT, returns the number of items imported from the hash.
  438. #------------------------------------------------------------------------
  439.  
  440. sub set {
  441.     my ($self, $ident, $value, $default) = @_;
  442.     my ($root, $result, $error);
  443.  
  444.     $root = $self;
  445.  
  446.     ELEMENT: {
  447.         if (ref $ident eq 'ARRAY'
  448.             || ($ident =~ /\./) 
  449.             && ($ident = [ map { s/\(.*$//; ($_, 0) }
  450.                            split(/\./, $ident) ])) {
  451.             
  452.             # a compound identifier may contain multiple elements (e.g. 
  453.             # foo.bar.baz) and we must first resolve all but the last, 
  454.             # using _dotop() with the $lvalue flag set which will create 
  455.             # intermediate hashes if necessary...
  456.             my $size = $#$ident;
  457.             foreach (my $i = 0; $i < $size - 2; $i += 2) {
  458.                 $result = $self->_dotop($root, @$ident[$i, $i+1], 1);
  459.                 last ELEMENT unless defined $result;
  460.                 $root = $result;
  461.             }
  462.             
  463.             # then we call _assign() to assign the value to the last element
  464.             $result = $self->_assign($root, @$ident[$size-1, $size], 
  465.                                      $value, $default);
  466.         }
  467.         else {
  468.             $result = $self->_assign($root, $ident, 0, $value, $default);
  469.         }
  470.     }
  471.     
  472.     return defined $result ? $result : '';
  473. }
  474.  
  475.  
  476. #------------------------------------------------------------------------
  477. # getref($ident)
  478. # Returns a "reference" to a particular item.  This is represented as a 
  479. # closure which will return the actual stash item when called.  
  480. # WARNING: still experimental!
  481. #------------------------------------------------------------------------
  482.  
  483. sub getref {
  484.     my ($self, $ident, $args) = @_;
  485.     my ($root, $item, $result);
  486.     $root = $self;
  487.  
  488.     if (ref $ident eq 'ARRAY') {
  489.         my $size = $#$ident;
  490.         
  491.         foreach (my $i = 0; $i <= $size; $i += 2) {
  492.             ($item, $args) = @$ident[$i, $i + 1]; 
  493.             last if $i >= $size - 2;  # don't evaluate last node
  494.             last unless defined 
  495.                 ($root = $self->_dotop($root, $item, $args));
  496.         }
  497.     }
  498.     else {
  499.         $item = $ident;
  500.     }
  501.     
  502.     if (defined $root) {
  503.         return sub { my @args = (@{$args||[]}, @_);
  504.                      $self->_dotop($root, $item, \@args);
  505.                  }
  506.     }
  507.     else {
  508.         return sub { '' };
  509.     }
  510. }
  511.  
  512.  
  513.  
  514.  
  515. #------------------------------------------------------------------------
  516. # update(\%params)
  517. #
  518. # Update multiple variables en masse.  No magic is performed.  Simple
  519. # variable names only.
  520. #------------------------------------------------------------------------
  521.  
  522. sub update {
  523.     my ($self, $params) = @_;
  524.  
  525.     # look out for magical 'import' argument to import another hash
  526.     my $import = $params->{ import };
  527.     if (defined $import && UNIVERSAL::isa($import, 'HASH')) {
  528.         @$self{ keys %$import } = values %$import;
  529.         delete $params->{ import };
  530.     }
  531.  
  532.     @$self{ keys %$params } = values %$params;
  533. }
  534.  
  535.  
  536. #------------------------------------------------------------------------
  537. # undefined($ident, $args)
  538. #
  539. # Method called when a get() returns an undefined value.  Can be redefined
  540. # in a subclass to implement alternate handling.
  541. #------------------------------------------------------------------------
  542.  
  543. sub undefined {
  544.     my ($self, $ident, $args);
  545.     return '';
  546. }
  547.  
  548.  
  549. #========================================================================
  550. #                  -----  PRIVATE OBJECT METHODS -----
  551. #========================================================================
  552.  
  553. #------------------------------------------------------------------------
  554. # _dotop($root, $item, \@args, $lvalue)
  555. #
  556. # This is the core 'dot' operation method which evaluates elements of 
  557. # variables against their root.  All variables have an implicit root 
  558. # which is the stash object itself (a hash).  Thus, a non-compound 
  559. # variable 'foo' is actually '(stash.)foo', the compound 'foo.bar' is
  560. # '(stash.)foo.bar'.  The first parameter is a reference to the current
  561. # root, initially the stash itself.  The second parameter contains the 
  562. # name of the variable element, e.g. 'foo'.  The third optional
  563. # parameter is a reference to a list of any parenthesised arguments 
  564. # specified for the variable, which are passed to sub-routines, object 
  565. # methods, etc.  The final parameter is an optional flag to indicate 
  566. # if this variable is being evaluated on the left side of an assignment
  567. # (e.g. foo.bar.baz = 10).  When set true, intermediated hashes will 
  568. # be created (e.g. bar) if necessary.  
  569. #
  570. # Returns the result of evaluating the item against the root, having
  571. # performed any variable "magic".  The value returned can then be used
  572. # as the root of the next _dotop() in a compound sequence.  Returns
  573. # undef if the variable is undefined.
  574. #------------------------------------------------------------------------
  575.  
  576. sub _dotop {
  577.     my ($self, $root, $item, $args, $lvalue) = @_;
  578.     my $rootref = ref $root;
  579.     my $atroot  = ($root eq $self);
  580.     my ($value, @result);
  581.  
  582.     $args ||= [ ];
  583.     $lvalue ||= 0;
  584.  
  585. #    print STDERR "_dotop(root=$root, item=$item, args=[@$args])\n"
  586. #   if $DEBUG;
  587.  
  588.     # return undef without an error if either side of the dot is unviable
  589.     # or if an attempt is made to access a private member, starting _ or .
  590.     return undef
  591.         unless defined($root) and defined($item) and $item !~ /^[\._]/;
  592.  
  593.     if ($atroot || $rootref eq 'HASH') {
  594.         # if $root is a regular HASH or a Template::Stash kinda HASH (the 
  595.         # *real* root of everything).  We first lookup the named key 
  596.         # in the hash, or create an empty hash in its place if undefined
  597.         # and the $lvalue flag is set.  Otherwise, we check the HASH_OPS
  598.         # pseudo-methods table, calling the code if found, or return undef.
  599.         
  600.         if (defined($value = $root->{ $item })) {
  601.             return $value unless ref $value eq 'CODE';      ## RETURN
  602.             @result = &$value(@$args);                      ## @result
  603.         }
  604.         elsif ($lvalue) {
  605.             # we create an intermediate hash if this is an lvalue
  606.             return $root->{ $item } = { };                  ## RETURN
  607.         }
  608.         # ugly hack: only allow import vmeth to be called on root stash
  609.         elsif (($value = $HASH_OPS->{ $item })
  610.                && ! $atroot || $item eq 'import') {
  611.             @result = &$value($root, @$args);               ## @result
  612.         }
  613.         elsif ( ref $item eq 'ARRAY' ) {
  614.             # hash slice
  615.             return [@$root{@$item}];                        ## RETURN
  616.         }
  617.     }
  618.     elsif ($rootref eq 'ARRAY') {    
  619.         # if root is an ARRAY then we check for a LIST_OPS pseudo-method 
  620.         # (except for l-values for which it doesn't make any sense)
  621.         # or return the numerical index into the array, or undef
  622.         
  623.         if (($value = $LIST_OPS->{ $item }) && ! $lvalue) {
  624.             @result = &$value($root, @$args);               ## @result
  625.         }
  626.         elsif ($item =~ /^-?\d+$/) {
  627.             $value = $root->[$item];
  628.             return $value unless ref $value eq 'CODE';      ## RETURN
  629.             @result = &$value(@$args);                      ## @result
  630.         }
  631.         elsif ( ref $item eq 'ARRAY' ) {
  632.             # array slice
  633.             return [@$root[@$item]];                        ## RETURN
  634.         }
  635.     }
  636.     
  637.     # NOTE: we do the can-can because UNIVSERAL::isa($something, 'UNIVERSAL')
  638.     # doesn't appear to work with CGI, returning true for the first call
  639.     # and false for all subsequent calls. 
  640.     
  641.     elsif (ref($root) && UNIVERSAL::can($root, 'can')) {
  642.  
  643.         # if $root is a blessed reference (i.e. inherits from the 
  644.         # UNIVERSAL object base class) then we call the item as a method.
  645.         # If that fails then we try to fallback on HASH behaviour if 
  646.         # possible.
  647.         eval { @result = $root->$item(@$args); };       
  648.         
  649.         if ($@) {
  650.             # temporary hack - required to propogate errors thrown
  651.             # by views; if $@ is a ref (e.g. Template::Exception
  652.             # object then we assume it's a real error that needs
  653.             # real throwing
  654.             
  655.             die $@ if ref($@) || ($@ !~ /Can't locate object method/);
  656.  
  657.             # failed to call object method, so try some fallbacks
  658. # patch from Stephen Howard
  659. # -- remove from here... --
  660.             if (UNIVERSAL::isa($root, 'HASH')
  661.                 && defined($value = $root->{ $item })) {
  662.                 return $value unless ref $value eq 'CODE';      ## RETURN
  663.                 @result = &$value(@$args);
  664.             }
  665. # -- and replace with this... --
  666. #            if (UNIVERSAL::isa($root, 'HASH') ) {
  667. #                if( defined($value = $root->{ $item })) {
  668. #                    return $value unless ref $value eq 'CODE';      ## RETURN
  669. #                    @result = &$value(@$args);
  670. #                }
  671. #                elsif ($value = $HASH_OPS->{ $item }) {
  672. #                    @result = &$value($root, @$args);
  673. #                }
  674. #            }
  675. # -- remove from here... --
  676.             elsif (UNIVERSAL::isa($root, 'ARRAY') 
  677.                && ($value = $LIST_OPS->{ $item })) {
  678.                 @result = &$value($root, @$args);
  679.             }
  680. # -- and replace with this... --
  681. #            elsif (UNIVERSAL::isa($root, 'ARRAY') ) {
  682. #                if( $value = $LIST_OPS->{ $item }) {
  683. #                   @result = &$value($root, @$args);
  684. #                }
  685. #                elsif( $item =~ /^-?\d+$/ ) {
  686. #                   $value = $root->[$item];
  687. #                   return $value unless ref $value eq 'CODE';      ## RETURN
  688. #                   @result = &$value(@$args);                      ## @result
  689. #                }
  690. #                elsif ( ref $item eq 'ARRAY' ) {
  691. #                    # array slice
  692. #                    return [@$root[@$item]];                        ## RETURN
  693. #                }
  694. #            }
  695. # -- end --
  696.             elsif ($value = $SCALAR_OPS->{ $item }) {
  697.                 @result = &$value($root, @$args);
  698.             }
  699.             elsif ($value = $LIST_OPS->{ $item }) {
  700.                 @result = &$value([$root], @$args);
  701.             }
  702.             elsif ($self->{ _DEBUG }) {
  703.                 @result = (undef, $@);
  704.             }
  705.         }
  706.     }
  707.     elsif (($value = $SCALAR_OPS->{ $item }) && ! $lvalue) {
  708.         # at this point, it doesn't look like we've got a reference to
  709.         # anything we know about, so we try the SCALAR_OPS pseudo-methods
  710.         # table (but not for l-values)
  711.         @result = &$value($root, @$args);           ## @result
  712.     }
  713.     elsif (($value = $LIST_OPS->{ $item }) && ! $lvalue) {
  714.         # last-ditch: can we promote a scalar to a one-element
  715.         # list and apply a LIST_OPS virtual method?
  716.         @result = &$value([$root], @$args);
  717.     }
  718.     elsif ($self->{ _DEBUG }) {
  719.         die "don't know how to access [ $root ].$item\n";   ## DIE
  720.     }
  721.     else {
  722.         @result = ();
  723.     }
  724.  
  725.     # fold multiple return items into a list unless first item is undef
  726.     if (defined $result[0]) {
  727.         return                              ## RETURN
  728.         scalar @result > 1 ? [ @result ] : $result[0];
  729.     }
  730.     elsif (defined $result[1]) {
  731.         die $result[1];                     ## DIE
  732.     }
  733.     elsif ($self->{ _DEBUG }) {
  734.         die "$item is undefined\n";         ## DIE
  735.     }
  736.  
  737.     return undef;
  738. }
  739.  
  740.  
  741. #------------------------------------------------------------------------
  742. # _assign($root, $item, \@args, $value, $default)
  743. #
  744. # Similar to _dotop() above, but assigns a value to the given variable
  745. # instead of simply returning it.  The first three parameters are the
  746. # root item, the item and arguments, as per _dotop(), followed by the 
  747. # value to which the variable should be set and an optional $default
  748. # flag.  If set true, the variable will only be set if currently false
  749. # (undefined/zero)
  750. #------------------------------------------------------------------------
  751.  
  752. sub _assign {
  753.     my ($self, $root, $item, $args, $value, $default) = @_;
  754.     my $rootref = ref $root;
  755.     my $atroot  = ($root eq $self);
  756.     my $result;
  757.     $args ||= [ ];
  758.     $default ||= 0;
  759.  
  760. #    print(STDERR "_assign(root=$root, item=$item, args=[@$args], \n",
  761. #                         "value=$value, default=$default)\n")
  762. #   if $DEBUG;
  763.     
  764.     # return undef without an error if either side of the dot is unviable
  765.     # or if an attempt is made to update a private member, starting _ or .
  766.     return undef                        ## RETURN
  767.     unless $root and defined $item and $item !~ /^[\._]/;
  768.     
  769.     if ($rootref eq 'HASH' || $atroot) {
  770. #   if ($item eq 'IMPORT' && UNIVERSAL::isa($value, 'HASH')) {
  771. #       # import hash entries into root hash
  772. #       @$root{ keys %$value } = values %$value;
  773. #       return '';                      ## RETURN
  774. #   }
  775.         # if the root is a hash we set the named key
  776.         return ($root->{ $item } = $value)          ## RETURN
  777.             unless $default && $root->{ $item };
  778.     }
  779.     elsif ($rootref eq 'ARRAY' && $item =~ /^-?\d+$/) {
  780.         # or set a list item by index number
  781.         return ($root->[$item] = $value)            ## RETURN
  782.             unless $default && $root->{ $item };
  783.     }
  784.     elsif (UNIVERSAL::isa($root, 'UNIVERSAL')) {
  785.         # try to call the item as a method of an object
  786.         
  787.         return $root->$item(@$args, $value)         ## RETURN
  788.             unless $default && $root->$item();
  789.         
  790. # 2 issues:
  791. #   - method call should be wrapped in eval { }
  792. #   - fallback on hash methods if object method not found
  793. #
  794. #     eval { $result = $root->$item(@$args, $value); };     
  795. #     if ($@) {
  796. #         die $@ if ref($@) || ($@ !~ /Can't locate object method/);
  797. #         # failed to call object method, so try some fallbacks
  798. #         if (UNIVERSAL::isa($root, 'HASH') && exists $root->{ $item }) {
  799. #         $result = ($root->{ $item } = $value)
  800. #             unless $default && $root->{ $item };
  801. #         }
  802. #     }
  803. #     return $result;                       ## RETURN
  804.  
  805.     }
  806.     else {
  807.         die "don't know how to assign to [$root].[$item]\n";    ## DIE
  808.     }
  809.  
  810.     return undef;
  811. }
  812.  
  813.  
  814. #------------------------------------------------------------------------
  815. # _dump()
  816. #
  817. # Debug method which returns a string representing the internal state
  818. # of the object.  The method calls itself recursively to dump sub-hashes.
  819. #------------------------------------------------------------------------
  820.  
  821. sub _dump {
  822.     my $self   = shift;
  823.     return "[Template::Stash] " . $self->_dump_frame(2);
  824. }
  825.  
  826. sub _dump_frame {
  827.     my ($self, $indent) = @_;
  828.     $indent ||= 1;
  829.     my $buffer = '    ';
  830.     my $pad    = $buffer x $indent;
  831.     my $text   = "{\n";
  832.     local $" = ', ';
  833.  
  834.     my ($key, $value);
  835.  
  836.     return $text . "...excessive recursion, terminating\n"
  837.         if $indent > 32;
  838.     
  839.     foreach $key (keys %$self) {
  840.         $value = $self->{ $key };
  841.         $value = '<undef>' unless defined $value;
  842.         next if $key =~ /^\./;
  843.         if (ref($value) eq 'ARRAY') {
  844.             $value = '[ ' . join(', ', map { defined $_ ? $_ : '<undef>' }
  845.                                  @$value) . ' ]';
  846.         }
  847.         elsif (ref $value eq 'HASH') {
  848.             $value = _dump_frame($value, $indent + 1);
  849.         }
  850.         
  851.         $text .= sprintf("$pad%-16s => $value\n", $key);
  852.     }
  853.     $text .= $buffer x ($indent - 1) . '}';
  854.     return $text;
  855. }
  856.  
  857.  
  858. 1;
  859.  
  860. __END__
  861.  
  862.  
  863. #------------------------------------------------------------------------
  864. # IMPORTANT NOTE
  865. #   This documentation is generated automatically from source
  866. #   templates.  Any changes you make here may be lost.
  867. #   The 'docsrc' documentation source bundle is available for download
  868. #   from http://www.template-toolkit.org/docs.html and contains all
  869. #   the source templates, XML files, scripts, etc., from which the
  870. #   documentation for the Template Toolkit is built.
  871. #------------------------------------------------------------------------
  872.  
  873. =head1 NAME
  874.  
  875. Template::Stash - Magical storage for template variables
  876.  
  877. =head1 SYNOPSIS
  878.  
  879.     use Template::Stash;
  880.  
  881.     my $stash = Template::Stash->new(\%vars);
  882.  
  883.     # get variable values
  884.     $value = $stash->get($variable);
  885.     $value = $stash->get(\@compound);
  886.  
  887.     # set variable value
  888.     $stash->set($variable, $value);
  889.     $stash->set(\@compound, $value);
  890.  
  891.     # default variable value
  892.     $stash->set($variable, $value, 1);
  893.     $stash->set(\@compound, $value, 1);
  894.  
  895.     # set variable values en masse
  896.     $stash->update(\%new_vars)
  897.  
  898.     # methods for (de-)localising variables
  899.     $stash = $stash->clone(\%new_vars);
  900.     $stash = $stash->declone();
  901.  
  902. =head1 DESCRIPTION
  903.  
  904. The Template::Stash module defines an object class which is used to store
  905. variable values for the runtime use of the template processor.  Variable
  906. values are stored internally in a hash reference (which itself is blessed 
  907. to create the object) and are accessible via the get() and set() methods.
  908.  
  909. Variables may reference hash arrays, lists, subroutines and objects
  910. as well as simple values.  The stash automatically performs the right
  911. magic when dealing with variables, calling code or object methods,
  912. indexing into lists, hashes, etc.
  913.  
  914. The stash has clone() and declone() methods which are used by the
  915. template processor to make temporary copies of the stash for
  916. localising changes made to variables.
  917.  
  918. =head1 PUBLIC METHODS
  919.  
  920. =head2 new(\%params)
  921.  
  922. The new() constructor method creates and returns a reference to a new
  923. Template::Stash object.  
  924.  
  925.     my $stash = Template::Stash->new();
  926.  
  927. A hash reference may be passed to provide variables and values which
  928. should be used to initialise the stash.
  929.  
  930.     my $stash = Template::Stash->new({ var1 => 'value1', 
  931.                        var2 => 'value2' });
  932.  
  933. =head2 get($variable)
  934.  
  935. The get() method retrieves the variable named by the first parameter.
  936.  
  937.     $value = $stash->get('var1');
  938.  
  939. Dotted compound variables can be retrieved by specifying the variable
  940. elements by reference to a list.  Each node in the variable occupies
  941. two entries in the list.  The first gives the name of the variable
  942. element, the second is a reference to a list of arguments for that 
  943. element, or 0 if none.
  944.  
  945.     [% foo.bar(10).baz(20) %]
  946.  
  947.     $stash->get([ 'foo', 0, 'bar', [ 10 ], 'baz', [ 20 ] ]);
  948.  
  949. =head2 set($variable, $value, $default)
  950.  
  951. The set() method sets the variable name in the first parameter to the 
  952. value specified in the second.
  953.  
  954.     $stash->set('var1', 'value1');
  955.  
  956. If the third parameter evaluates to a true value, the variable is
  957. set only if it did not have a true value before.
  958.  
  959.     $stash->set('var2', 'default_value', 1);
  960.  
  961. Dotted compound variables may be specified as per get() above.
  962.  
  963.     [% foo.bar = 30 %]
  964.  
  965.     $stash->set([ 'foo', 0, 'bar', 0 ], 30);
  966.  
  967. The magical variable 'IMPORT' can be specified whose corresponding
  968. value should be a hash reference.  The contents of the hash array are
  969. copied (i.e. imported) into the current namespace.
  970.  
  971.     # foo.bar = baz, foo.wiz = waz
  972.     $stash->set('foo', { 'bar' => 'baz', 'wiz' => 'waz' });
  973.  
  974.     # import 'foo' into main namespace: foo = baz, wiz = waz
  975.     $stash->set('IMPORT', $stash->get('foo'));
  976.  
  977. =head2 clone(\%params)
  978.  
  979. The clone() method creates and returns a new Template::Stash object which
  980. represents a localised copy of the parent stash.  Variables can be
  981. freely updated in the cloned stash and when declone() is called, the
  982. original stash is returned with all its members intact and in the
  983. same state as they were before clone() was called.
  984.  
  985. For convenience, a hash of parameters may be passed into clone() which 
  986. is used to update any simple variable (i.e. those that don't contain any 
  987. namespace elements like 'foo' and 'bar' but not 'foo.bar') variables while 
  988. cloning the stash.  For adding and updating complex variables, the set() 
  989. method should be used after calling clone().  This will correctly resolve
  990. and/or create any necessary namespace hashes.
  991.  
  992. A cloned stash maintains a reference to the stash that it was copied 
  993. from in its '_PARENT' member.
  994.  
  995. =head2 declone()
  996.  
  997. The declone() method returns the '_PARENT' reference and can be used to
  998. restore the state of a stash as described above.
  999.  
  1000. =head1 AUTHOR
  1001.  
  1002. Andy Wardley E<lt>abw@andywardley.comE<gt>
  1003.  
  1004. L<http://www.andywardley.com/|http://www.andywardley.com/>
  1005.  
  1006.  
  1007.  
  1008.  
  1009. =head1 VERSION
  1010.  
  1011. 2.85, distributed as part of the
  1012. Template Toolkit version 2.13, released on 30 January 2004.
  1013.  
  1014. =head1 COPYRIGHT
  1015.  
  1016.   Copyright (C) 1996-2004 Andy Wardley.  All Rights Reserved.
  1017.   Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.
  1018.  
  1019. This module is free software; you can redistribute it and/or
  1020. modify it under the same terms as Perl itself.
  1021.  
  1022. =head1 SEE ALSO
  1023.  
  1024. L<Template|Template>, L<Template::Context|Template::Context>
  1025.  
  1026. =cut
  1027.  
  1028. # Local Variables:
  1029. # mode: perl
  1030. # perl-indent-level: 4
  1031. # indent-tabs-mode: nil
  1032. # End:
  1033. #
  1034. # vim: expandtab shiftwidth=4:
  1035.