in reply to Re: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
in thread Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use

I initially tried a hash and got the same type of error. I then rewrote the code to work with tables and it still did not work. I would rather use hashes. Can someone please show me why I am getting the error and hopefully the syntax to correct it. If I ignore the error then the hash table has the incorrect entries. The error I received was: Can't use string ("Wed") as a HASH ref while "strict refs" in use at test3.pl line 51, My input file was:

lmutil - Copyright (c) 1989-2009 Flexera Software, Inc. All Rights Res +erved. Flexible License Manager status on Wed 1/2/2019 07:00 [Detecting lmgrd processes...] License server status: 27000@unodecx80 License file(s) on unodecx80: E:\Program Files (x86)\IBM\RationalR +LKS\common\rational_server_perm.dat:E:\Program Files (x86)\IBM\Ration +alRLKS\common\rational_server_temp.dat: unodecx80: license server UP (MASTER) v11.10 Vendor daemon status (on unodecx80): ibmratl: UP v11.10 Feature usage info: Users of ClearCase: (Total of 10 licenses issued; Total of 1 license + in use) "ClearCase" v1.00000, vendor: rational floating license amlove unodecx86 WI_zfTVVG-n7Ph2jhkOo #u#amlove#u# (v1.0) (unodecx +80/27000 615), start Wed 1/2 6:56 (linger: 1800) Users of ADALangPack: (Total of 1 license issued; Total of 0 license +s in use) The following was my code: #!/usr/bin/perl use strict; use warnings; my $mydebug1=1; my $val="X"; my $k1=""; my $k2=""; my $k3=""; my $k4=""; my %metrics = (); my $sysacc=""; my $origsys=""; my $product=""; my $day=""; my $date=""; my $hour=""; my $skip=1; my $user=""; my $dum1=""; my $dum2=""; my $dum3=""; my $dum4=""; my $dum5=""; my $dum6=""; my $dum7=""; my $cnt=0; my $found=0; my $checkval="Users of"; my $str = ""; open (LICIN, "<C:\\SCCI\\scci_clearcase\\All_license_info_Jan2019_samp +le\.txt"); while ($str = <LICIN>) { chomp $str; if ($str =~ /^Flexible License/) { ($dum1,$dum2,$dum3,$dum4,$dum5,$day,$date,$dum6) = split(/ /,$ +str,8); ($hour,$dum1) = split(/:/,$dum6,2); next; } if ($str =~ /$checkval/) { if ($str =~ /Users of ClearCase/) { $str = <LICIN>; $str = <LICIN>; $str = <LICIN>; $str = <LICIN>; while ($str = <LICIN>) { chomp $str; last if ($str eq ""); $str =~ s/^\s+//; ($user,$sysacc,$origsys,$dum1) = split(/ /,$str,4); $product="ClearCase"; $metrics{$product}{$date} = $day; $metrics{$product}{$date}{$hour}{$user} = $val; } } next; } } # # print hash table # if ($mydebug1) { for $k1 (keys (%metrics)) { print "k1 = $k1 \n"; for $k2 (keys(%{ $metrics{$k1} })) { print "k2 = $k2 \n"; for $k3 (keys(%{ $metrics{$k1}{$k2} })) { print "k3 = $k3 \n"; for $k4 (keys(%{ $metrics{$k1}{$k2}{$k3} })) { print "k4 = $k4 \t k4val = $metrics{$k1}{$k2}{$k3} +{$k4}\n"; } } } } }
  • Comment on Re^2: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
  • Download Code

Replies are listed 'Best First'.
Re^3: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
by hippo (Archbishop) on Feb 28, 2019 at 14:25 UTC

    Lines 50 and 51 are:

    $metrics{$product}{$date} = $day; $metrics{$product}{$date}{$hour}{$user} = $val;

    So, on line 50 you set $metrics{$product}{$date} to be a scalar and then on line 51 you try to treat it as a hash ref. That's incompatible.

Re^3: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
by pryrt (Abbot) on Feb 28, 2019 at 14:25 UTC

    Following #2 in Basic debugging checklist, I would recommend printing out the hash after every time you assign to a key or subkey of your %metrics hash. Because it's a complex structure, use Data::Dumper, as:

    use Data::Dumper; ... # after some assignment like $metrics{$product}{$date} = $day; print STDERR Dumper \%metrics; $metrics{$product}{$date}{$hour}{$user} = $val; print STDERR Dumper \%metrics;

    as a one liner, with hardcoded values, for the first assignment and print:

    C:\usr\local\share\PassThru\perl>perl -MData::Dumper -le "$metrics{pro +duct}{today} = 'Wed'; print STDERR Dumper \%metrics" $VAR1 = { 'product' => { 'today' => 'Wed' } };

    You might then notice that at the first print, the value of the 'today' key is a string, 'Wed', and not another { nested => hash }. With a string as the value of {today}, you cannot take another subkey (like {today}{12}), because strings don't have subkeys. I think you need to rethink your data structure. Maybe show us in the Data::Dumper-like notation printed above, what you do want your data to look like when you're done, and we can help you organize your data into that format.

Re^3: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
by poj (Abbot) on Feb 28, 2019 at 14:26 UTC

    If you want to build the hash

    $metrics{$product}{$date}{$hour}{$user} = $val;

    Then $metrics{$product}{$date} has to be a hash reference. It can't be used the store the day. If you need to store the day use a separate hash

    $calendar{$date} = $day;
    poj
Re^3: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
by NetWallah (Canon) on Mar 01, 2019 at 00:26 UTC
    Here is some working code.

    Pretty printing is left as an exercise:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %lic_info; my $pending_product=""; my $pending_user_count=0; my %actions=( "Flexible License Manager" => sub{ @lic_info{qw|DAY DATE TIME|} = $_[0]=~/ on (\w+) (\S+) (\S+)$ +/; }, "Users of " => sub{ my ($product,$issued, $usecount) = $_[0]=~/Users of (\w+): \( +Total of (\d+) license\w? issued; Total of (\d+) lic/; $lic_info{$product}{ISSUED}= $issued; $pending_user_count = $lic_info{$product}{USED}= $usecount; $pending_product = $product; }, ); my $regex = "(" . join ("|", keys %actions) . ")"; while (<DATA>){ if ( m/$regex/ ){ $actions{$1}->($_); # Where the work happens }elsif ($pending_product){ next if m/^\s+$/; next if m/floating license/; next if m/\s*\S?$pending_product/; push @{$lic_info{$pending_product}{USERS}}, m/(\S+)/; --$pending_user_count or $pending_product = ""; } } print Dumper \%lic_info; __DATA__ lmutil - Copyright (c) 1989-2009 Flexera Software, Inc. All Rights Res +erved. Flexible License Manager status on Wed 1/2/2019 07:00 [Detecting lmgrd processes...] License server status: 27000@unodecx80 License file(s) on unodecx80: E:\Program Files (x86)\IBM\RationalR +LKS\common\rational_server_perm.dat:E:\Program Files (x86)\IBM\Ration +alRLKS\common\rational_server_temp.dat: unodecx80: license server UP (MASTER) v11.10 Vendor daemon status (on unodecx80): ibmratl: UP v11.10 Feature usage info: Users of ClearCase: (Total of 10 licenses issued; Total of 1 license + in use) "ClearCase" v1.00000, vendor: rational floating license amlove unodecx86 WI_zfTVVG-n7Ph2jhkOo #u#amlove#u# (v1.0) (unodecx +80/27000 615), start Wed 1/2 6:56 (linger: 1800) Users of ADALangPack: (Total of 1 license issued; Total of 0 license +s in use)
    OUTPUT:
    $VAR1 = { 'ClearCase' => { 'USED' => '1', 'USERS' => [ 'amlove' ], 'ISSUED' => '10' }, 'ADALangPack' => { 'ISSUED' => '1', 'USED' => '0' }, 'DATE' => '1/2/2019', 'DAY' => 'Wed', 'TIME' => '07:00' };

    Update: FYI/FWIW - I was a ClearCase admin in a previous job, decades ago, and I sympathize. That was what taught me perl - so good luck !

                    As a computer, I find your faith in technology amusing.

Re^3: Why am I getting Can't use string (<string value>) as an ARRAY ref wile "strict refs" in use
by bliako (Abbot) on Mar 02, 2019 at 01:05 UTC

    I am tempted to try some code but I think it will save us all some time if you present your data. Not as a file, but as how you see it being parsed from a file-line to a data structure. In pseudo/abstract-code. Then, along with you, we can see if a hash is a good idea. It seems to me that you thought about how you want your data structure to be but you have some difficulty in doing it in Perl. So talk abstract if you have too.