NAME
Attribute::Constant - Make read-only variables via attribute
VERSION
$Id: Constant.pm,v 1.0 2013/04/03 06:49:25 dankogai Exp dankogai $
SYNOPSIS
use Attribute::Constant;
my $sv : Constant( $initial_value );
my @av : Constant( @values );
my %hv : Constant( key => value, key => value, ...);
DESCRIPTION
This module uses Data::Lock to make the variable read-only. Check the document and source of Data::Lock for its mechanism.
ATTRIBUTES
This module adds only one attribute, Constant
. You give its initial value as shown. Unlike Readonly, parantheses cannot be ommited but it is semantically more elegant and thanks to Data::Lock, it imposes almost no performance penalty.
CAVEAT
Multi-line attributes
Multi-line attributes are not allowed in Perl 5.8.x.
my $o : Constant(Foo->new(one=>1,two=>2,three=>3)); # ok
my $p : Constant(Bar->new(
one =>1,
two =>2,
three =>3
)
); # needs Perl 5.10
In which case you can use Data::Lock instead:
dlock(my $p = Bar->new(
one => 1,
two => 2,
three => 3
)
);
After all, this module is a wrapper to Data::Lock;
Constants from Variables
You may be surprised the following code DOES NOT work as you expected:
#!/usr/bin/perl
use strict;
use warnings;
use Attribute::Constant;
use Data::Dumper;
{
package MyClass;
sub new {
my ( $class, %params ) = @_;
return bless \%params, $class;
}
}
my $o = MyClass->new( a => 1, b => 2 );
my $x : Constant($o);
print Dumper( $o, $x );
Which outputs:
$VAR1 = bless( {
'a' => 1,
'b' => 2
}, 'MyClass' );
$VAR2 = undef;
Why? Because $x : Constant($o)
happens before $o = Myclass->new()
.
On the other hand, the following works.
my $y : Constant(MyClass->new(a => 1,b => 2));
print Dumper( $o, $y );
Rule of the thumb is do not feed variables to constant because varialbes change after the attribute invocation.
Or simply use Data::Lock::dlock
.
use Data::Lock qw/dlock/;
dlock my $z = $o;
print Dumper( $o, $y );
BENCHMARK
Here I have benchmarked like this.
1. Create an immutable variable.
2. try to change it and see if it raises exception
3. make sure the value stored remains unchanged.
See t/benchmark.pl for details.
- Simple scalar
-
Rate Readonly glob Attribute Readonly 7803/s -- -97% -97% glob 281666/s 3510% -- -5% Attribute 295780/s 3691% 5% --
- Array with 1000 entries
-
Rate Readonly Attribute Readonly 8589/s -- -97% Attribute 278755/s 3145% --
- Hash with 1000 key/value pairs
-
Rate Readonly Attribute Readonly 6979/s -- -97% Attribute 207526/s 2874%
SEE ALSO
AUTHOR
Dan Kogai, <dankogai+cpan at gmail.com>
BUGS & SUPPORT
See Data::Lock.
ACKNOWLEDGEMENTS
COPYRIGHT & LICENSE
Copyright 2008-2013 Dan Kogai, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.