问题
I've just begun designing a Perl class, and my only prior experience with OOP is with C++, a long time ago.
There are a few items of data that I need to be "class variables" - shared by all instances. I'd like for them to be initialized prior to the first time I instantiate an object, and I'd like for the main program that issues use MyClass
to be able to provide a parameter for that initialization process.
Here's a working example of a class with a class variable:
package MyClass;
use strict;
use warnings;
# class variable ('our' for package visibility)
#
our $class_variable = 3; # Would like to bind to a variable
sub new {
my $class = shift;
my $self = { };
bless $self, $class;
return $self;
}
sub method {
my $self = shift;
print "class_variable: $class_variable\n";
++$class_variable; # prove that other instances will see this change
}
And here's a demo:
#!/usr/bin/perl
use strict;
use warnings;
use MyClass;
my $foo = MyClass->new();
$foo->method(); # show the class variable, and increment it.
my $bar = MyClass->new();
$bar->method(); # this will show the incremented class variable.
Is there any way for the main program to specify a value for $class_variable? The value would be known at compile time in the main program.
回答1:
Using the import facility:
package MyClass;
my $class_variable;
sub import
{
(undef, my $new_class_variable) = @_;
if (defined $class_variable and
defined $new_class_variable and
$class_variable ne $new_class_variable)
{
warn '$MyClass::class_variable redefined';
}
$class_variable = $new_class_variable if defined $new_class_variable;
}
Pass the value when you use the module:
use MyClass qw(42);
It's not exactly idiomatic Perl, but it's not uncommon either. That sanity check in the middle of the function should give you a hint about why it might not be the best approach in all cases. If MyClass is only supposed to be use
d from a top-level script, you could enforce that sanity check instead:
caller eq 'main' or die 'MyClass can only be used from package main';
回答2:
You can also make the variable "private" by declaring it with my
instead of our
. In such a case, you have to provide a class method to initialize it:
my $class_variable = 3;
sub initialize_variable {
my ($class, $value) = @_;
die "Ivalid value $value.\n" unless $value =~ /^[0-9]+$/;
$class_variable = $value;
}
And then in the programme:
'MyClass'->initialize_variable(42);
回答3:
$MyClass::class_variable = "some value";
回答4:
You can also use a Class method:
Ex:
package myclass;
our $class_variable = 5;
sub myclass_method{
my ($class, $new_class_variable_value) = @_;
if( $class_variable != $new_class_variable_value )
{
## set the new value of the class/package variable
$class_variable = $new_class_variable_value;
}
}
In your script you'd invoke this by doing:
myclass::myclass_method('myclass', 7);
来源:https://stackoverflow.com/questions/16655603/perl-objects-class-variable-initialization