2015-09-03 7 views
4

Я столкнулся с нечетной проблемой в одном из своих сценариев Perl. У меня есть объект Perl. В определенной области я хочу, чтобы один из атрибутов объектов был изменен, но я хочу, чтобы атрибут был восстановлен до его старого значения после того, как он покинул область.Локально изменить атрибут класса в Perl

Пример:

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(); 

Есть ли способ, чтобы добиться чего-то вроде этого?

+0

Простой если невпечатляющими хак будет просто сохранить исходное значение в новой переменной в верхней части рамки, делать вещи, и восстановить исходное значение в нижней части. – swornabsent

+0

, если вы можете вызывать разные методы (с другой реализацией) внутри блока или внешнего блока, это сработает. –

ответ

5

Это может быть не столько инкапсуляции, как вы просили, но вы можете local - ize атрибут хэша. Это выводит "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; 

Вы могли бы также local -ize весь метод. Это также выводит "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; 
-1

Я совершенно не понял, что там происходит. Вы не можете использовать локальный вызов подпрограммы, это проблема, с которой вы сталкиваетесь.

Позволяет использовать пример кода из того, что я знаю, и попытаться объяснить, что на самом деле делает eval.

Это работает, потому что я изменяю переменную, не вызывая другую подпрограмму для изменения моей переменной.

Для того, чтобы он работал так, как вы ожидаете, вам нужно будет создать глубокую копию объекта для изменения в локальной области или что-то в этом роде. (Который я уверен, что это то, что происходит в первую очередь)

местные создают простор для данной скобки, Eval или файла (проблема там)

Если вы были в состоянии получить доступ к элементам непосредственно без вызова метода (неправильная практика 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"; 
+0

У вас вообще не возник вопрос? –

+0

нет, непонятый контекст. такие вещи, как local, eval и многие ключевые слова perl, делают разные вещи в зависимости от контекста. Он не нажимал, что проблема была вызвана локальным вызовом метода – steve

+0

НО, вам более разрешено отвечать на вопросы самостоятельно, а не размещать их в теме только для того, чтобы сверлить;) – steve