teamassociated has asked for the wisdom of the Perl Monks concerning the following question:

Been trying to figure out why this code is not storing my sprintf output. Please help! Thx!!!
use strict; use warnings; $lsmapFH = new FileHandle "/usr/ios/cli/ioscli lsmap -vadapter $option +s[4] |" or die $!; while (<$lsmapFH>) { if (/no virtual device found/i) { warn "\n\nThis vhost $options[4] has no clients using me, tr +y again with a correct vhost #!\n\n"; die $!; } chomp; $vh = (split)[0] if /^vhost/i; $clid = (split)[2] if /^vhost/i; $cltid = sprintf "%d", $clid; } $lsmapHash{$vh} = { 'clientID' => $cltid, }; } use Data::Dumper; print Dumper \%lsmapHash; $VAR1 = { 'vhost10' => { 'clientID' => '0' } works fine in CLI: # perl -le '$clid=0x0000000a; $cltid= sprintf "%d", $clid; print $clti +d;' 10 __SAMPLE_OUTPUT__ from lsmap SVSA Physloc Client Pa +rtition ID --------------- -------------------------------------------- --------- +--------- vhost10 U9117.MMD.218A8B7-V1-C2 0x0000000b VTD vtscsi25 Status Available LUN 0x8100000000000000 Backing device l02duapXXXX_r1.58ff94782d7c325acc49a8dd9c04bb1e Physloc Mirrored N/A VTD vtscsi26 Status Available LUN 0x8200000000000000 Backing device l02duapofdev_b1.0ee86903d4951ce38a9b691b322ff1d2 Physloc Mirrored N/A

Replies are listed 'Best First'.
Re: sprintf to hash
by toolic (Bishop) on Sep 19, 2014 at 18:58 UTC
    Use hex and I think you need to re-work your logic...
    use warnings; use strict; my %lsmapHash; while (<DATA>) { chomp; if (/^vhost/i) { my $vh = (split)[0]; my $clid = (split)[2]; my $cltid = sprintf '%d', hex $clid; $lsmapHash{$vh} = { 'clientID' => $cltid, }; } } use Data::Dumper; $Data::Dumper::Sortkeys=1; print Dumper(\%lsmapHash) +; __DATA__ SVSA Physloc Client Pa +rtition ID --------------- -------------------------------------------- --------- +--------- vhost10 U9117.MMD.218A8B7-V1-C2 0x0000000b VTD vtscsi25 Status Available LUN 0x8100000000000000 Backing device l02duapXXXX_r1.58ff94782d7c325acc49a8dd9c04bb1e Physloc Mirrored N/A VTD vtscsi26 Status Available LUN 0x8200000000000000 Backing device l02duapofdev_b1.0ee86903d4951ce38a9b691b322ff1d2 Physloc Mirrored N/A
Re: sprintf to hash
by ikegami (Patriarch) on Sep 19, 2014 at 18:54 UTC

    You want hex($clid).

    sprintf "%d" doesn't convert something that isn't a number into a number. In fact, it does the opposite. It converts numbers into their string representation.

    Your test snippet is not equivalent because 0x0000000b doesn't produce the string 0x0000000b which you have in your actual code.

    $ perl -wE'say sprintf "%d", "0x0000000b"' Argument "0x0000000b" isn't numeric in sprintf at -e line 1. 0

    Why didn't you mention you were getting an error message?

Re: sprintf to hash
by RonW (Parson) on Sep 19, 2014 at 23:02 UTC

    Yes, you do need to use hex to explicitly convert a string containing a hexadecimal value.

    This is because while the Perl parser can safely infer that the bare word 0x000a is a numeric constant expressed in hexadecimal because this is an established syntactic rule of the Perl language. However, Perl's run time string-to-number coercion doesn't make assumptions about a string not matching /^[0-9]/ because a string is just a string.

    Perl also has oct to handle octal values.

    However, there there is an important differnece between hex and oct. hex will only try to interpret the string as hexadecimal, skipping a leading '0x' if present. oct, on the other hand, if the string has a leading '0x' (or '0b'), will try to interpret the string as hexadecimal (or binary). Otherwise, it will try octal.

    Using oct, you can create a simple, dumb converter that will handle decimal, hexadecimal and binary string to number conversion:

    sub dhob2num { my $s = shift; if ($s =~ /^0/) { return oct($s); } # Note: should validate the stri +ng return ( 0 + $s ); }

    While flexible and useful, this function is dumb because it doesn't validate the string to insure it is a proper number in the radix indicated by the prefix.