Schrift
[thread]6198[/thread]

Klassendaten: Globale Variablen in Klassen

Leser: 1


<< |< 1 2 >| >> 17 Einträge, 2 Seiten
Gast Gast
 2004-04-17 13:01
#81624 #81624
Hallo,

ich habe
- eine Datei mit Config-Variablen
- ein Hauptprogramm
- verschiedene (unterschiedliche) Klassen

Sowohl im Hauptprogramm als auch in den Klassen werden die Inhalte bestimmter Config-Variablen benötigt.
Die Config-Variablen liegen als Hash Referenz vor.

Der Konstruktor:
my $sys = SysConfig->new($config);

liefert die Hash-Referenz an die Klasse SysConfig.
Innerhalb der Klasse SysConfig wird dann ein wenig herumgewerkelt (u.a. wird $config einiges an Feldern hinzugefügt) und $config wird Bestandteil von $self.

Nun habe ich aber auch eine Klasse die sich ausschließlich mit I/O - Vorgängen beschäftigt, dabei unbedingt die innerhalb der Klasse SysConfig ermittelten Werte benötigt während die Klasse SysConfig (zur Ermittlung eben dieser Werte) auf die Methoden der I/O Klasse zurückgreifen muß.

Ist das nicht eine wunderschöne Katze-Schwanz-Beiß-Konstruktion? ;)

OK - das funktioniert wenn ich zuerst den Konstruktor für das I/O Objekt aufrufe (dabei $config übergebe) und im Anschluß daran den Konstruktor der Klasse SysConfig abbilde und dabei das I/O Objekt übergebe.

Irgendwie ist das alles aber sehr halsbrecherisch.

Kann mir jemand einen Tip geben wie ich das eleganter löse?

Gruß
Dieter
pfuschi
 2004-04-17 18:26
#81625 #81625
User since
2004-03-31
198 Artikel
BenutzerIn
[default_avatar]
Servus,
ich nehme an, dass das ladne der Sysconf Daten immer nur einmal passiert.
Es gibt 2 Möglichkeiten
1. du baust für das Sysconf ne eigen I/O die etwasunabhängiger ist
2. du benutzt Defaultwerte die beim erstenmal Laden zum tragen kommen

Das mit den Defaults ist glaub das einfachste.

greetz & fetten Segen
manu
PCE - Editor für Perl in Perl
Bookzilla.de - Mit jedem Kauf OpenSource unterstützen
"I know I can't hold the hate inside my mind
cause what consumes your thoughts controls your life"
- Creed
Gast Gast
 2004-04-17 18:47
#81626 #81626
Richtig:
die Config-Datei wird nur einmal geladen (über require eingebunden)

Aber:
die Klasse SysConfig ermittelt die Pfade welche die I/O Klasse zum Lesen und Schreiben benötigt.

Mehr zum Hintergrund:
Das Hauptprogramm ist unabhängig von der Art der Speicherung.
Der User kann also, per Eintrag in die Config-Datei, entscheiden ob die Programm-Daten in einem Flat-File System oder in einer echten Datenbank (bisher wird MySQL und MS-Access unterstützt) gespeichert werden sollen.
Je nach Art des gewählten Speicherungs-Systems, wird dann entweder die Flat-File I/O Klasse oder die DB I/O Klasse vom Hauptprogramm geladen.

Wie gesagt - das funktioniert ...
aber die Verschachtelungen der Klassendaten (nicht die der Instanzdaten) sind mir irgenwie zu brachialisch - das müsste mE eleganter zu lösen sein - aber wie? :)\n\n

<!--EDIT|Dieter|1082213362-->
Knuddlbaer
 2004-04-18 06:25
#81627 #81627
User since
2004-04-13
32 Artikel
BenutzerIn
[default_avatar]
Spricht was dagegen das IO Objekt als Member in die SysConf aufzunehmen ?

Ich bin mal so frei das als C++ Code zu posten. In perl tu ich mich noch viel zu schwer:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ioKlasse
{
public:
ioKlasse(config & myConf);

}

class SysConfig
{
ioKlasse io;
public:
SysConfig(config & myConf);

}

SysConfig::SysConfig(config & myConf) : io(myConf)
{
// Pfade ermitteln
// io benutzten
// noch was anderes machen
}



Der Source is nu nich gerade valid aber ich denke Du weisst was ich meine. Du hättest so die Möglichkeit das IO Objekt über SysConfig zu bekommen und stellst immer sicher das IO initialisiert wird mit config bevor SysConfig richtig existiert.

Da die Klassen stark von ein ander abhängig sind können diese ohnehin nicht alleine leben und in C++ würde ich das dadurch lösen das ich Io als Member aufnehme. (Vererbung wäre auch ne Variante, je nach Anforderung und Designwünschen)
Gast Gast
 2004-04-18 12:45
#81628 #81628
Das ist OK Baer ...
und entspricht (in etwa) dem was ich da veranstaltet habe.
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#-#############################################
  package SysConfig;

#-#############################################
# Use-Section
#-#############################################
   use strict;
   use warnings;
   
#-#############################################
# Setup-Section
#-#############################################
   our ($config, $io);
   
#-#############################################
sub new {
#-#############################################
   my $invoc = shift;
   my $class = ref $invoc || $invoc;
   my $self = {};
   
   ($config, $io) = @{shift()};
   
   bless $self, $class;
   return $self;
}


Damit steht dann das I/O Object ($io) im Namensraum der Klasse SysConfig, als globale Variable zur Verfügung.
(
Gerade fällt mir dazu ein:
man könnte ja $io den Instanzmethoden in Form einer Closure zuweisen ...
$self->{io} = $io;
ob das allerdings die Sache entwirren würde?
Muss mir mal in Ruhe ansehen wie sich die I/O Klasse dann verhält.
)
Strat
 2004-04-19 02:07
#81629 #81629
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
was haelst du von der Idee, die Konfiguration in einen Hash zu packen? Dann hast du nur eine globale Variable, die du z.B. in eine Subroutine auslagern koenntest, z.B.
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
package MyProgram::Config;
use FindBin;
sub GetConfig {
  return {
    pathToScript => $FindBin::Bin,
    xyz => 30,
    # ...
  };
} # GetConfig

und im Hauptprogramm:
Code (perl): (dl )
1
2
3
4
5
6
7
#! /usr/bin/perl
use warnings;
use strict;
use FindBin;
use lib $FindBin::Bin;
use MyProgram::Config;
my $configHashRef = MyProgram::Config->GetConfig();

oder aehnlich
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Gast Gast
 2004-04-19 14:44
#81630 #81630
Quote
was haelst du von der Idee, die Konfiguration in einen Hash zu packen?


$config ist bereits der Hash (die Hashref)

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
#-#############################################
sub new {
#-#############################################
  my $invoc = shift;
  my $class = ref $invoc || $invoc;
  my $self = {};
 
  ($config, $io) = @{shift()};
 
  bless $self, $class;
  return $self;
}
Crian
 2004-04-19 20:28
#81631 #81631
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Nur mal zur Sicherheit, Du redest von Objektdaten (die Daten liegen bei [jedem] Objekt und getrennt voneinander), im Gegensatz zu Klassendaten (siehe Titel des Threads), diese gibt es einmal in der Klasse und sie sind für jedes Objekt physikalisch gleich (gleiche Speicheradresse). Sinnvoll etwa für Objektzähler oder dergleichen.
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Gast Gast
 2004-04-19 21:04
#81632 #81632
Ich rede tatsächlich von Klassendaten (ääähhhm - denk ich mal)

our $config # Hashref
steht innerhalb einer Klasse allen Instanzmethoden zur Verfügung.
Crian
 2004-04-19 21:13
#81633 #81633
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Und warum machst Du dann etwas in new?
Dann überschreibst Du ja auch die Daten für schon existierende Objekte.

Alternative: eine andere Klassenmethode (init ...), die diesen Hash kopiert?
Falls Du Angst hast, dass der User vergißt die aufzurufen, setz bei Dir in der Klassendefinition den Hash auf undef und stirb in new mit einem Hinweis, dass init zu verwenden wäre, falls der Wert immer noch undef ist.

Oder liege ich völlig falsch (habe nicht alles ganz genau gelesen :blush: )


Edit: Anstatt den ganzen Hash dann per get auszuhändigen, könntest Du dann getter (und ev. keine setter) dafür schreiben, das wären dann aber auch Klassen- und keine Objektmethoden.

Falls Du nicht weißt, was da alles drinstehen mag, könntest Du AUTOLOAD dafür nehmen (hab ich bisher immer vermieden, aber es geht, wie mir gerade wieder in Erinnerung gerufen wurde ;-).


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



Oder aber Du erstellst Dir eine Config-Klasse, von der Du im Hauptprogramm einObjekt verwendest, und Deine anderen Klassen verwenden dann auch ein solches Objekt, oder aber erben davonm je nachdem, was besser wäre. (Wahrscheinlich ersteres, sonst wären es ja wieder Objektdaten.)


Hmmm ... das Hauptproblem löst das aber auch nicht.\n\n

<!--EDIT|Crian|1082395378-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
<< |< 1 2 >| >> 17 Einträge, 2 Seiten



View all threads created 2004-04-17 13:01.