Change class attribute locally in Perl

I ran into an odd problem in one of my Perl scripts. I have a Perl object. In a specific area, I want one of the attributes of the objects to be changed, but I want the attribute to be restored to it with the old value after it left the area.

Example:

my $object = Object->new('name' => 'Bob');
{
     # I know this doesn't work, but it is the best way
     # I can represent what I amd trying to do.
     local $object->name('Lenny');

     # Prints "Lenny"
     print $object->name();
}

# Prints "Bob"
print $object->name();

Is there a way to achieve something like this?

+4
source share
2 answers

It may not be as much encapsulation as you requested, but you can local-ize the hash attribute. It outputs"CarlLennyCarl"

sub Object::new { bless { _name => $_[1] }, $_[0] } }
sub Object::name { $_[0]->{_name} }

my $obj = Object->new("Carl");
print $obj->name;
{
    local $obj->{_name} = "Lenny";
    print $obj->name;
}
print $obj->name;

You can also local-ize the whole method. This also outputs "CarlLennyCarl":

sub Object::new { bless { _name => $_[1] }, $_[0] } }
sub Object::name { $_[0]->{_name} }

my $obj = Object->new("Carl");
print $obj->name;
{
    local *Object::name = sub { "Lenny" };
    print $obj->name;
}
print $obj->name;
+5
source

, . , , .

, , , , , eval.

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Cwd;

print getcwd() . "\n";

eval{
        local @INC = ('/tmp');
        require 'test.pl';

        print 'local: ' . Dumper(\@INC);
};
print Dumper(\@INC);

, , .

, , - . ( , , )

local , eval, OR ( )

( IMHO), , , .

:

name.pm:

package name;
use strict;
use warnings;

{

    sub new {
        my ($class,$name) = @_;
        my $self = bless {}, $class;
        $self->{'name'} = $name if defined $name;
        return $self;
    }

    sub name
    {
        my ($self,$name) = @_;
        $self->{'name'} = $name if defined $name;
        return $self->{'name'};
    }
}

index.pl:

#!/usr/bin/perl -w
use strict;
use warnings FATAL => 'all';

use name;

my $obj = name->new('test');

print $obj->{'name'} . "\n";

{
    local $obj->{'name'} = 'test2';

    print $obj->{'name'} . "\n";
}

print $obj->{'name'} . "\n";
-1

Source: https://habr.com/ru/post/1605827/


All Articles