.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Pod::POM::Node 3pm" .TH Pod::POM::Node 3pm "2022-11-20" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Pod::POM::Node \- base class for a POM node .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 3 \& package Pod::POM::Node::Over; \& use parent qw( Pod::POM::Node ); \& use vars qw( @ATTRIBS @ACCEPT $EXPECT $ERROR ); \& \& @ATTRIBS = ( indent => 4 ); \& @ACCEPT = qw( over item begin for text verbatim ); \& $EXPECT = q( back ); \& \& package main; \& my $list = Pod::POM::Node::Over\->new(8); \& $list\->add(\*(Aqitem\*(Aq, \*(AqFirst Item\*(Aq); \& $list\->add(\*(Aqitem\*(Aq, \*(AqSecond Item\*(Aq); \& ... .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This documentation describes the inner workings of the Pod::POM::Node module and gives a brief overview of the relationship between it and its derived classes. It is intended more as a guide to the internals for interested hackers than as general user documentation. See Pod::POM for information on using the modules. .PP This module implements a base class node which is subclassed to represent different elements within a Pod Object Model. .PP .Vb 2 \& package Pod::POM::Node::Over; \& use parent qw( Pod::POM::Node ); .Ve .PP The base class implements the \fBnew()\fR constructor method to instantiate new node objects. .PP .Vb 1 \& my $list = Pod::POM::Node::Over\->new(); .Ve .PP The characteristics of a node can be specified by defining certain variables in the derived class package. The \f(CW@ATTRIBS\fR list can be used to denote attributes that the node should accept. In the case of an \f(CW\*(C`=over\*(C'\fR node, for example, an \f(CW\*(C`indent\*(C'\fR attribute can be specified which otherwise defaults to 4. .PP .Vb 3 \& package Pod::POM::Node::Over; \& use parent qw( Pod::POM::Node ); \& use vars qw( @ATTRIBS $ERROR ); \& \& @ATTRIBS = ( indent => 4 ); .Ve .PP The \fBnew()\fR method will now expect an argument to set the indent value, or will use 4 as the default if no argument is provided. .PP .Vb 2 \& my $list = Pod::POM::Node::Over\->new(8); # indent: 8 \& my $list = Pod::POM::Node::Over\->new( ); # indent: 4 .Ve .PP If the default value is undefined then the argument is mandatory. .PP .Vb 3 \& package Pod::POM::Node::Head1; \& use parent qw( Pod::POM::Node ); \& use vars qw( @ATTRIBS $ERROR ); \& \& @ATTRIBS = ( title => undef ); \& \& package main; \& my $head = Pod::POM::Node::Head1\->new(\*(AqMy Title\*(Aq); .Ve .PP If a mandatory argument isn't provided then the constructor will return undef to indicate failure. The \f(CW$ERROR\fR variable in the derived class package is set to contain a string of the form \*(L"$type expected a \&\f(CW$attribute\fR\*(R". .PP .Vb 3 \& # dies with error: "head1 expected a title" \& my $head = Pod::POM::Node::Head1\->new() \& || die $Pod::POM::Node::Head1::ERROR; .Ve .PP For convenience, the \fBerror()\fR subroutine can be called as a class method to retrieve this value. .PP .Vb 3 \& my $type = \*(AqPod::POM::Node::Head1\*(Aq; \& my $head = $type\->new() \& || die $type\->error(); .Ve .PP The \f(CW@ACCEPT\fR package variable can be used to indicate the node types that are permitted as children of a node. .PP .Vb 3 \& package Pod::POM::Node::Head1; \& use parent qw( Pod::POM::Node ); \& use vars qw( @ATTRIBS @ACCEPT $ERROR ); \& \& @ATTRIBS = ( title => undef ); \& @ACCEPT = qw( head2 over begin for text verbatim ); .Ve .PP The \fBadd()\fR method can then be called against a node to add a new child node as part of its content. .PP .Vb 1 \& $head\->add(\*(Aqover\*(Aq, 8); .Ve .PP The first argument indicates the node type. The \f(CW@ACCEPT\fR list is examined to ensure that the child node type is acceptable for the parent node. If valid, the constructor for the relevant child node class is called passing any remaining arguments as attributes. The new node is then returned. .PP .Vb 1 \& my $list = $head\->add(\*(Aqover\*(Aq, 8); .Ve .PP The \fBerror()\fR method can be called against the \fIparent\fR node to retrieve any constructor error generated by the \fIchild\fR node. .PP .Vb 2 \& my $list = $head\->add(\*(Aqover\*(Aq, 8); \& die $head\->error() unless defined $list; .Ve .PP If the child node is not acceptable to the parent then the \fBadd()\fR method returns one of the constants \s-1IGNORE, REDUCE\s0 or \s-1REJECT,\s0 as defined in Pod::POM::Constants. These return values are used by the Pod::POM parser module to implement a simple shift/reduce parser. .PP In the most common case, \s-1IGNORE\s0 is returned to indicate that the parent node doesn't know anything about the new child node. The parser uses this as an indication that it should back up through the parse stack until it finds a node which \fIwill\fR accept this child node. Through this mechanism, the parser is able to implicitly terminate certain \s-1POD\s0 blocks. For example, a list item initiated by a \f(CW\*(C`=item\*(C'\fR tag will \fInot\fR accept another \f(CW\*(C`=item\*(C'\fR tag, but will instead return \s-1IGNORE.\s0 The parser will back out until it finds the enclosing \f(CW\*(C`=over\*(C'\fR node which \fIwill\fR accept it. Thus, a new \f(CW\*(C`=item\*(C'\fR implicitly terminates any previous \f(CW\*(C`=item\*(C'\fR. .PP The \f(CW$EXPECT\fR package variable can be used to indicate a node type which a parent expects to terminate itself. An \f(CW\*(C`=over\*(C'\fR node, for example, should always be terminated by a matching \f(CW\*(C`=back\*(C'\fR. When such a match is made, the \fBadd()\fR method returns \s-1REDUCE\s0 to indicate successful termination. .PP .Vb 3 \& package Pod::POM::Node::Over; \& use parent qw( Pod::POM::Node ); \& use vars qw( @ATTRIBS @ACCEPT $EXPECT $ERROR ); \& \& @ATTRIBS = ( indent => 4 ); \& @ACCEPT = qw( over item begin for text verbatim ); \& $EXPECT = q( back ); \& \& package main; \& my $list = Pod::POM::Node::Over\->new(); \& my $item = $list\->add(\*(Aqitem\*(Aq); \& $list\->add(\*(Aqback\*(Aq); # returns REDUCE .Ve .PP If a child node isn't specified in the \f(CW@ACCEPT\fR list or doesn't match any \f(CW$EXPECT\fR specified then \s-1REJECT\s0 is returned. The parent node sets an internal error of the form \*(L"$type expected a terminating \f(CW$expect\fR\*(R". The parser uses this to detect missing \s-1POD\s0 tags. In nearly all cases the parser is smart enough to fix the incorrect structure and downgrades any errors to warnings. .PP .Vb 3 \& # dies with error \*(Aqover expected terminating back\*(Aq \& ref $list\->add(\*(Aqhead1\*(Aq, \*(AqMy Title\*(Aq) # returns REJECT \& || die $list\->error(); .Ve .PP Each node contains a 'type' field which contains a simple string indicating the node type, e.g. 'head1', 'over', etc. The \f(CW$NODES\fR and \&\f(CW$NAMES\fR package variables (in the base class) reference hash arrays which map these names to and from package names (e.g. head1 <=> Pod::POM::Node::Head1). .PP .Vb 1 \& print $list\->{ type }; # \*(Aqover\*(Aq .Ve .PP An \s-1AUTOLOAD\s0 method is provided to access to such internal items for those who don't like violating an object's encapsulation. .PP .Vb 1 \& print $list\->type(); .Ve .PP Nodes also contain a 'content' list, blessed into the Pod::POM::Node::Content class, which contains the content (child elements) for the node. The \s-1AUTOLOAD\s0 method returns this as a list reference or as a list of items depending on the context in which it is called. .PP .Vb 2 \& my $items = $list\->content(); \& my @items = $list\->content(); .Ve .PP Each node also contains a content list for each individual child node type that it may accept. .PP .Vb 3 \& my @items = $list\->item(); \& my @text = $list\->text(); \& my @vtext = $list\->verbatim(); .Ve .PP The \fBpresent()\fR method is used to present a node through a particular view. This simply maps the node type to a method which is then called against the view object. This is known as 'double dispatch'. .PP .Vb 2 \& my $view = \*(AqPod::POM::View::HTML\*(Aq; \& print $list\->present($view); .Ve .PP The method name is constructed from the node type prefixed by 'view_'. Thus the following are roughly equivalent. .PP .Vb 1 \& $list\->present($view); \& \& $view\->view_list($list); .Ve .PP The benefit of the former over the latter is, of course, that the caller doesn't need to know or determine the type of the node. The node itself is in the best position to determine what type it is. .SH "AUTHOR" .IX Header "AUTHOR" Andy Wardley .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (C) 2000, 2001 Andy Wardley. All Rights Reserved. .PP This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .SH "SEE ALSO" .IX Header "SEE ALSO" Consult Pod::POM for a general overview and examples of use.