Announcement

Collapse
No announcement yet.

Unit-Reihenfolge in uses-Klauseln

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unit-Reihenfolge in uses-Klauseln

    Tag Leute.<p>
    Ich bin inzwischen schon einige Male auf folgende Situation gestossen:<br>
    Ich brauche in einer Klasse eine Referenz auf z.B. ein Graphics.TBitmap.<br>
    Also füge ich
    - ein Feld "FBitmap: TBitmap" in die Klassendeklaration,<br>
    - und "Graphics" in die uses-Klausel im interface-Teil ein.<br>
    In der Klassenimplementation benötige ich Zugriff auf die API<br>
    ==> "Windows" kommt in die uses-Klausel im implementation-Teil.
    <p>Da Windows.pas auch einen Typ TBitmap exportiert, aber nach Graphics "geused"
    wird, darf ich jetzt bei jeder Verwendung des Typs TBitmap den Qualifizierer
    "Graphics." vornedranschreiben.
    <p>Nun meine Frage: Gibt's außer der Holzhammermethode ("Windows" schon im
    interface-Teil usen, obwohl ich es dort gar nicht brauche) eine Möglichkeit,
    unit-weit vorzugeben, dass ich Graphics.TBitmap will, nicht Windows.TBitmap?
    Irgendwie glaube ich das ja nicht, aber ich wollte trotzdem mal nachgefragt
    haben, ob jemand eine Idee hat.

    Vielen Dank im Voraus,<br>
    Uli.

    <p>PS: Irgendwie erinnert mich obiges Problem an das zweier Klassen, die wechselseitig
    aufeinander verweisen sollen, aber in unterschiedlichen
    Units stehen müssen (z.B. damit Delphis Formulareditor nicht die Krise kriegt).
    Das ist ja ein gerne diskutiertes Thema, wo auch noch keiner 'ne "vernünftige"
    Lösung bringen konnte. Da müsste wohl der Compilerhersteller ran, und der will nicht. ;-)

  • #2
    Hallo Ulrich,<br>Du könntest evt. den Code Proofreader von GExperts verwenden. Der kann Dir dann automatisch das Wort TBitmap durch Graphics.TBitmap ersetzen.<br>
    http://www.gexperts.or

    Comment


    • #3
      nee, die einzigste Möglichkeit ist die Reihenfolge zu ändern. Im Falle von Windows.pas als erste im interface uses, dürfte das weniger störend sein

      Comment


      • #4
        Das ging ja fix... Danke euch beiden.<br>
        Wie's ausschaut, muss ich wohl mit solchen Kompromissen leben.
        Vom Aufwand (Qualifizierer) bzw. den Seiteneffekten (uses verschieben) her sind die Lösungen ja tragbar, aber mir gfällt's halt einfach nedd ;-)
        <p>Was mir grad so durch den Kopf schießt: Wenn ich sowas schreibe:
        <pre>
        unit Unit2;
        interface
        uses
        Graphics;

        implementation

        uses
        Windows,
        Graphics;

        end.
        </pre>
        beschwert sich der Compiler. Wäre das so schwierig gewesen, das
        zweite "Graphics" in ein "reuses" umzuinterpretieren, das außer
        einer Änderung der Lookup-Reihenfolge (oder wie auch immer das heißt) keine Wirkung hat

        Comment


        • #5
          Ich hab noch ein bißchen über meine letzte Frage/Idee nachgedacht, und mir
          ist nichts eingefallen, was dagegen spräche, sie in die Sprache einzubauen.
          <p>Sie würde zuersteinmal bestehenden Code nicht betreffen, da der das Konstrukt
          eh nicht enthalten könnte. (BTW: Kennt jemand ein kurzes und treffendes deutsches
          Gegenstück zu "wouldn't break existing code"?)
          <p>Und in die Sprache würde es sich -- glaube ich -- auch ganz gut einpassen.
          Wenn man sich folgendes Beispiel anschaut:
          <pre>
          unit Unit2;

          interface
          uses
          Graphics;

          type
          TDummy = class
          private
          FBitmap: TBitmap;
          public
          constructor Create(ABitmap: TBitmap);
          end;

          implementation
          uses
          Windows,
          //Graphics, //***
          Messages;

          { TDummy }

          constructor TDummy.Create(ABitmap: Graphics.TBitmap);
          begin
          FBitmap := ABitmap;
          end;

          end.
          </pre>
          sieht man, dass der Delphi-Compiler jetzt schon damit klarkommt,
          innerhalb *einer* Unit ein unqualifiziertes "TBitmap" mal der Unit "Windows" und mal
          der "Graphics" zuzuordnen. (Wie soll's auch anders sein.)<b>
          Würde man nun die mit //*** markierte Zeile einkommentieren, so wäre doch für die
          Interpretation durch den Compiler:
          <b>- im interface-Teil alles identisch
          <b>- die Reihenfolge der Units in der implementation-uses-Klausel innerhalb
          derselben irrelevant.
          <b>Im implementation-Teil *hinter* der uses-Klausel sind jetzt -- unabhängig von
          der Reihenfolge des "Usens" -- alle Bezeichner aus allen Units aus beiden uses-Klauseln bekannt.
          Die Reihenfolge wirkt sich ausschließlich darauf aus, welcher Bezeichner bei
          Mehrdeutigkeiten den Vorrang erhält. Hier käme dann die einzige Neuerung durch
          meine(???) Idee ins Spiel, nämlich: die letzte (statt bisher: die einzige)
          Erwähnung einer Unit zählt.
          <p>Seht ihr hier Probleme, die ich übersehen habe? Und macht das Ganze
          überhaupt Sinn? Und wenn es Sinn macht und machbar ist: Lohnt es sich,
          so etwas Borland vorzuschlagen? &lt;ggggggg&gt;
          <p>Wahrscheinlich hab ich mir all die Gedanken ja eh umsonst gemacht, weil ich da
          sicher nicht als erster draufkomme und sowieso schon jemand gemeint hat, das
          bei Borland vorzuschlagen zu müssen (und offensichtlich gescheitert ist,
          sonst wärt ihr von diesem Thread verschont geblieben).
          <br>Aber interessant finde ich's trotzdem

          Comment


          • #6
            Ich hab noch ein bißchen über meine letzte Frage/Idee nachgedacht, und mir
            ist nichts eingefallen, was dagegen spräche, sie in die Sprache einzubauen.
            <p>Sie würde zuersteinmal bestehenden Code nicht betreffen, da der das Konstrukt
            eh nicht enthalten könnte. (BTW: Kennt jemand ein kurzes und treffendes deutsches
            Gegenstück zu "wouldn't break existing code"?)
            <p>Und in die Sprache würde es sich -- glaube ich -- auch ganz gut einpassen.
            Wenn man sich folgendes Beispiel anschaut:
            <pre>
            unit Unit2;

            interface
            uses
            Graphics;

            type
            TDummy = class
            private
            FBitmap: TBitmap;
            public
            constructor Create(ABitmap: TBitmap);
            end;

            implementation
            uses
            Windows,
            //Graphics, //***
            Messages;

            { TDummy }

            constructor TDummy.Create(ABitmap: Graphics.TBitmap);
            begin
            FBitmap := ABitmap;
            end;

            end.
            </pre>
            sieht man, dass der Delphi-Compiler jetzt schon damit klarkommt,
            innerhalb *einer* Unit ein unqualifiziertes "TBitmap" mal der Unit "Windows" und mal
            der "Graphics" zuzuordnen. (Wie soll's auch anders sein.)<br>
            Würde man nun die mit //*** markierte Zeile einkommentieren, so wäre doch für die
            Interpretation durch den Compiler:
            <b>- im interface-Teil alles identisch
            <b>- die Reihenfolge der Units in der implementation-uses-Klausel innerhalb
            derselben irrelevant.
            <b>Im implementation-Teil *hinter* der uses-Klausel sind jetzt -- unabhängig von
            der Reihenfolge des "Usens" -- alle Bezeichner aus allen Units aus beiden uses-Klauseln bekannt.
            Die Reihenfolge wirkt sich ausschließlich darauf aus, welcher Bezeichner bei
            Mehrdeutigkeiten den Vorrang erhält. Hier käme dann die einzige Neuerung durch
            meine(???) Idee ins Spiel, nämlich: die letzte (statt bisher: die einzige)
            Erwähnung einer Unit zählt.
            <p>Seht ihr hier Probleme, die ich übersehen habe? Und macht das Ganze
            überhaupt Sinn? Und wenn es Sinn macht und machbar ist: Lohnt es sich,
            so etwas Borland vorzuschlagen? &lt;ggggggg&gt;
            <p>Wahrscheinlich hab ich mir all die Gedanken ja eh umsonst gemacht, weil ich da
            sicher nicht als erster draufkomme und sowieso schon jemand gemeint hat, das
            bei Borland vorzuschlagen zu müssen (und offensichtlich gescheitert ist,
            sonst wärt ihr von diesem Thread verschont geblieben).
            <br>Aber interessant finde ich's trotzdem

            Comment


            • #7
              Ich hab noch ein bißchen über meine letzte Frage/Idee nachgedacht, und mir
              ist nichts eingefallen, was dagegen spräche, sie in die Sprache einzubauen.
              <p>Sie würde zuersteinmal bestehenden Code nicht betreffen, da der das Konstrukt
              eh nicht enthalten könnte. (BTW: Kennt jemand ein kurzes und treffendes deutsches
              Gegenstück zu "wouldn't break existing code"?)
              <p>Und in die Sprache würde es sich -- glaube ich -- auch ganz gut einpassen.
              Wenn man sich folgendes Beispiel anschaut:
              <pre>
              unit Unit2;

              interface
              uses
              Graphics;

              type
              TDummy = class
              private
              FBitmap: TBitmap;
              public
              constructor Create(ABitmap: TBitmap);
              end;

              implementation
              uses
              Windows,
              //Graphics, //***
              Messages;

              { TDummy }

              constructor TDummy.Create(ABitmap: Graphics.TBitmap);
              begin
              FBitmap := ABitmap;
              end;

              end.
              </pre>
              sieht man, dass der Delphi-Compiler jetzt schon damit klarkommt,
              innerhalb *einer* Unit ein unqualifiziertes "TBitmap" mal der Unit "Windows" und mal
              der "Graphics" zuzuordnen. (Wie soll's auch anders sein.)<br>
              Würde man nun die mit //*** markierte Zeile einkommentieren, so wäre doch für die
              Interpretation durch den Compiler:
              <br>- im interface-Teil alles identisch
              <br>- die Reihenfolge der Units in der implementation-uses-Klausel innerhalb
              derselben irrelevant.
              <br>Im implementation-Teil *hinter* der uses-Klausel sind jetzt -- unabhängig von
              der Reihenfolge des "Usens" -- alle Bezeichner aus allen Units aus beiden uses-Klauseln bekannt.
              Die Reihenfolge wirkt sich ausschließlich darauf aus, welcher Bezeichner bei
              Mehrdeutigkeiten den Vorrang erhält. Hier käme dann die einzige Neuerung durch
              meine(???) Idee ins Spiel, nämlich: die letzte (statt bisher: die einzige)
              Erwähnung einer Unit zählt.
              <p>Seht ihr hier Probleme, die ich übersehen habe? Und macht das Ganze
              überhaupt Sinn? Und wenn es Sinn macht und machbar ist: Lohnt es sich,
              so etwas Borland vorzuschlagen? &lt;ggggggg&gt;
              <p>Wahrscheinlich hab ich mir all die Gedanken ja eh umsonst gemacht, weil ich da
              sicher nicht als erster draufkomme und sowieso schon jemand gemeint hat, das
              bei Borland vorzuschlagen zu müssen (und offensichtlich gescheitert ist,
              sonst wärt ihr von diesem Thread verschont geblieben).
              <br>Aber interessant finde ich's trotzdem

              Comment


              • #8
                Ich persönlich halte nichts von solchen Sprachänderungen. Die Grundidee beim PASCAL ist doch eine KLARE und EINDEUTIGE Syntax in der Programmierung durchzusetzen. D.h. wenn der Programmierer möchte das Windows.TBitmap Verwendung findet dann muß er dies EINDEUTIG zur Kenntnis geben. Ein nachheriges umdefinieren dieser Logik wiederspräche dem Konzept. So und nicht anders arbeitet C/C++, siehe Operator overloading, Templates und inline Macros. Wenn Du des öfteren C/C++ Code gelesen hast dann wirst Du sehen das es dort Gang und Gäbe ist vor jedem effektiven Codepiece jede DEFINE, INCLUDE, Templates, overloads nochmals zu definieren und die möglichen Seiteneffekt Templates, Includes, Defines wieder zu deaktivieren. C/C++ Source besteht also zu >10% nur aus Präventivsource.<br>
                Dies liegt eben ganau daran das man eine einmal getroffene Vereinbarung, sprich Source -Interface, jederzeit deaktivieren, überschreiben oder umdefinieren kann.<br>

                Nein, das generelle Problem mit Windows.TBitmap und Graphics.TBitmap liegt darin das hier die Borland-Entwickler ziemlich geschlampt haben. Es wäre in deren Aufgabe gewesen bei solchen Grundlagenunits auf EINDEUTIGKEIT zu achten !<br>

                Übrigens, ich habe mich auch schon mehrmals über diese TBitmap Problem geärgert, mittlerweile kommt Windows immer als eine der ersten Units in die uses Klausel, fertig.<br>

                Gruß Hage

                Comment


                • #9
                  Unklarer oder uneindeutiger als die jetzige Lösung (mal ganz unabhängig vom
                  konkreten Beispiel TBitmap) ist mein Vorschlag doch auch nicht.
                  <br>Andererseits seh das auch schon so, dass ich die meisten Vorteile meines
                  Vorschlags auch durch Nachobenziehen der betreffenden Unit haben kann.
                  Da ein uses im interface-Teil auch nicht den "viralen Effekt" eines #include's
                  in einem C-Header hat, gibt's in der Praxis wohl auch keine Nachteile.
                  (außer meinem verletzten ästhetisches Empfinden natürlich ;-)

                  <p><b>&lt;off-topic&gt&lt;halb-flame&gt</b>
                  <br>Von wegen Präventivsource in C/C++:<br>
                  (a) C und C++ in einem Atemzug zu nennen, ist gewagt ;-)
                  <br>(b) Soooo schlimm ist's ja nun auch nicht.
                  Die in dem Sinne gefährlichen Sachen sind eh nur die Makros, weil die kein C/C++
                  können. Deshalb benutze ich (wenn ich "C/C++" - siehe dazu (a) - programmiere
                  und die Wahl habe) zum einen kein C, und zum anderen den nicht sprachignoranten
                  Teil des "Horrorkabinetts" aus Makros, Templates, Operator overloading usw.,
                  den ich dann schön in seinen Scope einsperre. Damit ist das
                  "jederzeit deaktivieren, überschreiben oder umdefinieren" von Vereinbarungen
                  schon ganz schön eingeschränkt.
                  <br>Die Mächtigkeit von C++, die man sich mit obigen Gefahren erkauft, vermisse
                  ich in OP schon öfter mal (wenn ich z.B. gerade mit einer TList arbeite und
                  den x-ten Cast schreibe (x mind. dreistellig), bzw. mir dann DOCH noch
                  die y-te Ableitung von TList abquäle -- y nicht *unbedingt* dreistellig).
                  <br><b>&lt;/halb-flame&gt&lt;/off-topic&gt</b&gt

                  Comment


                  • #10
                    Unklarer oder uneindeutiger als die jetzige Lösung (mal ganz unabhängig vom
                    konkreten Beispiel TBitmap) ist mein Vorschlag doch auch nicht.
                    <br>Andererseits ist es schon wahr, dass ich die meisten Vorteile meines
                    Vorschlags auch durch Nachobenziehen der betreffenden Unit haben kann.
                    Da ein uses im interface-Teil auch nicht den "viralen Effekt" eines #include's
                    in einem C-Header hat, gibt's in der Praxis wohl auch keine Nachteile.
                    (außer meinem verletzten ästhetisches Empfinden natürlich ;-)

                    <p><b>&lt;off-topic&gt;&lt;halb-flame&gt;</b>
                    <br>Von wegen Präventivsource in C/C++:<br>
                    (a) C und C++ in einem Atemzug zu nennen, ist gewagt ;-)
                    <br>(b) Soooo schlimm ist's ja nun auch nicht.
                    Die in dem Sinne gefährlichen Sachen sind eh nur die Makros, weil die kein C/C++
                    können. Deshalb benutze ich (wenn ich "C/C++" - siehe dazu (a) - programmiere
                    und die Wahl habe) zum einen kein C, und zum anderen den nicht sprachignoranten
                    Teil des "Horrorkabinetts" aus Makros, Templates, Operator overloading usw.,
                    den ich dann schön in seinen Scope einsperre. Damit ist das
                    "jederzeit deaktivieren, überschreiben oder umdefinieren" von Vereinbarungen
                    schon ganz schön eingeschränkt.
                    <br>Die Mächtigkeit von C++, die man sich mit obigen Gefahren erkauft, vermisse
                    ich in OP schon öfter mal (wenn ich z.B. gerade mit einer TList arbeite und
                    den x-ten Cast schreibe (x mind. dreistellig), bzw. mir dann DOCH noch
                    die y-te Ableitung von TList abquäle -- y nicht *unbedingt* dreistellig).
                    <br><b>&lt;/halb-flame&gt;&lt;/off-topic&gt;</b&gt

                    Comment


                    • #11
                      Hoi Uli,

                      du übersiehst eigentlich nur eine Kleinigkeit. Auch Compilerentwickler sind Programmierer....und von daher aus prinzip faul.*gggggggggggggg

                      und es damit ist es klar. Eindeutige Sachen lassen sich leichter coden als mehrdeutige. Das sollteste aber langsam mal wissen.*ggg

                      Gruß

                      Uw

                      Comment


                      • #12
                        Na, wo kommt er denn so spät noch her? :-

                        Comment

                        Working...
                        X