LX-PERL-INFO-functions
Updated aug/04/2010 14:24

functions

  1. syntax

    #!/usr/bin/perl
    #
    sub funktienaam
    {
    <perl code>
    }
    <perl code>
    &funktienaam;
    <perl code>

    Een functie wordt gedeclareerd met het voorzetsel sub. Een functie wordt aangeroepen met zijn naam, voorafgegaan van het "&" teken (de ampersand). Voor functienamen gelden dezelfde regels en beperkingen als voor de namen van variabelen.

  2. voorbeeld

    In dit voorbeeld maken we een eenvoudige funktie die een horizontale lijn afdrukt.

    #!/usr/bin/perl
    #
    # fvb_1 : funktie voorbeeld 1
    #
    #subs#
    sub hlijn
    {
         print "=============================================================\n"
    }
    #main#
    print "Dit is een titel\n";
    &hlijn;
    for ($i=1; $i<=10; $i++) {
         print "En dit zijn 10 tekst regels\n"; }
    &hlijn;



  3. funkties met parameters

    Zou het niet interessant zijn de funktie hierboven ook een parameter mee te geven die de lengte van de horizontale lijn meegeeft, en het onderlijnkarakter?

    Dat kan. Die parameters zien er bijna net zo uit als in bash: $_[n] met n een getal van 0 tot ... zoveel parameters als je nodig hebt.

    In de funktie hlijn, maken we de lengte en het onderlijnkarakter variabel.
    We maken een tweede funktie tekstregels. Daarin is het aantal tekstregels, de te herhalen tekst en de regellengte variabel.

    #!/usr/bin/perl
    #
    # fvb_2 : funktie voorbeeld 2
    #
    #subs#
    sub hlijn
    {
        $lengte   = $_[0];
        $karakter = $_[1];
      # indien karakter niet is meegegeven gebruik een default "="
        if (!$karakter) { $karakter="=" }
        $lijn = $karakter x $_[0] . "\n";
        print $lijn;
    }
    sub tekstregels
    {
        $aantal = $_[0];
        $lengte = $_[1];
        $tekst  = $_[2];
        if (!$tekst) { $tekst = "En dit zijn tekstregels " }
        # de lengte van de tekst is meestal niet de gewenste lengte
        # we verlengen de tekst net zo lang tot hij langer is dan de gewenste lengte
        # hiervoor gebruiken o.a. we de interne perlfunction length
        # daarna gebruiken we de interne function substr om de tekst op de gewenste
        # lengte af te knippen

        $tekstregel = substr($tekst x ($lengte/length($tekst) +1), 0, $lengte);
        for ($i=1; $i<=$aantal; $i++) {print "$tekstregel\n"; }
    }
    #main#
    $regellengte = 80;
    $regelaantal = 20;
    @teststring="a".."z";
    $teststring=join('',@teststring);
    $lijnkarakter="_";
    print "Dit is een titel\n";
    &hlijn($regellengte,$lijnkarakter);
    &tekstregels($regelaantal,$regellengte,$teststring);
    &hlijn($regellengte); # we vergeten bewust het lijnkarakter mee te geven

    length      geeft de lengte van de string

    length STRING
    substr      deze funktie kan werken op drie manieren:

    substr (STRING,OFFSET,LEN,REPLACEMENT)
    substr (STRING,OFFSET,LEN)
    substr (STRING,OFFSET)

    offset en len zijn getallen, string en replacement zijn strings

    substr (STRING,OFFSET)
    geeft alle karakters rechts van de offset

    substr (STRING,OFFSET,LEN)
    geeft alle karakters rechts van de offset tot een lengte len

    substr (STRING,OFFSET,LEN,REPLACEMENT)
    vervangt het stuk van de string dat begint bij offset naar rechts tot een lengte len met de string replacement



  4. lokale variabelen in funkties

    Als je in het vorige voorbeeld op funkties, de hierna volgende regel helemaal onderaan het script toevoegt, zul je merken dat de variabelen die we in onze funkties gebruikt hebben globaal zijn:

    print "$lengte $karakter $aantal $tekst $lijn $tekstregel\n";

    output:

    80 = 20 abcdefghijklmnopqrstuvwxyz ==========================================================================
    abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv

    Als je dan niet goed nadenkt over de gebruikte var-namen, is de kans groot dat je vroeg of laat bestaande variabelen overschrijft.

    Je kan variabelen lokaal maken met het adjectief my:

    sub hlijn
    {
      my $lengte   = $_[0];
      my $karakter = $_[1];
      if (!$karakter) { $karakter="=" }
      my $lijn = $karakter x $_[0] . "\n";
      print $lijn;
    }
    sub tekstregels
    {
      my $aantal = $_[0];
      my $lengte = $_[1];
      my $tekst  = $_[2];
      if (!$tekst) { $tekst = "En dit zijn tekstregels " }
      my $tekstregel = substr($tekst x ($lengte/length($tekst)+1), 0, $lengte);
      for ($i=1; $i<=$aantal; $i++) {
      print "$tekstregel\n"; }
    }

    Als je nu, buiten de funkties om, de variabelen wenst te printen met

    print "$lengte $karakter $aantal $tekst $lijn $tekstregel\n";

    is er geen output meer.


  5. return value

    In onze voorbeelden met funkties, hebben we tot hiertoe funkties gebruikt die zelf standaardoutput creëerden.

    Dikwijls is het echter nodig een variabele toe te wijzen aan het resultaat van een funktie. Denk bijvoorbeeld aan de interne funktie sqrt :

    $kw=189;
    $wt=sqrt($kw); # toewijzing van resultaat sqrt in $wt
    print "de vierkantswortel van $kw is $wt \n";

    output:

    de vierkantswortel van 189 is 13.7477270848675

    Om dit te illustreren maken we in het volgende script een funktie die de faculteit berekent van een getal, zoals we dat deden in een vorig hoofdstuk:

    #!/usr/bin/perl
    #
    # ffacul: om faculteiten te berekenen vanuit een functie
    #
    sub facul
    {
         my $faculteit=1;
         my $getal=$_[0];
         for (my $x=1; $x<=$getal; $x++) { $faculteit = $faculteit * $x }
         if ($getal <=0) { $faculteit = 0 }
         $faculteit;
    }
    $a=$ARGV[0];
    if (!$a) {$a=12}
    $b=&facul($a);
    print "$a faculteit = $b \n";

    Ons exit statement is $faculteit, en dat wordt de waarde van onze toewijzing. Het lijkt een beetje vreemd, maar het is wel eenvoudig.

    output:

    $ ffacul.pl 8
    8 faculteit = 40320

  6. ampersand weglaten

    Dat mag indien er geen interne perl-function bestaat met dezelfde naam, en als de function gedeclareerd is vóór zijn aanroep! Wie Perl goed kent, kan zich hieraan wagen.

  7. argument aanpassen

    De interne functie chomp past zijn argument aan door er de linefeed af te halen. Iets dergelijks doen we als volgt:

    #!/usr/bin/perl
    #
    # vtest: een test om argumenten reverse door te geven in een funktie
    #
    sub mijnbomma   # ze heette jozefien
    {
            my $b=$_[0];
            $b = $b * $b;
            $_[0]=$b;
    }
    my $a=13;
    print "De waarde van \$a is $a\n";
    &mijnbomma($a);
    print "De waarde van \$a is $a\n";

    Een waarde plaatsen in het argument is voldoende om zijn aanroeper aan te passen!
    Het is dan ook levensgevaarlijk om in een funktie rechtstreeks met de parameters te werken ipv ze toe te wijzen aan lokale variabelen.

    output:

    $ vtest.pl
    De waarde van $a is 13
    De waarde van $a is 169