library library datatype

## Description

What a library of functions written in Scilab language is made of?

Such a library is made of a directory containing

- an editable XML file always named `lib`. This file contains
  1. the name of the library
  2. the list of names of public functions belonging to the library.
  This file is generated by `genlib(..)`. It can't be made by hand.

- a set of binary files named with the `.bin` extension, whose basenames are the names of functions possibly registered in the `lib` file.

- and possibly -- but it's not mandatory to load and use the library --, the `.sci` sources files written in Scilab language, whose compilation with `genlib(..)` has generated the `lib` and `.bin` files.

  When the `foo.sci` source file of a foo() function is not provided in the library's directory, `edit foo` won't be able to edit its Scilab code, and will open a empty file from scratch.

Loading / declaring a library in the session :

`load("/path/to/lib")` then loads the targeted library in the Scilab session: a variable whose name is the library's name -- say `libname` -- is created. Its dedicated `type(libname)` is 14. Its `typeof(libname)` is `"library"`. This library's handle contains

- the path to the library's root directory
- the list of public functions names belonging to the library.

Both parts can be retrieved with either the libraryinfo() or the string() functions.

Example: `interpolationlib` is a native Scilab library:

    --> interpolationlib
     interpolationlib  =

    Functions files location : SCI\modules\interpolation\macros\.
    interp1  mesh2d  interpln  smooth

    --> type(interpolationlib)
     ans  =
       14.

    --> [typeof(interpolationlib), typeof(interpolationlib, "overload")]
     ans  =
      "library"  "f"

    --> string(interpolationlib)
     ans  =
      "SCI\modules\interpolation\macros\"
      "interp1"
      "mesh2d"
      "interpln"
      "smooth"

    --> [fnames, libpath] = libraryinfo("interpolationlib")
     fnames  =
      "interp1"
      "mesh2d"
      "interpln"
      "smooth"

     libpath  =
      "SCI\modules\interpolation\macros\"

Autoloading when first calling a function:

When the name of a function -- say `foo()` -- belonging to the library is called in the session, Scilab does the following:

1. Is `foo` the name of a builtin function? If so, this builtin is called. Otherwise,

2. Is `foo` the name of a local variable, possibly the required foo() (provided that it has been already called)? If so, this variable is used. Otherwise,

3. All loaded libraries are scanned -- in anti-alphabetical order of libraries names -- for the searched foo(). The first found is then "loaded" from its `.bin` file, and finally called. Next calls to foo() will then go up to the step #2 that will be successful, unless the `foo` handle has been cleared in the meantime.

Without the step #3, a user's function not belonging to any library and that would be cleared can not be automatically retrieved.

If the `foo.sci` file is modified while foo() has been already called, then recompiling and reloading its library won't update the current foo() behavior: foo() being already known, Scilab will stop at the step #2, without reloading the updated library, and will use the former foo(). Entering `clear foo` before the next call to foo(..) will force Scilab going up to the step #3 during the next call, and so load and use the updated foo().

Homonymous functions in distinct libraries: libname.foo()

If several loaded libraries have a foo() public function, the anti-alphabetical priority can be unrelevant. Fortunately, it is always possible to force to use the instance of a given library, with the dot-name's resolution syntax: `libname.foo(..)` will call the foo() instance belonging to the `libname` library.

## Examples

`interpolationlib` is a native Scilab library:

    interpolationlib        //displays the contents of the library
    type(interpolationlib)
    [typeof(interpolationlib), typeof(interpolationlib, "overload")]
    string(interpolationlib)
    [fnames, libpath] = libraryinfo("interpolationlib")

The output is illustrated in the above Description section.

Handling calls of homonymous functions:

    whereis(blanks)
    clear blanks, isdef("blanks","l")
    blanks(20)          // loads blanks() and calls it
    isdef("blanks","l") // It stays in the workspace

    // Building a library with our own homonymous blanks() function
    libDir = fullfile(TMPDIR, "mylib");
    code = ["function r = blanks(n, nbsp)"
            "    if nbsp, r = part(ascii(160),ones(1,n)),"
            "    else r = ""ABC"","
            "    end"
            "endfunction" ];
    mkdir(libDir);
    mputl(code, libDir + filesep() + "blanks.sci");
    genlib("mylib", libDir);    // Compiling our own library

    clear blanks
    ascii(blanks(3)) // stringlib.blanks() is called ⇐ "stringlib" > "mylib"
    clear blanks
    ascii(mylib.blanks(3,%t)) // forced call to mylib.blanks()
    blanks(3)        // Next call is with the default stringlib.blanks()

    --> whereis(blanks)
     ans  =
      "stringlib"

    --> clear blanks, isdef("blanks","l")
     ans  =
      F

    --> blanks(20)          // loads blanks() and calls it
     ans  =
      "                    "
    --> isdef("blanks","l") // It stays in the workspace
     ans  =
      T

    --> // Building a library with our own homonymous blanks() function
    --> libDir = fullfile(TMPDIR, "mylib");
    --> code = ["function r = blanks(n, nbsp)"
      >         "    if nbsp, r = part(ascii(160),ones(1,n)),"
      >         "    else r = ""ABC"","
      >         "    end"
      >         "endfunction" ];
    --> mkdir(libDir);
    --> mputl(code, libDir + filesep() + "blanks.sci");
    --> genlib("mylib", libDir);    // Compiling our own library

    --> clear blanks
    --> ascii(blanks(3)) // stringlib.blanks() is called ⇐ "stringlib" > "mylib"
     ans  =
       32.   32.   32.

    --> clear blanks
    --> ascii(mylib.blanks(3,%t)) // forced call to mylib.blanks()
     ans  =
       194.   160.   194.   160.   194.   160.

    --> blanks(3)        // Next call is with the default stringlib.blanks()
     ans  =
      "   "

## See also

- load
- lib
- genlib
- libraryinfo
- string
- whereis
- librarieslist

## History

6.0.0

- A library can now contain only functions, no longer any variables of other types.
- The lib file is now an editable XML file, no longer a binary one.
- When a foo.sci source file contains several consecutive function/endfunction blocks, only the defined foo() is now registered in the library. Other defined functions are now private and known only from foo().