6.15 Import

While Asymptote provides many features by default, some applications require specialized features contained in external Asymptote modules. For instance, the lines

access graph;
graph.axes();

draw x and y axes on a two-dimensional graph. Here, the command looks up the module under the name graph in a global dictionary of modules and puts it in a new variable named graph. The module is a structure, and we can refer to its fields as we usually would with a structure.

Often, one wants to use module functions without having to specify the module name. The code

from graph access axes;

adds the axes field of graph into the local name space, so that subsequently, one can just write axes(). If the given name is overloaded, all types and variables of that name are added. To add more than one name, just use a comma-separated list:

from graph access axes, xaxis, yaxis;

Wild card notation can be used to add all non-private fields and types of a module to the local name space:

from graph access *;

Similarly, one can add the non-private fields and types of a structure to the local environment with the unravel keyword:

struct matrix {
  real a,b,c,d;
}

real det(matrix m) {
  unravel m;
  return a*d-b*c;
}

Alternatively, one can unravel selective fields:

real det(matrix m) {
  from m unravel a,b,c as C,d;
  return a*d-b*C;
}

The command

import graph;

is a convenient abbreviation for the commands

access graph;
unravel graph;

That is, import graph first loads a module into a structure called graph and then adds its non-private fields and types to the local environment. This way, if a member variable (or function) is overwritten with a local variable (or function of the same signature), the original one can still be accessed by qualifying it with the module name.

Wild card importing will work fine in most cases, but one does not usually know all of the internal types and variables of a module, which can also change as the module writer adds or changes features of the module. As such, it is prudent to add import commands at the start of an Asymptote file, so that imported names won’t shadow locally defined functions. Still, imported names may shadow other imported names, depending on the order in which they were imported, and imported functions may cause overloading resolution problems if they have the same name as local functions defined later.

To rename modules or fields when adding them to the local environment, use as:

access graph as graph2d;
from graph access xaxis as xline, yaxis as yline;

The command

import graph as graph2d;

is a convenient abbreviation for the commands

access graph as graph2d;
unravel graph2d;

Except for a few built-in modules, such as settings, all modules are implemented as Asymptote files. When looking up a module that has not yet been loaded, Asymptote searches the standard search paths (see Search paths) for the matching file. The file corresponding to that name is read and the code within it is interpreted as the body of a structure defining the module.

If the file name contains nonalphanumeric characters, enclose it with quotation marks:

access "/usr/local/share/asymptote/graph.asy" as graph;

from "/usr/local/share/asymptote/graph.asy" access axes;

import "/usr/local/share/asymptote/graph.asy" as graph;

If Asymptote is compiled with support for libcurl, the file name can even be a URL: import "https://raw.githubusercontent.com/vectorgraphics/asymptote/HEAD/doc/axis3.asy" as axis3;

It is an error if modules import themselves (or each other in a cycle). The module name to be imported must be known at compile time.

However, you can import an Asymptote module determined by the string s at runtime like this:

eval("import "+s,true);

To conditionally execute an array of asy files, use

void asy(string format, bool overwrite ... string[] s);

The file will only be processed, using output format format, if overwrite is true or the output file is missing.

One can evaluate an Asymptote expression (without any return value, however) contained in the string s with:

void eval(string s, bool embedded=false);

It is not necessary to terminate the string s with a semicolon. If embedded is true, the string will be evaluated at the top level of the current environment. If embedded is false (the default), the string will be evaluated in an independent environment, sharing the same settings module (see settings).

One can evaluate arbitrary Asymptote code (which may contain unescaped quotation marks) with the command

void eval(code s, bool embedded=false);

Here code is a special type used with quote {} to enclose Asymptote code like this:

real a=1;
code s=quote {
  write(a);
};
eval(s,true);        // Outputs 1

To include the contents of an existing file graph verbatim (as if the contents of the file were inserted at that point), use one of the forms:

include graph;

include "/usr/local/share/asymptote/graph.asy";

To list all global functions and variables defined in a module named by the contents of the string s, use the function

void list(string s, bool imports=false);

Imported global functions and variables are also listed if imports is true.