Ok, I post part of my code in order to be more explicit:
#!/usr/bin/perl -w
use strict;
use Storable;
use User;
use Node;
use Hostgroup;
use Fcntl qw

DEFAULT :flock);
use Term::ANSIColor qw

constants);
my $nodes = {};
my $hostgroups = {};
.....blablabla.....
addHostgroup();
.....blablabla.....
sub addHostgroup {
my $end = 0;
header();
print "--- ADD HOSTGROUPS---------------------------\n";
do {
my $hostgroupCreated = 0;
my $choice = undef;
my $name = getText("hostgroup name");
my $hostgroup = Hostgroup->new(NAME=>$name);
$hostgroup = addNodes($hostgroup);
$end = 0;
do {
print "---REVIEW-------------------------\n";
print "[1] name: ".$hostgroup->name()."\n";
print "[2] Nodes: ".$hostgroup->printNodesName()."\n";
print "[3] save hostgroup and go to main menu\n";
print "[4] save hostgroup and create another hostgroup\n";
print "[5] cancel and go back to main menu\n";
print "-----------------------------------\n";
do {
print "Enter your choice: ";
$choice = <STDIN>;
chomp $choice;
}until ($choice =~ /^\d+|q$/i);
if ($choice eq 1) { $name = getText("hostgroup name") }
elsif ($choice eq 2) { addNodes($hostgroup) }
elsif ($choice eq 3) {
createHostgroup(HOSTGROUP=>$hostgroup);
$hostgroupCreated = 1;
$end = 1;
}
elsif ($choice eq 4) {
createHostgroup(HOSTGROUP=>$hostgroup);
$hostgroupCreated = 1;
$end = 0;
}
else {
$hostgroupCreated = 1;
$end = 1;
}
}until ($hostgroupCreated); #create hostgroup
}until($end); #add hostgroups
}
.....blablabla.....
sub addNodes {
my $hostgroup = shift;
my $end = 0;
do {
my @off = undef;
my @on = undef;
my $i = 0;
for my $node ( sort keys %{$nodes} ) {
unless($hostgroup->getNode(NAME=>$nodes->{$node}->{NAME}))
{
push @off, "[".YELLOW."$node".GREEN."]
$nodes->{$node}->{NAME} ";
}else {
push @on, "[".YELLOW."$node".GREEN."]
$nodes->{$node}->{NAME} ";
}
}
print "availables:\n";
foreach (@off) {
print GREEN;
if($i<3 and $_) { print "$_"; $i++;}
elsif ($_) { print "$_\n"; $i = 0;}
elsif ($#off eq 0) { print RED, "No more node available",
RESET; }
print RESET;
}
}
$i = 0;
print "\n";
print "in hostgroup:\n";
foreach (@on) {
print GREEN;
if($i<3 and $_) { print "$_"; $i++;}
elsif ($_) { print "$_\n"; $i = 0;}
elsif ($#on eq 0) { print RED, "No node to remove yet",
RESET; }
print RESET;
}
print "\n";
print RED, "Press ".YELLOW."q".RED." to Get to main menu\n",
RESET;
my $index = getNumber("node index");
if($index =~ /q/i) {$end = 1}
else {
if ($hostgroup->getNode(NAME=>$nodes->{$index}->{NAME})) {
print MAGENTA, "$nodes->{$index}->{NAME}".RED." removed
from hostgroup.\n", RESET;
$hostgroup->delNode($nodes->{$index}->{NAME});
}else {
!!! IMPORTANT BIT !!!
$hostgroup->addNode(\$nodes->{$index});
!!! IMPORTANT BIT !!!
print MAGENTA, "$nodes->{$index}->{NAME}".RED." added
to hostgroup.\n", RESET;
}
}
if($end) {
if((keys %{$hostgroup->{NODES}}) eq 0) {
$end = 0;
print RED, "You need to add at least one node\n",
RESET;
}
}
} until ($end);
return $hostgroup;
}
package Hostgroup;
use Term::ANSIColor qw

constants);
use strict;
sub new {
my $type = shift;
my %params = @_;
my $self = {};
$self->{'NAME'} = $params{'NAME'};
if (defined($params{'NODES'})) {
$self->{'NODES'} = $params{'NODES'};
}else {
$self->{'NODES'} = {};
}
bless $self, $type;
return $self;
}
sub name {
my $self = shift;
if(@_) { $self->{'NAME'} = shift }
return $self->{'NAME'};
}
sub addNode {
my $self = shift;
my $node = shift;
bless($node);
$self->{'NODES'}->{$node->name()} = $$node;
return $self->{'NODES'}->{$node->name()};
}
sub getNode {
my $self = shift;
my %params = @_;
if (defined($params{'NAME'})) {
return $self->{'NODES'}->{$params{'NAME'}};
}
if (defined($params{'IP'})) {
for my $node_name ( keys %{$self->{ 'NODES' }} ) {
if ($self->{'NODES'}->{$node_name}->{'IP'} eq
$params{'IP'}) {
return $self->{'NODES'}->{$node_name};
}
}
}
return 0;
}
package Node;
use strict;
use Term::ANSIColor qw

constants);
sub new {
my $type = shift;
my %params = @_;
my $self = {};
$self->{'NAME'} = $params{'NAME'};
$self->{'IP'} = $params{'IP'};
bless $self, $type;
return $self;
}
sub name {
my $self = shift;
if(@_) { $self->{'NAME'} = shift }
return $self->{'NAME'};
}
I hope this would be of some help...