Schrift
[thread]11711[/thread]

Zugriff auf anderes Package (klappt nicht)



<< |< 1 2 >| >> 13 Einträge, 2 Seiten
Gast Gast
 2008-04-27 01:10
#108904 #108904
Ich versuche auf eine Variable im main:: Package zuzugreifen. Irgendwie klappt es aber nicht:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/perl

use strict;
use warnings;

my $foo = 123;

sub foo {print 'foo'}

package bar;

print $main::foo;
&main::foo;


wenn ich das ausführe, kommt die Meldung, dass ich versuch einen undefinierten Wert auszugeben. Mit der Subrotiene funktioniert alles. Weiss jemand, was da los ist?
KurtZ
 2008-04-27 03:34
#108905 #108905
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Code (perl): (dl )
my $foo = 123;


definiert eine lexikalische (auch "private" deswegen my) statt einer Packagevariable (auch "öffentliche" deswegen our) .

Schreibe also stattdessen

Code (perl): (dl )
our $foo = 123;


dann sollte es gehen.
TMTOWTDYOG (there's more than one way to dig your own grave)
Gast Gast
 2008-04-27 21:44
#108913 #108913
hm. Aber das müsste doch eigentlich klappen. Auf die Funktion kann ich doch auch mit dem Packagenamen zugreifen; warum funktioniert das mit der Variable nicht?

Per our deklarieren wäre eine Alternative, allerdings ließt man doch immer, man soll solche Variablen vermeiden, wenn es nicht unbedingt nötig ist(?).
pktm
 2008-04-27 21:58
#108915 #108915
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Gast+2008-04-27 19:44:47--
hm. Aber das müsste doch eigentlich klappen. Auf die Funktion kann ich doch auch mit dem Packagenamen zugreifen; warum funktioniert das mit der Variable nicht?

Per our deklarieren wäre eine Alternative, allerdings ließt man doch immer, man soll solche Variablen vermeiden, wenn es nicht unbedingt nötig ist(?).


Wie KurtZ schon schrieb, erzeugen Variablen, die mit "my" innerhalb eines Packages erzeugt werden sozusagen private Packagenamen. Die nennt man so (privat), weil sie zu den privaten, nicht-öffentlichen (=/= public) und somit nicht von außen zu manipulierenden Variablen zählen.

Grüße, pktm
http://www.intergastro-service.de (mein erstes CMS :) )
Gast Gast
 2008-04-27 22:24
#108916 #108916
Ich glaube jetzt habe ich es kapiert ;)

Aber das ist doch merkwürdig:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/perl

use strict;
use warnings;

our $foo = 123;

package bar;

print $main::foo;
print $foo


Man kann entweder $main::foo oder $foo schreiben. Welchen Sinn soll das haben? Es wäre doch viel sinnvoller, wenn ich auf 'my'-Variablen per Packagenamen zugreifen könnte und nicht auf die 'our'-Variablen, die ja sowieso global verfügbar sind.
Struppi
 2008-04-27 23:06
#108917 #108917
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Mit our sagst du dass die package Variabel von aussen zugreifbar ist.

[EDIT]und mit our wird die Variabel nur Dateiweit global.
Gast Gast
 2008-04-27 23:29
#108918 #108918
Quote
[EDIT]und mit our wird die Variabel nur Dateiweit global.


Ach so. Das heißt, wenn ich die Variable in einem Modul verwenden will (was ich vor habe) muss ich sie zwangsläufig per $Packagename::Variablenname aufrufen?
KurtZ
 2008-04-28 00:03
#108919 #108919
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Struppi+2008-04-27 21:06:13--
[EDIT]und mit our wird die Variabel nur Dateiweit global.


Wirklich? Meiner Erinnerung nach, wird sie bestenfalls dateiweit deklariert, ist aber trotzdem dateiübergreifend nutzbar.

M.a.W. our $var sorgt innerhalb seines Scopes[1], dass use strict nicht meckert, wenn ich ohne explizites $package::var auf $var zugreife. Was aber nichts an Speicherort und Zugriff ändert, aus einer anderen Datei kann ich immer noch $package::var oder wieder our $var schreiben, und auf den gleichen Wert zugreifen.

Sorry, einen Beispielcode dafür zu hacken spar ich mir mal und behaupte das mal so, und lass mich gerne widerlegen.



[1] und ein Scope ist größtenfalls die Datei.
TMTOWTDYOG (there's more than one way to dig your own grave)
KurtZ
 2008-04-28 00:29
#108920 #108920
User since
2007-12-13
411 Artikel
BenutzerIn
[default_avatar]
Gast+2008-04-27 21:29:59--
Ach so. Das heißt, wenn ich die Variable in einem Modul verwenden will (was ich vor habe) muss ich sie zwangsläufig per $Packagename::Variablenname aufrufen?


du kannst mal ein ziemlich langes Streitgespräch dazu nachlesenKonzept der Namensräume; Global, Dynamic und Lexical Scope , steht leider auch öfters was falsches drin, achte deswegen auf die Chronologie.

Die Kurzform

Es gibt 2 Arten von Variablen in Perl, welche Sorte du verwendest hängt von der letzten Deklaration im gleichen Scope ab.
(Ohne use strict sind undeklarierte Variablen automatisch Packagevariablen, mit use strict muss jeder Variablenname deklariert werden.)

Packagevariablen sind Variablen die in öffentlichen Namensräumen abgelegt werden (auch Dateiübergreifend nutzbar)
Lexikalische Variablen werden in einem unbenannten, privaten Raum des Geltungsbereich (Scope) abgelegt, also der umgebende Klammernblock oder Funktion, maximal aber die aktuelle Datei.
Deklarationen wirken nur in ihrem Geltungsbereich (wie gesagt maximal aktuelle Datei) und müssen außerhalb falls nötig wiederholt werden.

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package xxx;
{ 
# Blockstart
    our $public;
    my $private;
    # in diesem Blockscope ist jedes $public als Kurzschreibung für $xxx::public deklariert
    # in diesem Blockscope ist jedes $private als lexikalisch deklariert,
    # und wird privat beim Blockscope gespeichert, absolut unabhängig vom Package 
}
# Blockende

# $private existiert nicht mehr, weil sein Scope verlassen wurde, Zugriff (ohne "Schmuggelaktionen") ist unmöglich

# hier ist der kurze Variablenname $public undeklariert
# ich kann aber immer noch problemlos auf die Variable $xxx::public zugreifen
# auch aus einer anderen Datei


um letztendlich deine Frage zu beantworten:

Solange in deinem aktuellen Scope auf ein package Packagename ein our $variablenname folgt, kannst du im ganzen Scope $variablenname statt $Packagename::variablenname schreiben.

Steht das am Anfang der Datei, gilt das sogar für die ganze Datei (äußerster Scope) siehe auch perldoc -f our
TMTOWTDYOG (there's more than one way to dig your own grave)
Gast Gast
 2008-04-28 01:03
#108921 #108921
Gute Erklärung. Vielen Dank!

Und nur nochmal zu Sicherheit: Wenn ich die $public außerhalb des Blockendes oder in einer anderen Datei ohne den Packagenamen verwenden will, kann ich sie einfach per 'our $public' neu deklarieren, ohne das so der Inhalt gelöscht/überschrieben wird?
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2008-04-27 01:10.