
=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 (unless appropriate marshalling methods are used); this
limitation will be fixed by a later release.

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

