
=head1 NAME

Perldoc::Data - Data structures as Perldoc streams

=head1 DESCRIPTION

The unlucky of us have to, at some point, try to shoe-horn their data
objects into a document structure not designed for serialisation.  Of
course, you can do this with Perldoc.

To send a message, you point C<Perldoc::Data::Chill> at a data
structure.  This structure currently should contain no circular
references; currently they are detected, and error processing
instructions inserted into the event stream when they are found again.
Fixing this properly requires the marshalling system to remember the
entire data structure it has sent, which isn't good if you're dealing
with very large data structures that might themselves be lazily
streaming from a database or some such.

The C<Perldoc::Data::Chill> class acts as a C<Perldoc::Sender>; so to
actually write a document, you should connect it to a writer class,
such as C<Perldoc::Writer::XML>.

Here is an example of using this interface;

  my $chiller = Perldoc::Data::Chill->new(source => $structure);
  my $writer  = Perldoc::Writer::XML->new(output => "somefile.xml");
  $chiller->receiver($writer);
  $chiller->send_all;

C<Perldoc::Data::Chill> provides per-class hooks for controlling the
document marshalling; these are described on its man page.

Going the other way is a matter of connecting a stream of Perldoc
events to C<Perldoc::Data::Thaw>.  This would normally come from a
source such as a L<Perldoc::Parser::XML>;

  my $reader = Perldoc::Reader->new(input => "source.xml");
  my $parser = Perldoc::Parser::XML->new(reader => $reader);
  my $warmer = Perldoc::Data::Thaw->new();
  $parser->receiver($warmer);
  $reader->send_all();

=head1 C<Perldoc::Data> XML FORM

XML Data is nasty, but we're talking about a document structure here,
so XML is a good way to describe it.

=over

=item B<Scalars>

All scalars are represented as a stream of characters.  There is
nothing at present to determine what data type they represent, other
than context.

For example, the scalar "Foo", is represented as:

   Foo

=item B<Sets, Arrays and Hashes>

Sets (well, actually I<only> C<Set::Object> containers) are
represented identically to arrays.

The special tag C<E<lt>itemE<gt>> is used to denote an entry in an
array or a hash.  It may have one attribute; C<name>, if it is an
entry in a hash.

For instance, this hash:

  { "foo" => "bar",
    "baz" => "frop",
  }

Would be represented as:

  <item name="foo">bar</item>
  <item name="baz">frop</item>

If you are passing the document in to C<Perldoc::Data::Thaw>, you can
use, if it makes you feel better:

  <Hash>
    <item name="foo">bar</item>
    <item name="baz">frop</item>
  </Hash>

Arrays are a similar story; this array:

  [ "one", "two", [ "three part 1", "three part 2" ] ]

Would be represented as:

  <item>one</item>
  <item>two</item>
  <item>
    <item>three part 1</item>
    <item>three part 2</item>
  </item>

Or, if you wanted to be more explicit about where the collections are;

  <Array>
    <item>one</item>
    <item>two</item>
    <item>
      <Array>
        <item>three part 1</item>
        <item>three part 2</item>
      </Array>
    </item>
  </Array>

It is currently possible to have C<Perldoc::Data::Chill> insert these
extra tags, but still untested.

=item B<blessed objects>

Objects (apart from C<Set::Object> containers) are converted to an
element, with attributes for properties and sub-elements for complex
properties.

For instance, the following Perl object;

  bless({ Foo => "bar",
          Baz => "frop",
          Cheese => bless({ jeez => "louise" }, "Bert"),
        }, "Bob");

Would be represened in YAML as the simple;

  --- !perl/Bob
  Baz: frop
  Cheese: !perl/Bert
    jeez: louise
  Foo: bar

But this isn't a document about how easy it is to send data structures
around using YAML.  No, in our little XML language it looks like this:

  <Bob Baz="frop" Foo="bar">
    <Cheese>
      <Bert jeez="louise"/>
    </Cheese>
  </Bob>

This is actually converted to the following Perl structure on
reassembly;

  Bob->new( Baz => "frop", Foo => "bar",
            Cheese => Bert->new( jeez => "louise" )
          );

This is a lot different to most serialisation systems in that it
actually calls the constructor nicely.  You can get it to call a
different constructor by sub-classing C<Perldoc::Data::Thaw>.

B<note>: To get the above behaviour, you'd actually need to either
turn on the I<unsafe> mode mode of C<Perldoc::Data::Thaw>, or pass in
a C<classmap> mapping element names to constructors;

  my $warmer_for_above_example = Perldoc::Data::Thaw->new
      ( classmap => { Bob => "Bob", Bert => "Bert" },
      );

Alternatively, you can tie the C<Perldoc::Data::Thaw> object to a
C<Perldoc::Scottish> object (still in design stages) that is capable
of performing appropriate decisions via various hooks in
C<Perldoc::Data::Thaw> that will no doubt receive testing sooner or
later.

=back

=head1 BUGS AND LIMITATIONS

See L<www.yaml.org> for a way for sending data structures around that
conforms to standards and doesn't suck kumara.

=head1 SEE ALSO

L<Perldoc::Data::Chill>, L<Perldoc::Writer::XML>,
L<Perldoc::Data::Thaw>, L<Perldoc::Parser::XML>.

=cut

