Tie::Array::PackedC - Tie a Perl array to a C-style array (packed; elements of a single, simple data type)
use Tie::Array::PackedC qw(packed_array packed_array_string); my $ref=packed_array(1,2,3,4); my $ref2=packed_array_string(my $s,1,2,3,4); use Tie::Array::PackedC Double=>'d'; tie my @array,'Tie::Array::PackedC::Double',1..10; $array=1.141;
Provides a perl array interface into a string containing a C style array. In other words the string is equivelent to the string that would be returned from the equivelent pack command (defaulting to pack type "l!") using a normal array of the same values. Eg:
my @foo=(1..10); my $string=pack "l!*",@foo;
leaves $string in basically the same condition as
my (@foo,$string); tie @foo,'Tie::Array::PackedC',$string,1..10;
Its only basically the same and not exactly the same because the tie version may be longer due to preallocation.
The basic usage is
This will tie @array to $string. So modifying the array will actually cause the string to change. If $string is undef then it will automatically be set to "", otherwise the initial contents of the string will be untouched. (It will however be extended according to the preallocation below.) Any values @initialize are treated as though an immediate
occured. This means that
my ($s,@a)=pack "l!*",1..5; tie @a,'Tie::Array::PackedC',$s,reverse 1..4;
wil result in "@a" being "4 3 2 1 5".
If no $string is provided then an anonymous string is used to bind to. This string can be obtained by saying
Note that the underlying object is a blessed reference to the string passed in. The difference between saying
and the string method is that the former will return the string by copy and it will be exactly the size of the array, the latter could be signifigantly longer due to preallocation.
There is also a utility method to dump the string/array in hex that is invoked accordingly
this dumps the full underlying string in hex bytes grouped according to the size of the packed element, and is in the byte order as packed.
A normal array returns undef when you access an element that has not been explicitly stored to. Arrays tied using this class do not behave in the same way. If an index is within the size of the array but has not been assigned to will return Tie::Array::PackedC::NULL a constant defined as the result of
Any index that is outside of the array will return undef as expected.
In order to avoid having to extend the string too often a preallocation strategy is used. This means that the underlying string is prefilled with a predetermined number of items worth of NULL each time a STORE accesses an element not currently mappable to the string. This allocation happens in terms of blocks which are of a size equal to a predetermined multiple of the size of each element. The number elements added each time the array is extended will be a multiple of the block size and will not be less than %20 of the current size.
NOTE I currently consider the preallocation mechanism to be less than it should be and will most likely figure out a better way to do it later. Please do not assume that the preallocation mechanism will stay the same.
The class uses a form of templating to provide a way to produce classes that are just as fast as the current version, but use different pack formats, or allocation block size. This is done at compile time by a special import mechanism. This mechanism works like this:
use Tie::Array::PackedC %Name% => %PackType%;
Where %Name% must match /[A-Z]/ and %PackType% is one of the pack formats. (The behaviour of the class is only well defined for types that are of fixed size that are byte aligned.)
If the module is used as follows
use Tie::Array::PackedC Double => 'd';
then a new class called
Tie::Array::PackedC::Double is created that produces a tied array of packed doubles. Thus the default implementation and usage
is almost exactly equivelent to
use Tie::Array::PackedC NativeLong => 'l!';
with the exceptions being its name and its import behaviour, the later of which is different in that it does not support the class factory import.
Returns the string represnting the array. This is not necessarily the same as the string passed into the array, which may be longer.
Prints to STDOUT a hex dump of the underlying string.
Frees up any preallocated but unused memory. This is useful if you know you will not be performing any more store operations on the string.
The base package and each of the children it produces in factory mode have the following constants defined, (adjust name accordingly)
Returns the pack format used by the class. This will always have a * at the end, regardless as to what was provided by the user.
The number of bytes that a single element of PACK takes up.
Used by the preallocation system to determine chunk size of preallocation. Currently the underlying string will always satisfy
length($string) % Tie::Array::PackedC::ALLOC == 0
These are not exportable, but they can be accessed by fully qualified name.
Normally Tie::Array::PackedC and its produced classes do not export. However two utility subroutines are provided which can be exported on request using the conventional syntax.
Note that the class factory approach can not be mixed with the export approach in the same use statement. However this means that you can do this:
use Tie::Array::PackedC Double => 'd'; use Tie::Array::PackedC::Double qw(packed_array);
and have the generated class export its utility subs.
Returns a reference to an array tied to an anonymous string. The LIST is used to initialize the array.
Returns a reference to an array tied to a string provided. The LIST is used to initialize the array.
demerphq, (yves at cpan dot org).
Released under the same terms as perl itself.