Thursday, April 10, 2008

my vs. our

In letzter Zeit bin ich immer wieder auf die Fragestellung "Was ist der Unterschied zwischen my und our?".

Aus perldoc -f my:
A "my" declares the listed variables to be local (lexically) to the enclosing
block, file, or "eval". If more than one value is listed, the list must be placed
in parentheses.


Und aus perldoc -f our:
Unlike "my", which both allocates storage for a variable and associates a simple
name with that storage for use within the current scope, "our" associates a
simple name with a package variable in the current package, for use within the
current scope. In other words, "our" has the same scoping rules as "my", but does
not necessarily create a variable.

Mit our sind die Variablen also an das package gebunden, wodurch die Variable auch nach "außen" hin sichtbar wird. D.h. dass die Variable auch von anderen packages aus verwendet werden können. Mit my ist das nicht möglich:

#!/usr/bin/perl
use strict;
use warnings;
{
package MyTest;
my $test = 823;
}
print $MyTest::test,"\n";



Gibt eine Warnung aus...

C:\>my_vs_our.pl
Name "MyTest::test" used only once: possible typo at C:\my_vs_our.pl line 12.
Use of uninitialized value in print at C:\my_vs_our.pl line 12.


Ändert man das my in our, gibt es folgende Ausgabe:

C:\>my_vs_our.pl
823


Allerdings finde ich den übermäßigen Gebrauch an our-Variablen nicht so prickelnd, weil es mich in meinem Modul stark einschränkt. Möchte ich in $test nicht nur eine Zahl speichern, sondern eine Datenstruktur, dann werden alle Skripte die $test direkt verwenden nicht mehr funktionieren.

Deshalb arbeite ich dann lieber mit my-Variablen und getter- und setter-Methoden.

#!/usr/bin/perl
use strict;
use warnings;
{
package MyTest;
our $test = 9;
sub get_test{ return $test; }
sub set_test{ $test = shift; }
}
print $MyTest::test,"\n";
print MyTest::get_test(),"\n";
MyTest::set_test( 199 );
print MyTest::get_test(),"\n";
__END__
9
9
199


vs.

#!/usr/bin/perl
use strict;
use warnings;
{
package MyTest;
our $test = { irgendwas => 823, test => 9 };
sub get_test{ return $test->{test}; }
sub set_test{ $test->{test} = shift; }
}
print $MyTest::test,"\n";
print MyTest::get_test(),"\n";
MyTest::set_test( 199 );
print MyTest::get_test(),"\n";
__END__
HASH(0x235fc0)
9
199


Wie man sieht, ist die Ausgabe bei der direkten Verwendung von $test nicht mehr wie ursprünglich gedacht, während die Verwendung der Funktionen noch einwandfrei läuft. Jetzt noch beim zweiten Code das our in my ändern und alles ist ok...

1 comment:

Anonymous said...

du hast zwar geschrieben dass du beim zweiten Mal "my" verwendest, hast du aber nicht gemacht...