Hi, danke für die Ideen.
PS: Ein bischen mehr zum Hintergrund. Verschiedene Klassen sind bereits kompiliert und die jeweilige Instanz ist erstellt. Die Klasse soll danach um mehrere Methoden erweitert werden, das sind Methoden eines Interface, welche über die Instanz aufgerufen werden sollen. Es ergibt sich die Situation, dass mehrere, namentlich unterschiedliche Klassen dieselben Interface-Methoden verwenden können, so müssen diese Methoden nur einmal definiert werden. Letzeres erfolgt in einer Datei, welche ich bisher mit require eingebunden habe. Redundanter Code soll vermieden werden. Das ist das Ziel.
Beispiel zur Verwendung: Die Klassen
MVC::TemplateFile und
MVC::EAV liefern verschiedene Seiten aus und ein paar von denen sollen ein Rating-Formular bekommen. So könnte ich die Verwendung infolge Subklassenbildung spezialisieren:
MVC::TemplateFile::Rating;
MVC::EAV::Rating;
hätte jedoch dann zwei verschiedene Dateien in denen exakt dieselben Interface-Methoden definiert sind. In diesem Fall würde die Instanz (Response-Objekt) über die jeweilige Subklasse erstellt.
Eine spätere Zuweisung der Interface-Methoden wäre möglich über ein Attribut, wegen der Package-Deklaration wäre die Datei mit den Interface-Methoden jedoch auch wieder fest an
MVC::TemplateFile oder
MVC::EAV gekoppelt, also auch hier wieder zwei Dateien, die sich nur in der Package-Deklaration unterscheiden würden.
Die spätere Zuweisung bringt gegenüber der Subklassenbildung den Vorteil, dass dies über die WebSite-Konfiguration möglich ist. Das betrifft auch den Einbau dynamischer Inhalte über Platzhalter im Template. Meine Lösung sieht nun so aus, dass für die betreffenden Seiten, um im Beispiel zu bleiben, einfach das Attribut
interface=Rating bekommen, was dazu führt, dass die Datei
interface/Rating.pm eingelesen und vor dem Kompilieren um die Package-Deklaration
package MVC::TemplateFile;
package MVC::EAV;
ergänzt wird. Mit
state %compiled; schaffe ich einen Merker (Semaphore) welcher sicherstellt, dass die Datei mit den Interface-Methoden für die jeweilige Klasse nur _einmal_ kompiliert wird, ähnlich wie das normalerweise über
%INC erfolgt.
Sonntagsfahrer
================
Ein völlig anderer Weg führt auch zum Ziel: Anstatt einer variablen Package-Deklaration wird sie einfach weggelassen.
do "interface/$ifdatei.pm"; liefert statt einer
1; einen Hash mit Codereferenzen. Diese Codereferenzen werden dann im Namespace der jeweiligen Klasse ausgeführt. Der Hash mit den Codereferenzen wird auch hierzu nur _einmal_ in den Hauptspeicher geladen, das bringt insbesondere für
mod_perl oder
mod_fastcgi Vorteile in Sachen Performance.
Last edited: 2015-02-15 12:33:19 +0100 (CET)