1

I'm making a Perl module and I am still getting to grips with how Perl deals with objects. This is the new sub that I wrote to create an object and I have no problem updating elements:

sub new {
    my $class = shift;
    my ($self) = {
        name => undef
    };
    bless($self, $class);
    return $self;
}
sub get_name {
    my $self = shift;
    $self->{name} = 'Eve';
    return $self->{name};
}

I can use the object fine when I call the module and access it from another file, but I want to use the data in the object at other areas in the module code.

So I have no problem doing this:

my $new_object = new ProgramTest; # ProgramTest being the module/package
my $name = get_name();

But I want to use the $self elements in a 'module-internal' method which is never accessed by an outside script. So I want to have something like this:

sub get_variables {
    return (name); # I don't know how to get the name here 
    # (I plan to have other variables, too)
}

I am probably missing something obvious (I'm sure I'll kick myself when I see the solution), so any help appreciated! I want this so that the rest of the module can use the variables (without changing) as there are conditions that rely on their values.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
dgBP
  • 1,681
  • 6
  • 27
  • 42
  • 1
    See [How do I make private functions in a Perl module?](http://stackoverflow.com/questions/451521/how-do-i-make-private-functions-in-a-perl-module). – qqx Oct 31 '12 at 13:46
  • That is actually very helpful and explains why I keep seeing `_` used in some places and not others +1 – dgBP Oct 31 '12 at 13:52
  • 1
    another thing to learn "new Thing" is bad in Perl: http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/ among many other good articles – Joel Berger Oct 31 '12 at 16:01

2 Answers2

6

There's no such thing as internal/private methods in perl objects. Common practise is to start any methods which should not be used publicly with an underscore, but this is not enforced in any way. Also have a look at moose - it takes a lot of the hassle out of OO perl.

With regards to your question the below shows how one module method can call another module method, with both having access to the object data. Again I woulds really recommend you use Moose!

sub publicSub{
    my ( $self ) = @_;

    return $self->_privateSub();
}

sub _privateSub{
    my ( $self ) = @_;

    return $self->{name};
}
beresfordt
  • 5,088
  • 10
  • 35
  • 43
  • oh interesting - I tried passing `$self` around and it didn't seem to do anything. I'll play with that, thanks – dgBP Oct 31 '12 at 13:54
  • 3
    The `$self` always holds the blessed object itself. If you call a method on an object like `$obj->do($stuff)` then the `->` makes Perl use `$obj` as the first argument to the `do` sub, thus it needs `my ($self, $stuff) = @_`. You can do the same with internal methods. Note that you **could** also call a method explicitly with `do($obj, $stuff)`. That works, but looks ugly and no-one will understand what you are doing, so **don't do it**. – simbabque Oct 31 '12 at 14:06
  • gah - knew it didn't look right, couldn't put my finger on why, updating – beresfordt Oct 31 '12 at 14:13
5

I think you want class-variables. They are global to a class and all instances of the class (i.e. all the objects you created) can see them. Global in this case means that they are at the ouside-most lexical scope, so all subs can see them.

package ProgramTest;
my $everyone_can_see_this = 1; # lexical scope, but 'global' to the package

sub new {
    my $class = shift;
    my ($self) = {
        name => undef
    };
    bless($self, $class);
    return $self;
}
sub get_var {
    my $self = shift;
    return ++$everyone_can_see_this;
}

package Main;
my $o1 = ProgramTest->new;
my $o2 = ProgramTest->new;

say $o1->get_var;
say $o2->get_var;
say $o1->get_var;

__END__
2
3
4

But I don't see why you would want to do that. It doesn't make sense (unless you want an object-counter). Don't use it for config values, or you cannot really have objects for different purposes of the same class.

Maybe you want something else. If so, please try to rephrase your question.

simbabque
  • 53,749
  • 8
  • 73
  • 136
  • hmm yeh, I had class variables before but was told that I should make an object and reference it. I know I can just put them back into variables again, but it seems a pointless use of an object. I use the variables as part of `if` statements later on in the module and use them as parameters for another module's method, so it all seems overly complicated to use an object for. Thanks for your reply :) – dgBP Oct 31 '12 at 13:49