1

I am currently creating a class in Perl that looks like this:

sub new{
   $class = shift;
   $self = {
     #Member Variables
     server => shift,
     type => shift,
     domains => shift
   };
   bless $self, $class;
   return $self;
}

I want the domains to be an array with multiple variables. How would I differentiate an array from a normal variable when using shift? I am trying to input the array like this:

 my $var = new class("server",1,(1,2,3));
 my $var = new class("server",1,[1,2,3]);

Neither of these work when trying to iterate through the array doing:

 for $i ($self->{domains}){
     print "$i\n";
 }
1
  • 1
    Especially when using object-oriented Perl, you must always use strict and use warnings 'all' at the top of every Perl source file, and declare each variable using my. Commented May 12, 2017 at 18:51

2 Answers 2

5

Arguments are passed to a function as a list of scalars, and your first invocation is just

my $var = new class("server",1,1,2,3);

A hash value need be a scalar, so you need an anonymous array there

domains => [ LIST ];

So either

  • shift off all single options as you do and then copy the rest into the arrayref

    domains => [ @_ ];
    
  • or pass an arrayref, which is a scalar, like in your second invocation and assign it

    domains => shift;
    

In both cases the $self->{domains} is going to be an arrayref.

On the other hand, consider nicely assigning arguments first

sub new { 
    my ($class, $server, $type, @domains) = @_;
    # ...
    my $self = { 
        # ...
        domains => \@domains
    };
    return bless $self, $class;
}

for the first invocation, or

sub new {
    my ($class, $server, $type, $rdomains) = @_;
    my $self = {
        # ...
        domains => $rdomains
    };
    return bless $self, $class;
}

for the second one. Since bless returns its first argument we can directly return (for brevity).

Finally, you use the indirect object notation for calling the constructor. In short, don't -- use

my $object = ClassName->new( ARGS );

See the link above for an official statement, and this post


Please always run with warnings, as that saves a lot of headaches. I also strongly suggest to always use strict as it promotes all manner of good practices

# At the beginning of every program
use warnings 'all';
use strict;
Sign up to request clarification or add additional context in comments.

2 Comments

Hey zdim, would i still need to include bless $self, $class; and return $self; after I set my $self = {...} ?
@user081608 Yes, by all means. Setting $self merely populates a hashref in the program. It is the bless-ing that makes $self an object of $class, and after that line $self "knows" what class it belongs to, you can call methods on it, etc. While returning it is important for all kinds of uses. I've added that for completeness, thank you for asking.
3

If you want to specify domains as a list, you need to do this:

sub new {
   $class = shift;
   $self = {
     server => shift,
     type => shift,
     domains => [ @_ ],
   };
   bless $self, $class;
   return $self;
}

That's because hashes cannot have non-scalar keys or values.

Either way, you are going to have to dereference that array ref when iterating through domains:

for my $domain (@{ $self->{domains} }){
     print "$domain\n";
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.