I'll start from the beginning because I don't think I'll
make much sense otherwise.
Okay, the basic idea is that, with so many values being
returned (3 is usually too many in my book), remembering
the exact order of the values is problematic. Also, if
you are returning a whole list of things, it'd be nice to
design the interface so it can evolve in an intelligent
manner.
So, just like when you have lots of parameters, it is nice
to "name" them (func(This=>"that",Count=>2)),
you can return "named" values by returning a hash. I try
to avoid returning hashes as lists so let's return a reference
to a hash.
One of the nice things about named parameters is that you
can leave out any parameters that you aren't interested in.
So let's allow the user the same option here. If they only
want page file information in megabytes, they can write:
my( $avail, $total )= MemoryStatus( "MB",
"AvailPageFile", "TotalPageFile" );
The "MB" parameter is optional and we can detect it due to
it being different from any of the field names. If you think
you may further extend the interface in the future, you
might want to make this distinction clearer and allow for
extra arguments by having the field names passed as an
array reference:
my( $avail, $total )= MemoryStatus( "MB",
[ "AvailPageFile", "TotalPageFile" ] );
but I don't think that is warranted in this case.
If the user wants all or most of the items, then they use
it like this:
my $hMem= MemoryStatus( "K" );
my $load= $hMem->{MemoryLoad};
This is particularly handy for add-hoc queries in the Perl
debugger:
perl -de 0
DB<1> use Win32::MemoryInfo "MemoryStatus"
DB<2> x MemoryStatus()
0 HASH(0x1df2628)
'AvailPageFile' => 3026
'TotalPageFile' => 32768
[...]
And Perl makes this easy to code as well:
my @fieldNames=
qw( MemoryLoad TotalPhys AvailPhys TotalPageFile
AvailPageFile TotalVirtual AvailVirtual );
my %unitSize= ( B=>1, K=>1024, M=>1024*1024, G=>1024*1024*1024 );
#[...]
my( $sUnits )= "B";
if( @_ && $_[0] =~ /^[BKMG]B?$/i ) {
$sUnits= uc substr(shift(@_),0,1);
}
my( $nUnits )= $unitSize{$sUnits};
my( $dwMSLength )= 0;
my( @fieldValues )= (0)x@fieldNames;
my $MEMORYSTATUS= pack "L8", $dwMSLength, @fieldValues;
$GlobalMemoryStatus->Call($MEMORYSTATUS);
( $dwMSLength, @fieldValues )=
unpack "L8", $MEMORYSTATUS;
return if 0 == $dwMSLength;
for( @fieldValues ) {
$_ /= $nUnits;
}
my $hFields= {};
@$hFields{@fieldNames}= @fieldValues;
return @_ ? @$hFields{@_} : $hFields;
-
tye
(but my friends call me "Tye") |