Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

creating an altered clone of a Moose object for a limited scope

by metaperl (Curate)
on Jul 09, 2011 at 11:10 UTC ( [id://913505]=perlquestion: print w/replies, xml ) Need Help??

metaperl has asked for the wisdom of the Perl Monks concerning the following question:

In the second code sample below, package LM has a subroutine mylol. In this subroutine, the object slot data is manually changed from it's initialized value and then set back to the original value before the subroutine exits.

I was hoping to use lexical scope or something to avoid manually setting the value back to its original value:

sub mylol { my $self=shift; { local $self; $self->{data} = {newdata => 1}; $lol = super(); } }
but I didnt like the idea of using package variables to achieve it. Is there some way to create a scope and change an object and then have it pop back to the initial settings?
package L; use Moose; has 'data' => ( is => 'rw', trigger => \&maybe_morph ); sub maybe_morph { my ($self) = @_; if ( $self->can('morph') ) { $self->morph; } } sub lol { my $self=shift; [ lol => 'haha' ]; } sub tree { warn 'tree'; $_[0]; } sub prune { warn 'prune'; } after 'tree' => sub { warn 'aftertree'; }; 1; package LM; use Moose; extends qw(L); override 'lol' => \&mylol; sub mylol { my ($self) = @_; # get data from object my $original_data = $self->data; my $lol; # set data to something superclass can use, # avoid $self->data($val) because that will # cause the trigger to fire $self->{data} = { newdataset => 1 }; $lol = super(); # now that superclass has been called # set $self->{data} $self->{data} = $original_data; use Data::Dumper; warn Dumper( $self->{data} ); $lol; } package main; my $b = LM->new( data => { m => 'em' } ); $b->mylol; 1;




The mantra of every experienced web application developer is the same: thou shalt separate business logic from display. Ironically, almost all template engines allow violation of this separation principle, which is the very impetus for HTML template engine development.

-- Terence Parr, "Enforcing Strict Model View Separation in Template Engines"

Replies are listed 'Best First'.
Re: creating an altered clone of a Moose object for a limited scope
by Corion (Patriarch) on Jul 09, 2011 at 11:44 UTC

    Your example is quite unclear to me. What is this supposed to to?

    sub mylol { my $self=shift; { local $self; $self->{data} = {newdata => 1}; $lol = super(); } }

    You could simply localize ->{data} and be on your merry way:

    sub mylol { my $self = shift; local $self->{data} = { newdata => 1 }; super(); # $self->{data} is restored here };

    (or, depending on what super() does, just ditch whatever contraptions Moose creates, and directly call $self->SUPPER::mylol, to achieve your goal).

    Update: After having looked at Moose::super, I'm not really sure what your aversion is against package variables, as it uses them as well. And your locally setting $self is quite unlikely to have any sane (or desired) effect as likely the referenced global variables in Moose:: get set from a wrapper installed by Moose::override:

    package Moose; ... our $SUPER_PACKAGE; our $SUPER_BODY; our @SUPER_ARGS; sub super { # This check avoids a recursion loop - see # t/bugs/super_recursion.t return if defined $SUPER_PACKAGE && $SUPER_PACKAGE ne caller(); return unless $SUPER_BODY; $SUPER_BODY->(@SUPER_ARGS); }

    I'm not sure what that contraption is supposed to achieve, but then, maybe that's because I have either never encountered the problems that Moose attempts to solve or have always taken other approaches to these problems.

      Your example is quite unclear to me. What is this supposed to to?
      Well, I had two choices in asking this question. Give the long version of the story describing the software I am developing and all the classes and all the things the classes are doing, or simply create a simple example showing what I did and how I didnt like how I did it. I decided on brevity.

      But to answer your question the way a lawyer does things, I will tell you exactly what the sub mylol is doing but not tell you exactly what big problem I'm writing a big solution to: mylol is a subroutine that subclasses lol from a package in the XML::Quickbooks::Tolol::* name space, such as you see on line 43 here . That sub lol builds an arrayref of arrayrefs for HTML::Element's new_from_lol method. As you can see, the first thing that sub does is get a hashref via $self->data. However, the data that I receive for this one subclass is not in the right format for the parent, so I needed to modify it.

      You could simply localize ->{data} and be on your merry way:
      "be on your merry way" - lol. Thank you. I thought only package variables, not hashref slots, could be localized. That does exactly what I want.
      I'm not sure what that contraption is supposed to achieve, but then, maybe that's because I have either never encountered the problems that Moose attempts to solve or have always taken other approaches to these problems.
      Wow, Moose is a godsend to me.



      The mantra of every experienced web application developer is the same: thou shalt separate business logic from display. Ironically, almost all template engines allow violation of this separation principle, which is the very impetus for HTML template engine development.

      -- Terence Parr, "Enforcing Strict Model View Separation in Template Engines"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://913505]
Approved by lidden
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (6)
As of 2024-04-23 16:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found