CDaly CDaly - 2 months ago 8
Perl Question

How to return the correct object attribute in perl?

I have a package I created that is meant to return the object's specified attribute (shortened code)

package vendor_info;

my $vars;
sub new{
my $class = shift;
$vars = {
_servers => shift,
_locations => shift,
_favorite => shift,
_default_selection => shift,
_database => shift,
_DB => shift};

bless $vars, $class;
return $vars;
}
sub get_locations{
return $vars->{_locations};
}

sub get_database{
return $vars->{_database};
}
sub get_DB{
return $vars->{_DB};
}


My perl file receives an input parsed from the terminal but in this case, the variable $vendor is hard coded for testing. I have a list of objects in a hash, and I want to return the correct attribute according to the object. Some of the variables have been removed with placeholders.

$vendor = "atrena";

my %vendor_hash = (
"atrena" => new vendor_info("Variable_server","Variable_location","Advanced_CDC|CDC dftso|DFT|gui|GUI|adv_checker|Lint|spl-view-only|view-only-GUI","adv_checker","database","DB"),

"ansys" => new vendor_info("Variable","Location","agppi|agppi|ane3fl|ane3fl|ansys|ansys|ensemble_gui|ensemble_gui|hfss_desktop|hfss_desktop|hfss_gui|hfss_gui|hfss_solve|hfss_solve|hfsshpc_pack|hfsshpc_pack|optimetrics|optimetrics|q3d_desktop|q3d_desktop|rdacis|rdacis|struct|struct","ane3fl","database", "db"),

"coventor" => new vendor_info("var","location","COV_ZsplatViewer|Viewer|COV_VoxelModeler|Voxel-Modeler|MEMSp_Import_Package|Import-Package|MEMSp_Innovator_Plugin|Innovator-Plugin|MEMSp_MATLAB_Simulation|MATLAB-Simulation|MEMSp_Platform|Platform|MTI_AutoBuilder|Auto-Builder|MTI_Catapult|Catapult|MTI_CoventorWare|Coventor-Ware|MTI_Memcap|Memcap|MTI_PreProcessor|PreProcessor","database","db","db")

);

$vendor_object = $vendor_hash{$vendor};

print Dumper( $vendor_object);

$foodb = $vendor_object -> get_database();


The dumper is printing the correct information, however, when I call get_database(), the database called is always the attribute from the last object in the list, which in this case is coventor. The same could be said for any of the sub routine getters.

How do I call the correct attribute for the correct object?

Answer

You have $vars as a lexical variable which is scoped to the file which contains your package. So there is only one instance of this variable and it will always contain the data for the last object that was set up.

I'm not sure where you picked up that approach, but it's not how Perl objects work at all. $vars should be scoped to only exist within your constructor and your accessors should be using the object that is passed to them as their first argument (traditionally called $self).

# Only pragmas should start with lower-case letters
package VendorInfo;

sub new{
    my $class = shift;
    my $vars = {
        _servers => shift,
        _locations => shift,
        _favorite => shift,
        _default_selection => shift,
        _database => shift,
        _DB => shift
    };

    return bless $vars, $class;
}

# Just one example accessor...
sub get_database{
    my $self = shift;
    return $self->{_database};
}

One more point, please use Class->new() instead of the potentially problematic new Class syntax that you are using in your code.

Comments