in reply to Re: Why not use a local variable for $self in Moose?
in thread Why not use a local variable for $self in Moose?

Ah, OK. So I understand what you are saying but I'm not quite sure why it is so. I don't have a clear idea of how memory gets allocated for a class. How does $self get assigned to the same exact memory location every time a new object is created? I guess this happens when the compiler sets up a "prototype" (for lack of a better word) for the object class?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

  • Comment on Re^2: Why not use a local variable for $self in Moose?

Replies are listed 'Best First'.
Re^3: Why not use a local variable for $self in Moose?
by haj (Vicar) on Oct 19, 2018 at 07:46 UTC
    How does $self get assigned to the same exact memory location every time a new object is created?

    In normal usage, you don't get the same exact memory location every time a new object is created. Quite on the contrary: Every object has its own value for $self which is returned by the new() method as a reference to a new (!) hash. You might get the same memory location if you drop an object and then create another one, if Perl's memory management decides that way.

    In your code example, $self is a lexical variable which gets a location in memory once, when the module's code is evaluated. The value of $self gets overwritten every time a new object is created, so the return value of kool_func_for_users changes with every new object - but then, it does so for all objects on that class. In effect, you have created a "class attribute" which has the name $self but in your case should actually be called $most_recent_object. There are valid use cases for these, and there's also a Moose module MooseX::ClassAttribute.

    Here's a short demo (in which I've also fixed your attribute syntax by using parens instead of braces, and by using is and isa as intended by Moose):

    use strict; use warnings; use 5.010; # saving some vertical space package My::Demo; use Moose; has 'why_pass_self' => ( is => 'ro', isa => 'Str', default => 'dunno, is this ok?' ); my $self; sub BUILD { my $s = shift; $self = $s; } sub _kool_func { say $self->why_pass_self; } sub kool_func_for_users { my $self = shift; $self->_kool_func; } ##################################################################### package main; use Scalar::Util qw(refaddr); my $o1 = My::Demo->new; print "o1 ", refaddr($o1), " at says: "; $o1->kool_func_for_users; my $o2 = My::Demo->new(why_pass_self => "That's why!"); print "o2 ", refaddr($o2), " at says: "; $o2->kool_func_for_users; print "o1 ", refaddr($o1), " at says: "; $o1->kool_func_for_users;
    PS: I just noticed I've provided what Corion suggested:
    Maybe consider just creating two objects of the same such class and watch what happens.
Re^3: Why not use a local variable for $self in Moose?
by haukex (Archbishop) on Oct 19, 2018 at 08:12 UTC
    I don't have a clear idea of how memory gets allocated for a class.

    Remember that in Perl, An Object is Simply a Data Structure. Even though Moose may add a ton of functionality, in the end, a Moose object is just a blessed hashref. When you allocate a new anonymous hash with {}, that's newly allocated memory. However, variables defined at the package level belong to that package - they are set up when the package is parsed and executed, which typically happens only once; a new package variable isn't instantiated because you created an instance of a class.

Re^3: Why not use a local variable for $self in Moose?
by Corion (Patriarch) on Oct 19, 2018 at 06:52 UTC

    No, your $self in global scope is just one variable that then gets overwritten every time you instantiate a new object. The old one automatically gets DESTROYed at that time.

    Maybe consider just creating two objects of the same such class and watch what happens.

      OK, I think I get it. There can only be one $my_package::self variable in the compiled code at a time.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        >  $my_package::self

        $self doesn't belong to a package, it's private (not local ) in the file scope, since you declared it with my.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice