Hi.
While developing an upcoming perl monks utility release (xml_pimp)
I went through a gamut ideas, in the midst of which, i thought about generating a temporary file.
I was messing with bunch of new things at the moment, some of which include the printf functions, regexes, inline pod ... ;)
None the less, here is what came out of it. Read it, test it, use it if you like.
++++What I went through to figure out how the generate the filename comes first, and my test script (that actually created and deleted files), comes after that .
#!/usr/bin/perl -w
use strict;
=head1 I MISUNDERSTOOD MY INPUT AND FUNCTION
Apparently sprintf does not provide maximum length for number types,
but only for strings. So in effect i was getting ints wih 8 or 9
digits before the . and the min length was 8, but you can't specify
max length.
Live and learn, and then make an ass out of yourself (almost) ;-^)~
I ended up making sure my input was an integer, and then treating
it as a string with max and min length specified.
Basically i feed it to sprintf twice
=cut
=head1 SPRINTF NOT PADDING CORRECTLY (original question)
print sprintf(".crazy.%010u.temp",rand(time)),"\n";
print sprintf(".crazy.%08.8s.temp",rand(time)),"\n";
Its' fine if i use string, but it's supposed to be minimum length for
+ int
but it doesn't pad with d (signed int), or with u (unsigned int).
unless it's the length is 9 or greater.
Is this flaw, or what?
If i use 8, some numbers don't get padded.
If i use 9 or greater, they do.
I don't think this has to do with my specific version of perl,
which is ActiveState 5.6(build 623) btw.
Why, cause perldoc:pelrfunc says:
Perl does its own sprintf formatting--it emulates the C function spri
+ntf,
but it doesn't use it (except for floating-point numbers, and even th
+en
only the standard modifiers are allowed). As a result, any non-standa
+rd
extensions in your local sprintf are not available from Perl.
And since i'm not trying to represent a floating point number (i want
+ int),
it should make no difference(not that it would anyway).
Also, I do not wish to use %08s (for string), because sometimes a . s
+neaks
in, which is because rand(time) outputs a positive float that looks l
+ike
BTW - rand(time) yields results like:
598318636.889648
52034455.75
52445775.5732422
However, it hardly yields a value less than 8 digits digits bef
+ore
the decimal, but that's besides the point.
BTW - srand is called automatically in my version of perl, so i
don't call it explicitly cause it makes my results duplicates 1
+/3 of
the time.
=cut
for(0..99)
{
print ' rand( ', rand(time),"\n";
}
=head1 WHAT I TRIED
=pod
Here come the un-signed integer examples.
sprintf(".crazy.%08u.temp" ,rand(time)) # min length 8, padd w/0
sprintf(".crazy.%08.8u.temp" ,rand(time)) # min length 8 or 8, padd w
+/0
sprintf(".crazy.%010u.temp" ,rand(time)) # min length 10, padd w/0
sprintf(".crazy.%0.8u.temp" ,rand(time)) # not actually sure
It's either padd with 0 w/min length of 8, or
BTW - rand(time) yields results like:
598318636.889648
52445775.5732422
=head1 MY SOLUTION
sprintf(".crazy.%08.8s.temp", sprintf("%u",rand(time)) );
Feed sprintf an unsigned int, and then feed that unsigned int
to a sprintf with 0 for padding and a string of max length 8
and min length 8 (you gotta specify both to get a fixed width)
or
sprintf(".crazy.%08.8s.temp", int(rand(time)) );
It's a little bit faster, cause it uses int, but it's the same shit.
=cut
print &_titled_hr(' sprintf(".crazy.%010.10s.temp", sprintf("%u",rand(
+time))) ');
for(0..99)
{
print ' %010.10s(',
sprintf(".crazy.%010.10s.temp", sprintf("%u",rand(time))),
"\n";
}
print &_titled_hr(' sprintf(".crazy.%010.10s.temp",rand(time)) ');
for(0..99)
{
print ' %010.10s(',
sprintf(".crazy.%010.10s.temp", int( rand(time) ) ),
"\n";
}
print &_titled_hr(' sprintf(".crazy.%08u.temp",rand(time)) ');
for(0..99)
{
print ' %08u(', sprintf(".crazy.%08u.temp",rand(time)),"\n";
}
print &_titled_hr(' sprintf(".crazy.%0.8u.temp",rand(time)) ');
for(0..99)
{
print ' %0.8u(', sprintf(".crazy.%0.8u.temp",rand(time)),"\n";
}
print &_titled_hr(' sprintf(".crazy.%08.8u.temp",rand(time)) ');
for(0..99)
{
print ' %08.8u(', sprintf(".crazy.%08.8u.temp",rand(time)),"\n";
}
print &_titled_hr(' sprintf(".crazy.%010u.temp",rand(time)) ');
for(0..99)
{
print ' %010u(', sprintf(".crazy.%010u.temp",rand(time)),"\n";
}
=pod
Here come the signed integer examples.
sprintf(".crazy.%08d.temp" , rand(time)))
sprintf(".crazy.%0.8d.temp" , rand(time)))
sprintf(".crazy.%08.8d.temp" , rand(time)))
sprintf(".crazy.%010d.temp" , rand(time)))
BTW - rand(time) always yields positive floats.
=cut
print &_titled_hr(' sprintf(".crazy.%08d.temp",rand(time)) ');
for(0..99)
{
print ' %08d(', sprintf(".crazy.%08d.temp",rand(time)), "\n";
}
print &_titled_hr(' sprintf(".crazy.%0.8d.temp",rand(time)) ');
for(0..99)
{
print ' %0.8d(', sprintf(".crazy.%0.8d.temp",rand(time)), "\n";
}
print &_titled_hr(' sprintf(".crazy.%08.8d.temp",rand(time)) ');
for(0..99)
{
print ' %08.8d(', sprintf(".crazy.%08.8d.temp",rand(time)), "\n"
+;
}
print &_titled_hr(' sprintf(".crazy.%010d.temp",rand(time)) ');
for(0..99)
{
print ' %010d(', sprintf(".crazy.%010d.temp",rand(time)), "\n";
}
exit;
sub _titled_hr
{
my $string= join('', @_);
my $oy = int (80 -(length $string) )/ 2;
$oy -=2;
return "\n ","-" x $oy, $string, "-" x $oy," \n";
};
######################################################################
+########
## END OF SCRIPT
__END__
Here is the test code, for what i was attempting (very messy)
#!/usr/bin/perl -w
use strict;
use Compress::Zlib;
my $userfile = '.crazyinsomniac.nodes.hashoaray.dat';
my $tempout = sprintf(".crazy.%010.10s.temp", int(rand(time)) );
for(0..10)
{
&testshit;
&cleanup_file;
}
sub testshit
{
&compressor();
for(0..100)
{
$tempout = sprintf(".crazy.%010.10s.temp", int(rand(time)) );
&decompressor();
}
}
sub cleanup_file
{
unlink $tempout if -e $tempout;
opendir(DIN,'.') or die "can't opendir . ($!)\n";
my @files = grep {/^.crazy.(\d){10}.temp$/} readdir(DIN);
print "trying to delete(",scalar(@files),"):\n", join "\n", @files
+,"\n";
print 'successfully deleted ',(unlink @files)," files \n";
}
sub decompressor
{
my $x = inflateInit() or die "Cannot create a inflation stream\n";
my ($output, $status,$input);
open(FIN , "<".$userfile.'.gz') or die "can't open $userfile($!)\n
+";
open(FOUT, ">".$tempout) or die "can't open $tempout.gz($!)\n";
binmode FIN;
binmode FOUT;
while (read(FIN, $input, 4096))
{
($output, $status) = $x->inflate(\$input) ;
if( ( $status == Z_OK ) or ( $status == Z_STREAM_END ) )
{
print FOUT $output;
}
last if $status != Z_OK ;
}
close(FIN);
close(FOUT);
#unlink $tempout; # you will be deleted
# since we don't wanna die before deleting this
die "inflation failed\n" unless $status == Z_STREAM_END ;
}
sub compressor
{
open(FIN , "<".$userfile) or die "can't open $userfile($!)\n";
open(FOUT, ">".$userfile.'.gz') or die "can't open $userfile.gz($
+!)\n";
binmode FIN;
binmode FOUT;
my $deflation_stream = deflateInit() or die "Cannot create a defla
+tion stream\n";
while (read(FIN, $_, 4096))
{
my ($output, $status) = $deflation_stream->deflate($_);
$status == Z_OK or die "deflation failed\n";
print FOUT $output ;
}
my ($output, $status) = $deflation_stream->flush();
$status == Z_OK or die "deflation failed\n";
print FOUT $output ;
}
sub sprinter
{
for(0..1000)
{
print sprintf(".crazyinsomniac.%010u.xml_pimp.tpl",rand(time))
+,"\n";
# print sprintf(".crazyinsomniac.%08.8s.xml_pimp.tpl",rand(tim
+e)),"\n";
# its' fine if i use string, but it's supposed to be minimum l
+ength for int
# but it doesn't pad with d (signed int), but it does with u.
# unless it's 9 or > (cause input is always 8 or less)
# is this flaw, or what?
# this is really fucked up. If i use 8, some strings don't ge
+t padded
# if i use 9 or greater, they do
}
}
___crazyinsomniac_______________________________________
Disclaimer: Don't blame. It came from inside the void
perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;" |