PerlSub - Release Notes


Copyright 2026-2027 by The Software Samurai.
On the web: http://www.SoftwareSam.us/
Software released under GNU GPL3, and documentation released under FDL1.3
This document describes version 0.0.01 of PerlSub.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. .
   Developed under: Perl v:5.40.3
                    libheif v:1.19.8

Description

This package includes two simple Perl scripts which demonstrate the use of subroutines in Perl.

'subtest.pl'
------------
This simple program demonstrates the use of "call-by-reference" versus "call-by-value" parameters.

'heic.pl'
---------
This is a more complex example which demonstrates the various ways Perl subroutines can be built and invoked.
The code itself is constructed as a front-end for the third-party utility program, "heif-dec" (heif-decode), which converts Apple(tm) HEIC-encoded images to other image formats.
The Perl source demonstrates subroutine access even without the external utility; however, for full functionality, "heif-dec" should be installed on the target system. See below for additional information.

'create_archive.pl'
-------------------
Also included is an example utility script used for creating distribution archives.
This Perl script takes no argments; simply navigate to the install directory and invoke the script:
cd PerlSub/install
./create_archive
This should create an archive file identical to the original archive downloaded from the website.
A useful feature is that it extracts a copy of the distro version number from the source data which is then incorporated into the name of the archive file.
Once the functionality is understood, the program structure and function can easily be adapted for any set of source files regardless of the complexity of the source tree.



Download and unpack the distribution archive.


Command-line Options for ‘heic.pl’

Usage: heic.pl SOURCE_FILE [TARGET_FILE] [OPTIONS]


Command-line Options for ‘subtest.pl’

The 'subtest.pl' example program demonstrates the syntax used for calling various subroutines, as well as the syntax used within the subroutines to access the parameters specified by the caller. In the examples shown, the labels “call” and “ref” indicate this syntax used for the individual tests.

Usage: subtest.pl [ -a | -p=WIDTH ]



Technical Notes On Perl Subroutines:

The functionality available in any Perl script depends heavily upon the version of Perl installed and the modules loaded. This script uses the standard modules available by default for the version currently installed.
The Perl version used for development of this project is: v5.40.4
The pragma used at the top of the file is: use v5.40

Calling subroutines in Perl (v5.36+)

  1. Unnamed parameters are pass-by-reference: ($_[0] is an alias for caller's variable).
    When the subroutine changes the contents of pass-by-reference, then caller's data has been changed.
    my $Apple = "original data" ;
    PolishApple ( $Apple ) ;
    print "$Apple" ;               # yields "new data"
    
    sub PolishApple
    { $_[0] = "new data" ; }
  2. Named parameters are pass-by-value: ($a is a copy of caller's variable)
    my $Apple = "original data" ;
    PolishApple ( $Apple ) ;
    print "$Apple" ;              # yields "original data"
    
    sub PolishApple ( $a )
    { $a = "new data" ; }
  3. Named pass-by-reference parameters:
    Perl syntax does not yet support named pass-by-reference; however, there is kludgy work-around:
    ($a is reference (pointer) to caller's variable, and the $$ de-references the pointer to caller's object).
    my $Apple = "original data" ;
    PolishApple ( \$Apple ) ;
    print "$Apple" ;              # yields "new data"
    
    sub PolishApple ( $a )
    { $$a = "new data" ; }
  4. Perl experimental modules (v:5.36) provide for a similar syntax for pass-by-reference which affects only the subroutine itself. (\$a is an alias for caller's variable).
    This experimental pragma is not used in heic.pl.
    use experimental 'refaliasing', 'signatures' ;
    my $Apple = "original data" ;
    PolishApple ( $Apple ) ;
    print "$Apple" ;              # yields "new data"
    
    sub PolishApple ( \$a )
    { $a = "new data" ; }
  5. Passing an array as a subroutine parameter:
    Because most Perl variables are handled as arrays, even if the array contains only one element or one scalar value, passing an array to a subroutine by reference is actually more straight-forward than non-array parameters. In the example below, four subroutines are defined and called.

    1. FruitSaladA is defined without named parameters, so any argument(s) passed to it are referenced by the default array alias: @_. This is a pass-by-reference value, so the subroutine can access each member of the caller's array using an indexing variable.
      my $buff = @_[$indxA] ;
    2. FruitSaladB is defined with one named parameter. By default, named parameters are pass-by-value.
      To put it another way, it is a a copy of the caller's data. In this example, however, a special syntax is used for the call: \@FruitBowl which indicates a pass-by-reference value which is effectively a pointer to the caller's data. The called subroutine can then use it as a pointer to the caller's array.
      $buff = $fPtr->[$indxA] ;
    3. FruitSaladC and FruitSaladD. Unlike FruitSaladB these subroutines receive not just a pointer to an array, but rather a pointer to an array of arrays. Note that the call syntax is the same as for FruitSaladB, but the parameter is defined differently within the subroutine itself.
      The functionality of FruitSaladC and FruitSaladD is identical; however, a different type of addressing is demonstrated for each:
      FruitSaladC addressess the data as an array embedded within another array (which it is).
      my $buff = $fArray[0][$indxA] ;
      FruitSaladD assigns a pointer to the first embedded array for simpler access.
      my $fPtr = @fArray[0] ;
      my $buff = $fPtr->[$indxA] ;
    Note that as an Easter Egg, the following sequence is fully functional under subtest.pl -f ('F' is for Fruit)

            my @FruitBowl = ( "Apple", "Orange", "Pear", "Peach", "Kumquat" ) ;
            FruitSaladA ( @FruitBowl ) ;
            FruitSaladB ( \@FruitBowl ) ;
            FruitSaladC ( \@FruitBowl ) ;
            FruitSaladD ( \@FruitBowl ) ;
    
            # (anonymous pass-by-reference array parameter) #
            sub FruitSaladA
            {
               my $itemCnt = scalar @_ ;     # number of elements in array
               my $indxA = $itemCnt - 1 ;
               my $indxB = 0 ;               # array item indices
               my $buff ;                    # temp buffer
    
               while ( $indxA > $indxB )     # Shuffle the elements.
               {
                  $buff = @_[$indxA] ;
                  @_[$indxA] = @_[$indxB] ;
                  @_[$indxB] = $buff ;
                  $indxA-- ;
                  $indxB++ ;
               }
            } # FruitSaladA() #
    
            # (named pass-by-reference array pointer) #
            sub FruitSaladB ( $fPtr )
            {
               my $itemCnt = scalar @$fPtr ; # number of elements in array
               my $indxA = $itemCnt - 1 ;
               my $indxB = 0 ;               # array item indices
               my $buff ;                    # temp buffer
    
               while ( $indxA > $indxB )     # Shuffle the elements.
               {
                  $buff = $fPtr->[$indxA] ;
                  $fPtr->[$indxA] = $fPtr->[$indxB] ;
                  $fPtr->[$indxB] = $buff ;
                  $indxA-- ;
                  $indxB++ ;
               }
            }  # FruitSaladB() #
    
            # (named by-reference array of arrays) #
            sub FruitSaladC ( @fArray )
            {
               my $itemCnt = @{$fArray[0]} ; # number of elements in array (note funky syntax)
               my $indxA = $itemCnt - 1 ;
               my $indxB = 0 ;               # array item indices
               my $buff ;                    # temp buffer
    
               while ( $indxA > $indxB )     # Shuffle the elements.
               {
                  $buff = $fArray[0][$indxA] ;
                  $fArray[0][$indxA] = $fArray[0][$indxB] ;
                  $fArray[0][$indxB] = $buff ;
                  $indxA-- ;
                  $indxB++ ;
               }
            }  # FruitSaladC() #
          
            # (named by-reference array of arrays) #
            sub FruitSaladD ( @fArray )
            {
               my $fPtr = @fArray[0] ;
               my $itemCnt = scalar @$fPtr ; # number of elements in array
               my $indxA = $itemCnt - 1 ;
               my $indxB = 0 ;               # array item indices
               my $buff ;                    # temp buffer
    
               while ( $indxA > $indxB )     # Shuffle the elements.
               {
                  $buff = $fPtr->[$indxA] ;
                  $fPtr->[$indxA] = $fPtr->[$indxB] ;
                  $fPtr->[$indxB] = $buff ;
                  $indxA-- ;
                  $indxB++ ;
               }
            }  # FruitSaladD() #
            
Calling subroutines in Perl v6.0  "Raku"  (Racoon?) To date, the author has had no interest in exploring Racoon; which in our view, is just another semi-useless scripting language, pretending to be a programming language. If the author changes his mind, (which hasn't happened since the introduction of C++98), we'll let you know.


HEIC Encoding and the ‘heif-dec’ image conversion utility:

High Efficiency Image Container encoding was developed by the Moving Picture Experts Group (MPEG),
ISO/IEC 23008-12. The first major player to adopt this encoding was Apple(tm) with iOS-11.

HEIC encoding (.heic extension) is now the default iPhone image format. It is technically efficient, but at this time, we aren’t sure whether we want to pollute our Linux systems with this image format.
Fortunately, the 'heif-dec' utility converts a file from .heic format to one of the following formats:
JPEG: 'jpg', 'jpeg'  - Joint Photographic Experts Group
TIFF: 'tif', 'tiff'  - Tag Image File Format
      'png'          - Portable Network Graphics
      'y4m'          - YUV4MPEG2 (uncompressed)
                       Y4M is a lossless encoding used primarily for testing codecs.
                       (the output is huge!)

Each source image file contains a magic-number sequence in the header:
1) "ftypmif1" generic version of HEIC encoding.
2) "ftypheic" indicates the specific codec used for encoding.
3) "ftypheix" indicates a "compatible" codec used for encoding

The 'heif-dec' utility is distributed as part of the 'libheif-tools' package. (Copyright © 2017 struktur AG)
The libheif package is available on GitHub or through RPM Fusion. If your system is not yet set up for 'rpmfusion', first enable it, then:
   sudo dnf install libheif-tools libheif-freeworld
      or
   sudo apt update && sudo apt install libheif-examples