Problem 1:
You want to pass a data structure to another plugin or store it in a MUSHclient variable for later use.
Solution:
use Storable qw( nfreeze thaw );
sub freezevar {
my $var = shift or die;
return join('#',unpack("U*",nfreeze $var));
}
sub thawvar {
my $var = shift or die;
return thaw pack("U*",split(/#/,$var));
}
my $data = {'This' => {'is' => {'a' => [{'weird' => {'data' => {'structure' => ['indeed!']}}}]}}};
$world->SetVariable('SERIALIZED',freezevar($data));
# ... later or somewhere else ...
my $newdata = thawvar($world->GetVariable('SERIALIZED'));
$world->Note($newdata->{'This'}{'is'}{'a'}[0]{'weird'}{'data'}{'structure'}[0]);
Explanation:
The Storable module (available with every perl distribution) and its nfreeze function allows you to make a serialized copy of what a structure looks like in the memory. It will not care for cross-references or other traps. Whatever "belongs" to the structure, will be copied and serialized. The resulting string can be used later on, stored to disk, or even send over network to another machine. Even such things like machine architecture will not matter. The only thing to note is that it only accepts a reference as the main argument.
The thaw function will create a new reference to the 'frozen' structure. It will look exactly like what you have copied, no matter when or where you 'thaw' it.
The reason for using join/unpack and split/pack is that MUSHclient doesn't like zero bytes in the strings, and those are common in nfreeze output. Thus, we first convert all characters in the 'frozen' string to their according numeric ASCII value, then join those numbers to a new string inserting '#' as a separator between them. Later we can split the string, convert the numbers back to their character values and use thaw on the result.
You could use this code to pass the $parsed from the ATCP plugin I've posted earlier to your other plugins through BroadcastPlugin, or CallPlugin or just store it in a MC variable for all to access.
Problem 2:
You want to view the contents of a data structure 'on the fly' (for debugging purposes for example).
Solution:
use Data::Dumper;
sub debugvar {
my $varname = shift;
if (defined $$varname) {
$world->Note("Contents of $varname:");
my $dumped = Data::Dumper->new([$$varname],['var']);
$dumped->Terse(1)->Sortkeys(1);
$world->Note($dumped->Dump());
} else {
$world->Note("$varname is undefined!");
}
}
my $data = {'This' => {'is' => {'a' => [{'weird' => {'data' => {'structure' => ['indeed!']}}}]}}};
debugvar('data');
Explanation:
The Data::Dumper does almost the same what Storable did, but the resulting string will be human-readable. It will look (almost) exactly like it would look, if you defined that structure in your code. It can even be stored to disk or sent somewhere and eval -uated afterwards to get the same structure back (but unless you really want to view or edit it, its better to use Storable in that case). Be aware though, that the actual example will neither handle cross-references, nor any advanced stuff like embedded code. The module itself can do all that, but at a cost of speed. This example will also not display any 'real' hashes or arrays. It only works for strings or references. But just having this bit of code in your main script will allow you to /debugvar(mydata) (if '/' is your configured script prefix) and instanly see the actual contents of $mydata.
For more info and/or ideas, see the documentation for both modules:
http://search.cpan.org/~ams/Storable-2.16/Storable.pm
http://search.cpan.org/~ilyam/Data-Dumper-2.121/Dumper.pm
As mentioned, both are supplied with all core distributions of perl. |