ahackney has asked for the wisdom of the Perl Monks concerning the following question:
Hello Monks!
I'm new to OO in Perl. I have a class that I have created. In this class, I need an attribute that is a hash whose members contain an array.
I have gotten the hash to work, but making the contents of the hash an array is a mystery to me.
I'm wondering if I need another class that this class will have as an attribute?
sub new {
my $class = shift;
my $self = {
coreID => 0,
isBpMaskError => 0,
isVrrpErrors => 0,
isSymPriorityErrors => 0,
isSslProfileErrors => 0,
isGlobalPortErrors => 0,
isVipsinVipGroupsErrors => 0,
isVipGroupErrors => 0,
isSnatIpErrors => 0,
isCodeVersionErrors => 0,
aclsMissingFromMaster => {},
};
bless $self, $class;
return $self;
}
I want the aclsMissingFromMaster hash to contain an array. Should I just make a class ACLS with attributes being arrays and make that class object an attribute of this class? Or is there a way to make the above class contain a hash containing arrays.
eg:
I am trying to make the following hash an attribute of the above class.
%hash1{'list1'}-> [1,2,3,4]
%hash1{'list2'}-> [4,5,6,7]
...
Thanks for your wisdom!
Re: OO Design Question with Hashes of Arrays
by kcott (Archbishop) on Jun 26, 2013 at 02:38 UTC
|
G'day ahackney,
Welcome to the monastery.
"... making the contents of the hash an array is a mystery to me."
A hash contains pairs of keys and values. While the contents of a hash could be considered as an array with an even number of elements, I'm guessing that's not really what you're driving at. Take a look at perlintro - Perl variable types for an overview and follow the links therein for more detailed discussion.
"I am trying to make the following hash an attribute of the above class."
Given the example data you've shown, I imagine you want to end up with something along these lines:
my $self = {
...
aclsMissingFromMaster => {
list1 => [1, 2, 3, 4],
list2 => [5, 6, 7, 8],
...
},
};
Take a look at Perl Data Structures Cook Book - HASHES OF ARRAYS to understand this data structure and how it can be created, accessed and manipulated.
You haven't provided sufficient information to advise whether a separate class for ACLs would be appropriate. If this is the only place you're handling ACLs, then maybe not; however, if you'll be working with ACLs in other classes (or as stand-alone objects), then it probably would be a good idea.
As you appear to be at the design (or, at least, very early development) stage, I'd recommend you consider Moose (or one of its relatives, e.g. Mouse, Moo) rather than coding your constructors from scratch and dealing with all the issues that arise from that course of action. The Moose DESCRIPTION starts off:
Moose is an extension of the Perl 5 object system.
The main goal of Moose is to make Perl 5 Object Oriented programming easier, more consistent, and less tedious. With Moose you can think more about what you want to do and less about the mechanics of OOP.
| [reply] [d/l] |
Re: OO Design Question with Hashes of Arrays
by Anonymous Monk on Jun 26, 2013 at 04:04 UTC
|
Hi ahackney,
While, I advise that you take vantage of the wisdom and words of kcott, I will say it's not bad to 'eat' on the boilerplate of perl OO intrinsic design.
..I am trying to make the following hash an attribute of the above class...
You could write subroutine, to 'set' and 'get', the value of the hash attribute like this:
{
package My::Sys;
sub new {
my $class = shift;
my $self = {
coreID => 0,
isBpMaskError => 0,
isVrrpErrors => 0,
isSymPriorityErrors => 0,
isSslProfileErrors => 0,
isGlobalPortErrors => 0,
isVipsinVipGroupsErrors => 0,
isVipGroupErrors => 0,
isSnatIpErrors => 0,
isCodeVersionErrors => 0,
aclsMissingFromMaster => {},
};
bless $self, $class;
return $self;
}
sub set_acls{
my $self = shift;
my $cot = 0;
$self->{aclsMissingFromMaster}{"list ".++$cot} = $_ for @_;
}
sub get_acls{
my $self = shift;
return $self->{aclsMissingFromMaster};
}
}
use Data::Dumper;
my $sys = My::Sys->new();
my @arr = ([1..4],[5..8],);
# set the attribute
$sys->set_acls(@arr);
{
local $Data::Dumper::Sortkeys = 1;
# get your values here
print Dumper $sys->get_acls();
}
..you get...
$VAR1 = {
'list 1' => [
1,
2,
3,
4
],
'list 2' => [
5,
6,
7,
8
]
};
Just an example for you to see... You might want to check some other documentation like perlobj, perlootut.
| [reply] [d/l] [select] |
|
Thanks for the input everyone. I do understand (somewhat) hashes of arrays data structure.
I have looked into moose and others as suggested. My needs are so small at this point (I'm almost done) that I think I'm going to keep hacking away at the base perl system.
Anonymous Monk, thank you so much. This was just what I needed and it works exactly as you demonstrated. I am ignorant of some of the syntax that you used and I was wondering if you could point me to an article that explains the syntax usage? I googled and could not find anyone using the syntax quite this way in my searches.
Specifically...
= $_ for @_;
I'm guessing this is shorthand for a for loop, but, again, my searches have been fruitless and the man pages have not been helpful.
Thank you again monks for the assistance!
| [reply] [d/l] |
|
... an article that explains the syntax usage ...
= $_ for @_;
I'm guessing this is shorthand for a for loop ...
This is the statement modifier form of a for-loop. It iterates over the elements of a LIST and 'topicalizes' (or aliases with localization) the default scalar $_ (see perlvar) to each element in turn. Because $_ is aliased, elements of an array can be altered "in place", which can be very helpful, even essential, in dealing with large arrays.
>perl -wMstrict -le
"$_ = 'same as it ever was';
;;
my @ra = (1, 2, 3, 4);
;;
$_ = $_ + 990 for @ra;
print qq{@ra};
;;
print 880 + $_ for 1, 2, 3, 4;
;;
print $_;
"
991 992 993 994
881
882
883
884
same as it ever was
(For some insight into the difference between a list and an array, try executing the statement
$_ = $_ + 990 for 1, 2, 3, 4;
instead.)
| [reply] [d/l] [select] |
Re: OO Design Question with Hashes of Arrays
by Loops (Curate) on Jun 26, 2013 at 01:57 UTC
|
Is this what you're looking for?
aclsMissingFromMaster => { list1 => [1,2,3,4], list2 => [4,5,6,7] },
| [reply] [d/l] |
|
|