MudGuard: Rekursion - Warnung wegen Prototype...

Hi,

hab ein kleines Perlscriptchen geschrieben:

#!perl -w
use strict;
use warnings;

sub showtree($$)
{
    my $level = $_[0];
    my $dir   = $_[1];

chdir $dir  or die "can't change to dir >$dir<: $!";
    opendir(DIR, "$dir") or die "can't open dir >$dir<: $!";

my @allentries = grep { ! /^./ && ! -f "$dir/$_" } readdir(DIR);

foreach (@allentries)
    {
        print "$level$_\n";
        showtree( "$level|   ", "$dir\$_");
    }
    closedir DIR;
}

my $startdir = $ARGV[0];
showtree("", $startdir);

Es listet rekursiv alle Unterverzeichnisse auf ab dem Verzeichnis, das als erster Parameter übergeben wurde.
Das klappt auch hervorragend.

Aber:
Ich bekomme immer eine Warnung:
main::showtree() called too early to check prototype at D:\perl\dirtree.pl line 18.

Zeile 18 ist die mit dem rekursiven Aufruf.

Wie bekomme ich die Warnung weg, ohne "-w" im Aufruf oder "use strict;" bzw. "use warning;" oder den Prototype "($$)" wegzunehmen?
Das muß doch irgendwie möglich sein...

Mir ist sowieso nicht ganz klar, wieso es an dieser Stelle (lange nachdem der Prototyp feststeht) noch zu früh ist...

Vielen Dank im Voraus!

cu,
Andreas

--
Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/
  1. Halihallo MudGuard

    print "$level$_\n";
            showtree( "$level|   ", "$dir\$_");

    ersetzen durch: showtree2( "$level|  ", "$dir\$_");

    sub showtree2 ($$) {
       my ($level,$dir) = ($_[0],$_[1]);
       showtree($level,$dir);
    }

    da ist leider ein kleiner Workaround nötig, wie mir scheint.
    These: Der rekursive Aufruf muss in einem anderen Block-Scope liegen. Frag mich
    jetzt bitte nicht warum; ich könnte mir nur vorstellen, dass Perl den Prototypen nicht
    auflösen kann, wenn auf denselben Block referenziert wird...

    Es listet rekursiv alle Unterverzeichnisse auf ab dem Verzeichnis, das als erster Parameter übergeben wurde.
    Das klappt auch hervorragend.

    Wozu brauchst du das $level? - Wozu ein chdir (halte ich für unsinnvoll, denn nach dem
    Script sollte das Verzeichnis dasselbe wie vorher sein)?

    Mir ist sowieso nicht ganz klar, wieso es an dieser Stelle (lange nachdem der Prototyp feststeht) noch zu früh ist...

    ggf. ein Problem im Perlparser, wenn der Parser die Funktion parsed, wird auf sie selber
    referenziert (referenz auf nicht vollständig geparstes Codesegment scheint die
    Fehlermeldung auszulösen). Soweit zumindest meine These.

    Viele Grüsse

    Philipp

    --
    RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
    Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
    1. Hi,

      print "$level$_\n";
              showtree( "$level|   ", "$dir\$_");

      ersetzen durch: showtree2( "$level|  ", "$dir\$_");

      sub showtree2 ($$) {
         my ($level,$dir) = ($_[0],$_[1]);
         showtree($level,$dir);
      }

      Das gefällt mir aber gar nicht...

      da ist leider ein kleiner Workaround nötig, wie mir scheint.

      Wozu brauchst du das $level?

      Um entsprechend der Verzeichnistiefe einzurücken:

      root
      |   firstlevel1
      |   firstlevel2
      |   |   secondlevel1
      |   |   |   thirdlevel1
      |   |   secondlevel2
      |   firstlevel3

      usw.
      Ja, ich hätte auch einfach einen Zähler nehmen können, der im äußersten Aufruf 0 ist und bei jeder Rekursion um 1 erhöht wird...

      • Wozu ein chdir (halte ich für unsinnvoll, denn nach dem
        Script sollte das Verzeichnis dasselbe wie vorher sein)?

      Ja, das war erstmal ein quick-hack - ich könnte jeweils den kompletten Verzeichnispfad benutzen...
      Ich brauchte einfach für ein Verzeichnis eine tree-förmige Auflistung...

      Mir ist sowieso nicht ganz klar, wieso es an dieser Stelle (lange nachdem der Prototyp feststeht) noch zu früh ist...
      ggf. ein Problem im Perlparser, wenn der Parser die Funktion parsed, wird auf sie selber
      referenziert (referenz auf nicht vollständig geparstes Codesegment scheint die
      Fehlermeldung auszulösen). Soweit zumindest meine These.

      Klingt zwar plausibel, aber eigentlich steht der Prototype doch schon bei der öffnenden geschweiften Klammer nach dem sub showtree($$) fest...

      cu,
      Andreas

      --
      Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
      http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/
      1. Halihallo MudGuard

        [...]

        Das gefällt mir aber gar nicht...

        Ich weiss, mir auch nicht... :-(

        Klingt zwar plausibel, aber eigentlich steht der Prototype doch schon bei der öffnenden geschweiften Klammer nach dem sub showtree($$) fest...

        Nun ja, Parsing ist ein ziemlich hartes Unterfangen, besonders bei Perl... Wäre gut
        denkbar, dass die Prototype-definition erst nachher analysiert wird. Was mich etwas
        stärker wundert ist das Faktum, dass die Meldungen zur Laufzeit generiert werden und
        spätestens dann steht die Prototype-definition schon lange fest (zumindest die Syntax
        wurde schon zur Compiletime gechecked und analysiert).

        Na ja... :-((

        Viele Grüsse

        Philipp

        --
        RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
        Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
  2. Hallo,

    hab ein kleines Perlscriptchen geschrieben:

    #!perl -w
    use strict;
    use warnings;

    sub showtree($$)
    {
    [...]
        foreach (@allentries)
        {
            print "$level$_\n";
            showtree( "$level|   ", "$dir\$_");
        }
        closedir DIR;
    }

    my $startdir = $ARGV[0];
    showtree("", $startdir);

    [...]

    Ich bekomme immer eine Warnung:
    main::showtree() called too early to check prototype at D:\perl\dirtree.pl line 18.

    Zeile 18 ist die mit dem rekursiven Aufruf.

    [...]

    Mir ist sowieso nicht ganz klar, wieso es an dieser Stelle (lange nachdem der Prototyp feststeht) noch zu früh ist...

    <mode type="suck from my fingertips"> ;)

    perl parst Deinen Code, kann aber eine Funktion erst als definiert erkennen, wenn der zugehörige Block auch geschlossen wurde. Wird nun innerhalb des Blocks die Funktion rekursiv aufgerufen, kann perl eben nicht die Prototypen während der Kompilierzeit überprüfen, weil die Definition der Funktion noch nicht beendet ist. Ohne Prototypen ist perl ein premature functioncall equal, weil es ja nichts zur Kompilierzeit zu prüfen gibt. Es könnte höchstens ein Runtime-Error auftreten, falls es die Funktion nicht gibt.

    </mode>

    Abhilfe schafft sicherlich eine Deklaration mit 'sub showtree($$);' am Anfang des Skripts.

    Gruß Alex

    --
    http://www.google.de/search?hl=de&safe=off&q=Rechtschreibung+Standart
    ss:) zu:} ls:} fo:| de:[ va:| ch:| sh:( n4:& rl:° br:& js:| ie:| fl:| mo:}
    1. Hi,

      <mode type="suck from my fingertips"> ;)
      perl parst Deinen Code, kann aber eine Funktion erst als definiert erkennen, wenn der zugehörige Block auch geschlossen wurde. Wird nun innerhalb des Blocks die Funktion rekursiv aufgerufen, kann perl eben nicht die Prototypen während der Kompilierzeit überprüfen, weil die Definition der Funktion noch nicht beendet ist. Ohne Prototypen ist perl ein premature functioncall equal, weil es ja nichts zur Kompilierzeit zu prüfen gibt. Es könnte höchstens ein Runtime-Error auftreten, falls es die Funktion nicht gibt.
      </mode>

      Ok, ok.

      Abhilfe schafft sicherlich eine Deklaration mit 'sub showtree($$);' am Anfang des Skripts.

      Das ist es! Ich danke Dir!
      Das gefällt mir doch wesentlich besser als die Umgehung mit der zweiten Funktion...

      cu,
      Andreas

      --
      Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
      http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/