Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]2092[/thread]

Programmgerüst und Gültigkeitsbereiche (Seite 2)

Leser: 3


<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten
PerlProfi
 2007-04-14 21:00
#23674 #23674
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Ergänzend zu sid burn:
Falls du nur eine package Variable erzeugen möchtest, ohne eine lexikalische zu überschreiben / erstellen, benutzt du weder my noch our, sondern schreibst es einfach so:
Code: (dl )
1
2
3
4
5
# package definition
package Test;

# package Variable erstellen
$Test::test = 'Test';


In main hätte $test immer noch den alten Wert.
Vollständiges Beispiel:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/perl -w
use strict;

# lexikalische Variable in main
my $test = 'Hallo';

# package wechseln
package Test;

# package Variable in Test
$Test::test = 'Welt';

# package wechseln
package main;

# Ausgabe beider Variablen
print join(' ', $test, $Test::test), "\n";


MfG


Jedenfalls mache ich das immer so...\n\n

<!--EDIT|PerlProfi|1176570042-->
sid burn
 2007-04-14 21:14
#23675 #23675
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=PerlProfi,14.April.2007, 19:00]Ergänzend zu sid burn:
Falls du nur eine package Variable erzeugen möchtest, ohne eine lexikalische zu überschreiben / erstellen, benutzt du weder my noch our, sondern schreibst es einfach so:
...
Jedenfalls mache ich das immer so...[/quote]
Hat aber den Nachteil das wenn du den Package Namen änderst auch alle Variablen anpassen musst.

-----------------------

Ansonsten sollten mehrere package Deklaration sowieso nicht in einer Datei seien, und wenn man es doch macht reicht wie gesagt auch einfach einen Block um die packages zu machen.

Zwar wird dann im Block der package Test umgibt die lexikalische Variable $test durch die our Deklaration überschrieben, aber dieser Automatische Nebeneffekt wird beim Verlassen des Blockes ja wieder aufgehoben.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl
use warnings;
use strict;

my $test = 'Hallo';

{
package Test;
# package Variable in Test
our $test = 'Welt';
}

package main;
# Ausgabe beider Variablen
print join(' ', $test, $Test::test), "\n";


Quote
In main hätte $test immer noch den alten Wert.
...
# lexikalische Variable in main

Lexikalische Variablen hängen nicht vom Package ab. ;)

Du kannst danach auch ins Packacke "foo" wechseln und die lexikalische Variable hätte immer noch den selbern Wert, und würde immer noch nur durch $test ausgegeben werden.\n\n

<!--EDIT|sid burn|1176571317-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
PerlProfi
 2007-04-14 22:26
#23676 #23676
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Das passt aber nicht zudem was du vorher gesagt hast:
Quote
5) Wenn du Package Variablen mit "our" Deklarierst wird als Nebeneffekt noch zusätzlich eine lexikalische Variable erzeugt, die auf die Package variable zeigt.

Was ja auch heißt, dass deren Wert überschrieben werden würde.
Macht man es in einem Block wird der Wert überschrieben, am Ende aber wieder zurückgesetzt, macht man es mit $Package::Variable wird der Wert nicht überschrieben.
Die lexikalische Variable wird vom Wert her also nicht verändert.
Anders als bei our().

Oder hab ich da was falsch verstanden ?

MfG
tonewheel
 2007-04-15 13:56
#23677 #23677
User since
2006-10-01
182 Artikel
BenutzerIn
[default_avatar]
Hallo,
nun muss ich erstmal schlucken bei soviel Info. ;)

@ronnie: Das heisst, Moose ist nichts "Besonderes" in dem Sinne, sondern nimmt vielmehr Schreibarbeit ab?! Und ist der Konstruktor bei Perl nur dann Derjenige, wenn die entspr. Methode (die m.W. nichtmal new heissen muss?!) "bless" beinhaltet?
Zur Aggregation/Assoziation; da es bei Perl keine Zeiger gibt, kommt wohl auch nur die Aggregation in Frage. Eine kurze Erklärung dazu ist hier zu finden.

@sid-burn/PerlProfi: ohje, das ist wirklich etwas verzwickt. Kannst Du nochmal kurz auflisten, was "my $foo", "our $foo" und nur "$foo" am Package deklariert aussagt, bzw. wann nun eine lexikalisch Variable mit erzeugt wird und wann nicht?
Ronnie
 2007-04-15 15:24
#23678 #23678
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=tonewheel,15.04.2007, 11:56]@ronnie: Das heisst, Moose ist nichts "Besonderes" in dem Sinne, sondern nimmt vielmehr Schreibarbeit ab?! Und ist der Konstruktor bei Perl nur dann Derjenige, wenn die entspr. Methode (die m.W. nichtmal new heissen muss?!) "bless" beinhaltet?
Zur Aggregation/Assoziation; da es bei Perl keine Zeiger gibt, kommt wohl auch nur die Aggregation in Frage. Eine kurze Erklärung dazu ist hier zu finden.[/quote]
Hallo tonewheel,

naja, Moose implementiert deutlich mehr als nur eine Kosmetik der Syntax. Es kann jede Menge Dinge mit denen ich mich noch nicht vollständig auseinandergesetzt habe. Ein Blick in das CPAN:Moose::Cookbook lohnt auf jeden Fall.

Ja, der Konstruktor muss nicht zwingend new genannt werden. Es gibt einige populäre Module die das nicht tun. Ich empfehle es aber aus Gründen der Einfachheit. Eine sinnvolle Namenswahl bei Methoden ist immer sinnvoll.

So wie ich das mit der Aggregation verstanden habe, solltest du keine Probleme damit bekommen.

Wer größere Projekte implementiert, für den ist es sicher sinnvoll sich auch mit POD für die Dokumentation; und mit den Test Suites zu beschäftigen. Test-driven development hat heute einen hohen Stellenwert und ausführliche Tests gehören bei CPAN Modulen zum guten Ton.
pktm
 2007-04-15 20:50
#23679 #23679
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Nur so als Zwischenfrage: Gibt es eigentlich auch sowas wie Programmgerüste für Tk oder Wx?
http://www.intergastro-service.de (mein erstes CMS :) )
lichtkind
 2007-04-15 23:21
#23680 #23680
User since
2004-03-22
5701 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
ja die GUI designer haben sowas oder du kopierst dir was aus dem tutorial hier. aber wenn ich in meinem editor snipptet libs habe wollt ich sowas auch dort einfügen.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
tonewheel
 2007-04-16 08:41
#23681 #23681
User since
2006-10-01
182 Artikel
BenutzerIn
[default_avatar]
Hallo,

[quote=lichtkind,15.04.2007, 21:21]ja die GUI designer haben sowas oder du kopierst dir was aus dem tutorial hier. aber wenn ich in meinem editor snipptet libs habe wollt ich sowas auch dort einfügen.[/quote]

was sind denn snippet libs?
lichtkind
 2007-04-16 11:47
#23682 #23682
User since
2004-03-22
5701 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
snippets sind halt codeschnippsel und eine lib eine bibliothe davon die man mit drag und drop reinziehen könnte.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
sid burn
 2007-04-16 16:56
#23683 #23683
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Quote
Das passt aber nicht zudem was du vorher gesagt hast:
Quote
5) Wenn du Package Variablen mit "our" Deklarierst wird als Nebeneffekt noch zusätzlich eine lexikalische Variable erzeugt, die auf die Package variable zeigt.

Was ja auch heißt, dass deren Wert überschrieben werden würde.

Jaein,
eigentlich wird der Wert nicht überschrieben. Da du in einem neuen Block bist, wird eine neue lexikalische Variable erzeugt. Da der Name zum Zugriff der selbe ist, verlierst du die Möglichkeit auf die vorherige zuzugreifen. Aber sie wird nicht überschrieben.

Das es nicht überschrieben wird kannst du an diesem Beispiel sehen.
Code: (dl )
1
2
3
4
5
6
#!/usr/bin/perl
use warnings;
use strict;

my $string = "Hallo";
{ my $string = "Welt"; }

Wenn die zweite Variable in dem Block die erste überschreiben könnte, dann würde hier eine Fehlermeldung kommen. Nämlich das $string bereits deklariert ist. Da du dich aber wie gesagt in einem neuen Block befindest gilt das als neuer Namensraum für lexikalische Variablen. Was dazu führt das eine komplett neue unabhängige lexikalische Variabel erzeugt wird. Wenn du die Klammern drum herum weg nimmst dann befindest du dich im selben namesraum wie die lexikalische Variable von davor. Dann würde es auch eine Fehlermeldung geben das du eine bereits definierte variable nochmal neu definierst.

Allerdiengs gibt es hier keinen Fehler. Den der Block stellt einen neuen Namensraum für lexikalische Variablen dar. Daher es wird im Block eine neue Variable $string erstellt. Es gibt nun zwei lexkialische Variablen die $string heißen, aber beide in einen anderen Namensraum.

Ansonsten wäre Temporär überschreiben folgendes:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
my $string = "Hallo, Welt!\n";
{
my $temp = $string;
$string = "wie geht es dir\n";

# tue etwas mit $string

# Variable wieder zurück setzen
$string = $temp;
}


Naja und ich sagte "Jaein" beim überschreiben, weil du dadurch halt kein Zugriff mehr auf die erste lexikalische Variable bekommst, dass ist natürlich richtig.

Allerdiengs gibt es ein Überschreiben von Variablen nur dann wenn du Package Variablen z.B: mit "local" nutzt. Dann wird die Original Variable wirklich überschrieben. Schau dir dazu mal folgende zwei Beispiel an.

Code: (dl )
1
2
3
4
5
6
7
8
9
my $string = "Hallo, Welt!\n";
sub print_out {
print $string;
}

{
my $string = "Wie geht es dir?\n";
print_out();
}


Code: (dl )
1
2
3
4
5
6
7
8
9
our $string = "Hallo, Welt!\n";
sub print_out {
print $string;
}

{
local $string = "Wie geht es dir?\n";
print_out();
}


Das erste Beispiel wird dir "Hallo, Welt!\n" ausgeben, dass zweite Beispiel jedoch "Wie geht es dir?\n".

Am Anfang wird eine lexikalische Variable definiert. Diese wird durch die darauffolgende Subroutine ausgegeben.

Danach beginnt ein neuer Block. Und es wird eine komplett neue lexikalische Variable definiert mit einem neuen String. Nun wird die Subroutine aufgerufen.

Die Subroutine hat aber einen komplett anderen Namensraum wie in unserem Block. Sie gibt also stattdessen die erste Variable aus. Die Zweite variable sieht die Subroutine gar nicht.

Das ist schon ein Beipsiel das die Variable nicht überschrieben wurde, sondern es zwei variablen gibt.


Im zweiten Beispiel wird die Variable wirklich überschrieben. Es wird eine Package Variable angelegt. Und die Subroutine soll diese Variable ausgeben.

Danach springen wir in den neuen Block. Das local bewirkt nun das die Package Variable "temporär" mit einem neuen Wert überschrieben wird. Die änderung an der Variable wird beim verlassen des Blockes wieder abgeändert.

Wenn wir allerdiengs innerhlab des Blockes die Subroutine aufrufen, dann gibt unsere Variable wirklich den neuen Wert aus. Denn es wurde die selbe variable genutzt, die temporär überschrieben wurde.

Quote
Macht man es in einem Block wird der Wert überschrieben, am Ende aber wieder zurückgesetzt, macht man es mit $Package::Variable wird der Wert nicht überschrieben.
Die lexikalische Variable wird vom Wert her also nicht verändert.
Anders als bei our().


Ich hoffe die Erklärung war oben gut genug.
In dem Block wird der Wert halt nicht überschrieben. Im Block ist ein neuer Namensraum für lexikalische variablen. Eine Deklaration mit "my" führt dazu das eine neue lexikalische Variable in diesem Namensraum erzeugt wird.

Trotzdem existiert die alte Variable weiterhin. Das einzige was du verlierst ist der Zugriff auf die lexikalische Variable von davor. Da immer die "engere" lexikalische Variable benutzt wird.

Bei "our" ist es das gleiche. Wenn du ein Block noch zusätzlich um dein ganzes Package + Methoden etc. machst bildest du damit auch gleichzeitig einen neuen Lexikalischen Raum. Ein our erstellt also noch zusätzlich eine neue lexikalische Variablen innerhalb dieses Blockes.


Die Definition über den vollen Package Namen würde ich halt deswegen nicht machen:
1) Wenn sich der Package Name ändert musst du alle Variablen abändern.
2) Wenn du eine lexikalische Variable nur in einem Package haben möchtest, dann solltest du einen Block drum herum machen und auch nur dort die lexikalische Variable erzeugen. Und nicht ausserhalb des Blockes.
3)Variablennamen solltest du dann so wählen das dort eben keine überscheidung zustande kommt.
4) Eine lexikalische Variable ausserhalb des Blockes zu definieren würde nur Sinn machen wenn du die variable mit mehreren Packages Teilen möchtest. Aber zum einen sollten sowieso nicht mehrere Packages in einer Datei liegen. Damit gibt es dann auch keine Probleme mit lexikalischen variablen die über mehrere Packages hinweg gelten. Möchtest du halt wirklich das eine variable über mehrere Packages gültig ist, dann solltest du dafür auch eine Package Variable nutzen.

Ich sehe also kein Problem darin "our" zu nutzen. Den über Variablen die für mehrere Packages gültig ist, solltest du Package variablen nutzen. Und alle lexikalischen Variablen die du benötigst solltest du innerhalb des Blockes definieren wo du auch das package definierst.

Ich hoffe meine Argumentation ist Verständlich genug. ^^\n\n

<!--EDIT|sid burn|1176728877-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
<< |< 1 2 3 >| >> 21 Einträge, 3 Seiten



View all threads created 2007-04-13 12:24.