NAME
Doc::Perlish::Data - Data structures as Perldoc streams
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 Doc::Perlish.
To send a message, you point Doc::Perlish::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 Doc::Perlish::Data::Chill
class acts as a Perldoc::Sender
; so to actually write a document, you should connect it to a writer class, such as Doc::Perlish::Writer::XML
.
Here is an example of using this interface;
my $chiller = Doc::Perlish::Data::Chill->new(source => $structure);
my $writer = Doc::Perlish::Writer::XML->new(output => "somefile.xml");
$chiller->receiver($writer);
$chiller->send_all;
Doc::Perlish::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 Doc::Perlish events to Doc::Perlish::Data::Thaw
. This would normally come from a source such as a Doc::Perlish::Parser::XML;
my $reader = Doc::Perlish::Reader->new(input => "source.xml");
my $parser = Doc::Perlish::Parser::XML->new(reader => $reader);
my $warmer = Doc::Perlish::Data::Thaw->new();
$parser->receiver($warmer);
$reader->send_all();
Doc::Perlish::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.
- 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
- Sets, Arrays and Hashes
-
Sets (well, actually only
Set::Object
containers) are represented identically to arrays.The special tag
<item>
is used to denote an entry in an array or a hash. It may have one attribute;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
Doc::Perlish::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
Doc::Perlish::Data::Chill
insert these extra tags, but still untested. - blessed objects
-
Objects (apart from
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
Doc::Perlish::Data::Thaw
.note: To get the above behaviour, you'd actually need to either turn on the unsafe mode mode of
Doc::Perlish::Data::Thaw
, or pass in aclassmap
mapping element names to constructors;my $warmer_for_above_example = Doc::Perlish::Data::Thaw->new ( classmap => { Bob => "Bob", Bert => "Bert" }, );
Alternatively, you can tie the
Doc::Perlish::Data::Thaw
object to aDoc::Perlish::Scottish
object (still in design stages) that is capable of performing appropriate decisions via various hooks inDoc::Perlish::Data::Thaw
that will no doubt receive testing sooner or later.
BUGS AND LIMITATIONS
See www.yaml.org for a way for sending data structures around that conforms to standards and doesn't suck kumara.
SEE ALSO
Doc::Perlish::Data::Chill, Perldoc::Writer::XML, Doc::Perlish::Data::Thaw, Perldoc::Parser::XML.