Search code examples
perlclasshashsubroutine

perl, populating a hash from a subroutine call on file input, array input, or no input


I made the class as follows:

package Tool;

sub new {

  my ( $class, %args ) = @ARG;

  my $self = bless {
  #hash reference  
    _ToolParameters => { }

  }, $class;

  return $self;

}

I then want to create an instance of this class:

my $Object = Tool->new();

then, I'd like to read from a textfile or array to populate the hash and call it as follows:

from an array:    $Object->ImportData(\@Arraylist);
from a textfile:  $Object->ImportData(textfile.csv);

in this function ImportData, I would like to read my key from an array list which will strictly be the ID#, or from the CSV file, it'd be strictly the first column that is the ID# or to be able to insert the values manually:

*I want it such that the ID# = the key.

I'm thinking of also generating at least one parameter field for this key by default, and assigning it a default value 0.

Basically when I return from this list I'll have something suggested by ikegami earlier, like:

$self->{_ToolParameters}{$ID#1}{test_parameter_1} = $value;
$self->{_ToolParameters}{$ID#2}{test_parameter_1} = $value;

If I'm accepting an array, the input is as follows:

@Arraylist = (key1 ,..., keyN);

as this is part of a larger program, I plan to run each key through a series of a number of 'X' test-suites, these test suites I plan to give the name "parameterX", X being the number of the test-suite. I take the first test-suite as given, so my desired output should be that in the object, i'd have by default (before pushing on any more parameters):

*the default value for the 'value' is zero, because I have not run the testsuite, I am just initializing the field

key1 -> first_test ->0
key2 -> first_test ->0
.
.
keyN ->     first_test ->            0
(key)  (test_parameter_1)  (value of test_parameter_1)

I want this returned to the object such that I can later pass more tests into the hash, such that for example I can have:

key1 -> first_test -> 0
     -> second_test -> 0

Similarly, from the textfile, all I care about are the columns which represent the keys, or IDs.

I guess my confusion was how to make this assignment reliably such that I have an object that contains a list of expandable valued pairings, but writing this out helped me resolve much of it.

This is where I require some guidance.

sub ImportData{
 my $a = shift;

 if($a eq /*.csv$/i )
{ #textfile case

  my @get_first_col = some kind of column dump; #keys, probably a while loop

  foreach $key (@get_first_col)
  {
  push($self->{_ToolParameters}{$key}{test_parameter_1} = 0);
  }
}
elseif($a)
{ #array case - want to reliably check if we're handling an array
  foreach (@{a})
  {
  push($self->{_ToolParameters}{$_}{test_parameter_1} = 0);
  }
}
else
{#case of manual input
my $a = <STDIN>
push($self->{_ToolParameters}{$_}{test_parameter_1} = 0);
}

}

Solution

  • It's unclear what you want.

    To produce

    {
        key1 => {
            parameter1 => 0,
            parameter2 => 0,
        },
        key2 => {
            parameter1 => 0,
            parameter2 => 1,
        },
    }
    

    given

    my @rows = (
        [ 'key1', 0, 0 ],
        [ 'key2', 0, 1 ],
    );
    

    you want

    $self->{$key}{parameter1} = $parameter;
    $self->{$key}{parameter2} = $parameter2;
    

    or

    $self->{_ToolParameters}{$key}{parameter1} = $parameter;
    $self->{_ToolParameters}{$key}{parameter2} = $parameter2;