OK.  After much thinking on the subject, here are my recommendations:

First: give Pod the ability to delimit blocks of ambient text, e.g.:

 =text
 class Foo {
   has $bar;
 }
 =stop

'=text' and '=stop' would be considered to be separate but related
single-line Pod Sections, so Pod-stripping utilities would remove them
while leaving the lines between them intact.  (I'm not sold on the
specific names for these tags; just the principles behind them.)

By default, 'A<>' searches backward from its current position within
the scope of the current ambient text block.  This helps you catch
gotchas such as removing a piece of code and failing to remove the
documentation that was referencing it.  Consider, for example,
documenting the first attribute of a class that follows another class.
The coder removes the attribute, but fails to remove the
documentation that references it.  Suddenly, that documentation is
referencing the last attribute of the previous class.  If each class
were encapsulated in a separate ambient text section, Pod would then
know to complain that there is no attribute to reference anymore.

--

Allow ambient text blocks to be named, and allow 'A<>' to choose a
named ambient text block to search.  When you do this, the position of
the A<> tag relative to the ambient text block becomes irrelevant.
Example:

 =begin pod
 A<Foo.has>
 =end pod

 =text Foo
 class Foo {
   has $bar;
 }
 =stop Foo

You might also consider changing the rules when searching ambient text
blocks in this way, so that it searches for the first instance of the
prefix in the block instead of searching for the last one.

--

Let a pod section specify a default ambient code block, causing all
ambient references within its scope to automatically reference that
block:

 =begin pod :A<Foo>
 A<has>
 =end pod

 =text Foo
 class Foo {
   has $bar;
 }
 =stop Foo

--

Allow ambient text blocks to be nested:

 =begin pod :A<Foo>
   =ATTRIBUTE A<has>
   =METHOD A<method> :A<baz>
     =NAME A<name>
     =RETURNS A<return>

 =end pod

 =text Foo
 class Foo {
   has $bar;

 =text baz
   method baz () returns Number { ... }
 =stop baz
 }
 =stop Foo

--

Allow an optional "array index" for the prefix so that you can skip
over a given number of matches, rather than being limited to the first
one you find:

 =begin pod :A<Foo>
 A<has[0]>
 A<has[1]>
 =end pod

 =text Foo
 class Foo {
   has $bar;
   has $baz;
 }
 =stop Foo

--

Finally, there are cases where prefix handles won't be readily
available.  Consider what happens when you try to document a C++
function:

 extern void swap(int*, int*);
 =NAME A<void>
 =RETURN A<extern>

How do you reference the 'extern' in that function definition?

Now let's say that the C++ programmer decides that he wants this
function to return a success flag:

 extern int swap(int*, int*);
 =NAME A<int>
 =RETURN A<extern>

Note that he had to change 'void' to 'int' in two places: once in the
code, and once in the documentation.  This, combined with the
distinctly unintuitive prefixes being used in the ambient references,
can lead to a real mess.

In cases such as these, it might be best to have Pod punt to an
'assistant parser' that returns the equivalent of a list of '=alias'
tags.  I see this as being a case of "All's fair if you predeclare",
and I was inspired by XML's Processor Instructions (conceptually) and
namespaces (syntactically).  Using this, the above might be handled
as:

 =parser C++ uri

 ...

 =text swap :parsed<C++>
 extern void swap(int*, int*);
 =stop text
 =for pod :A<swap>
 =NAME A<name>
 =RETURN A<return>

The '=parser' line tells Pod that some later ambient text sections
will be parsed using a C++ helper utility.  It's assumed that Pod will
search for said helper utility, and will complain if it can't find it.

I'm assuming that the helper utility would return the equivalent of:

 =alias name swap
 =alias return void

when given the ambient text section in question.  I'm also figuring
that these parser-generated aliases would take precedence over
prefix-based referencing, but that explicit '=alias' tags would take
precedence over them.

--

One ramification of Larry's earlier suggestion that Perl not handle
Pod sections exactly the same way that Pod does is that it's possible
for certain sections of Perl code to not register as ambient text in a
Pod Parser:

 say qq:to(END)
 =begin pod
 oops
 =end pod
 END
 =for pod
 A<=begin>

To a Perl Parser, the code is as follows:

 say qq:to(END)
 =begin pod
 oops
 =end pod
 END

To the Pod Parser, the ambient text is this:

 say qq:to(END)
 END

This wasn't a big deal when Pod was completely ignoring the ambient
text.  But once it starts referencing ambient text, you're best off
keeping Perl code and Pod ambient text in sync with each other.

--
Jonathan "Dataweaver" Lang

Reply via email to