Link a variable to a class attribute in Perl

2019-05-12 18:16发布

问题:

This question was born out of another (Completely destroy all traces of an object in Perl). After seeing some of the comments I believe I have narrowed the problem down to the "real" issue.

I'm looking for a simple way to link a variable to a class attribute in Perl so that whenever the attribute is modified, the variable will be automatically updated.

ex (some pseudo code):

# Create a file object
my $file = File->new();

# Get the text
my $text = $file->text();

# prints 'hello'
print $text;

# Set the text
$file->text('goodbye');

# prints 'goodbye'
print $text;

Also I want the $text variable to be read only so that you cannot inadvertently modify the text attribute of the file.

回答1:

Use tie:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{   package File;

    sub new {
        bless ['hello'], shift
    }

    sub text {
        my $self = shift;
        if (@_) {
            $self->[0] = shift;
        } else {
            return $self->[0]
        }
    }
}

{   package FileVar;
    use Tie::Scalar;
    use parent qw( -norequire Tie::StdScalar );

    sub TIESCALAR {
        my ($class, $obj) = @_;
        bless \$obj, $class
    }

    sub FETCH {
        my $self = shift;
        ${$self}->text()
    }

    sub STORE {
        die 'Read only!';

        # Or, do you want to change the object by changing the var, too?
        my ($self, $value) = @_;
        ${$self}->text($value);
    }

}

my $file = 'File'->new();
tie my $text, 'FileVar', $file;
say $text;
$file->text('goodbye');
say $text;

# Die or change the object:
$text = 'Magic!';
say $file->text;