library тип данных библиотеки

## Описание

Из чего сделана библиотека функций, написанных на языке Scilab?

Такая библиотека сделана из директории, содержащей

- редактируемый XML-файл, который всегда называется `lib`. Этот файл содержит
  1. имя библиотеки;
  2. список имён публичных функций, принадлежащих библиотеке.
  Этот файл сгенерирован с помощью `genlib(..)`. Его нельзя сделать вручную.

- набор двоичных файлов с расширением `.bin`, чьи основные имена являются именами функций возможно зарегистрированных в файле `lib`,

- и возможно -- но это необязательно для загрузки и использования библиотеки --, `.sci`-файлы исходников, написанные на языке Scilab, чья компиляция с помощью `genlib(..)` генерирует файлы `lib` и `.bin`.

  Если файл-исходник `foo.sci` функции `foo()` не предоставлен в директории библиотеки, то `edit foo` не может править его Scilab-код и откроет пустой файл с нуля.

Загрузка / декларирование библиотеки в сессии :

`load("/path/to/lib")` загружает предназначенную библиотеку в сессию Scilab: создаётся переменная, чьё имя является именем библиотеки -- скажем `libname`. Относящийся к ней тип `type(libname)` равен 14. Её `typeof(libname)` соответствует `"library"`. Этот дескриптор библиотеки содержит

- путь к корневой директории библиотеки;
- список имён публичных функций, принадлежащих библиотеке.

Обе части могут быть получены либо с помощью функции `libraryinfo()`, либо с помощью функции `string()`.

Пример: `interpolationlib` является родной библиотекой Scilab:

    --> 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\"

Автозагрузка при первом вызове функции:

Если имя функции -- скажем, `foo()` -- принадлежащей библиотеке, вызвана в сессии, то Scilab делает следующее:

1. Является ли `foo` именем встроенной функции? Если так, то эта встроенная функция вызывается. В противном случае,

2. Является ли `foo` именем локальной переменной, возможно требуемой `foo()` (предполагая, что она уже была вызвана)? Если так, то используется эта переменная. В противном случае,

3. Сканируются все загруженные библиотеки -- в обратном алфавитному порядку имён библиотек -- для поиска `foo()`. Первая найденная "загружается" из её `.bin`-файла и, наконец, вызывается. Следующие вызовы `foo()` будут переходить к шагу №2, который будет успешным, пока дескриптор `foo` не будет удалён по ходу дела.

Без шага №3 пользовательская функция, не принадлежащая ни к одной библиотеке и поэтому в случае удаления не может быть автоматически восстановлена.

Если файл`foo.sci` изменён, когда `foo()` уже была вызвана, то перекомпиляция и перегрузка её библиотеки не обновит текущее поведение `foo()`: `foo()`, является уже известной, поэтому Scilab остановится на шаге №2 без перегрузки обновлённой библиотеки и будет использовать прежнюю `foo()`. Введение `clear foo` перед следующим вызовом `foo()` заставит Scilab перейти к шагу №3 во время следующего вызова и таким образом загрузит и будет использовать обновлённую `foo()`.

Одноимённые функции в разных библиотеках: libname.foo()

Если несколько загруженных библиотек имеют публичную функцию `foo()`, то обратный алфавитный приоритет может быть неуместным. К счастью, всегда можно заставить использовать содержимое указанной библиотеки с помощью синтаксиса разделения точкой: `libname.foo(..)` будет вызывать содержимое `foo()`, принадлежащее библиотеке `libname`.

## Примеры

`interpolationlib` является родной библиотекой Scilab:

    interpolationlib        //отображает содержимое библиотеки
    type(interpolationlib)
    [typeof(interpolationlib), typeof(interpolationlib, "overload")]
    string(interpolationlib)
    [fnames, libpath] = libraryinfo("interpolationlib")

Вывод иллюстрируется в разделе Описание выше.

Вызовы обработки одноимённых функций:

    whereis(blanks)
    clear blanks, isdef("blanks","l")
    blanks(20)          // загрузка blanks() и её вызов
    isdef("blanks","l") // она остаётся в workspace

    // Построение библиотеки с нашей собственной одноимённой функцией blanks()
    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);    // Компиляция нашей собственной библиотеки

    clear blanks
    ascii(blanks(3)) // вызывается stringlib.blanks() ⇐ "stringlib" > "mylib"
    clear blanks
    ascii(mylib.blanks(3,%t)) // принудительный вызов mylib.blanks()
    blanks(3)        // следующий вызов по умолчанию 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  =
      "   "

## Смотрите также

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

## История

6.0.0

- Библиотека теперь содержать только функции, а не переменные любого типа.
- Файл lib теперь является редактируемым XML-файлом, а не бинарным.
- Если файл исходного кода foo.sci содержит несколько последовательных блоков function/endfunction, то только определённая foo() теперь записывается в библиотеку. Остальные определённые функции теперь являются приватными и известными только из foo().