Skip to content

Latest commit

 

History

History
147 lines (115 loc) · 4.13 KB

undefine.adoc

File metadata and controls

147 lines (115 loc) · 4.13 KB

undefine

since version 1.6.6

undefine can be used to undefine a macro.

Syntax

Jamal source
{@undefine macro_name}

Undefining a macro works the same way as the definition: in scope. When you undefine a macro, it will be undefined only for the current scope and later for any lower newly opened scope. Undefining a macro does not affect the definition of the macro at any higher level.

You can undefine a macro on the global level the same way as you can define a macro on the global level. Using a name that has : in it.

Simple undefine on one single scope

Jamal source
{@define fruit=apple}{fruit}{@undefine fruit} |{?fruit}|

Here we define the macro fruit to be apple, and we use it once. Following it, we undefine the macro. When we use it next time, it is undefined. The use of it is not an error because we use the ? in front of the macro name, but the result is empty.

output
apple ||

Undefine an inherited macro in a local scope

Jamal source
{@define fruit=apple}{fruit} {#ident {@undefine fruit} |{?fruit}|}  |{?fruit}|

In this example we define the macro apple on the top level scope, but we undefine it one level deeper. The macro is undefined only in the local scope, where it was undefined but on higher levels it is still defined.

output
apple ||  |apple|

Being undefined can be exported

Jamal source
{@define fruit=apple} |{fruit}|{#ident {@undefine fruit}{?fruit}|{@export fruit}}{?fruit}|

In this example we undefine the macro fruit in the local scope, but, then we export it from this scope. Being explicitly undefined can be exported the same way as the macro, which is defined. Because the "undefinedness" is exported the macro fruit becomes undefined in the enclosing scope.

output
|apple|||

Undefine, export and redefine

Jamal source
{@define fruit=apple}\
global scope: {fruit}
{@begin scope_1}\
scope_1: {fruit}
{@begin scope_2}\
scope_2: {fruit}
{@undefine fruit}{@export fruit}\
scope_2: {?fruit}
{@define fruit=pear}\
scope_2: {fruit}
{@end scope_2}\
scope_1: {?fruit}
{@end scope_1}\
global scope: {fruit}

In this example we define the macro fruit on the top level. After that we open two new scopes nested. We undefine the macro in the most inner scope, and we export this undefinedness to the middle scope. After that, we define the macro again in the most inner scope.

At this moment we have three "definition" of the macro fruit. In the outer scope it is defined to be apple. In the middle scope it is undefined. In the most inner scope it is defined to be pear.

output
global scope: apple
scope_1: apple
scope_2: apple
scope_2:
scope_2: pear
scope_1:
global scope: apple
Note

For the technically savvy, the following may help get a more comfortable grab of how the macro undefined works.

Jamal stores user-defined macros in maps. The key in the map is the id of the macro. The value in the map is a Java object that represents the user-defined macro. The maps are organized in a stack. The stack has one map for each scope. When a new scope opens in the Jamal source, the stack grows. When a scope is closed, the stack shrinks. Searching for a macro starts in the map stored at the top of the stack (opened latest). If the macro is not in the map, then the search goes deeper. The search finally finds the macro in one of the maps or runs out of stack levels.

The maps are very general in the sense that they can store any Java object that implements Identified. User-defined macros implement this interface along with UserDefinedMacro. A macro is undefined when there is no object assigned to the name in any of the maps. However, it is also undefined when the search finds an object in the stacked map structure that does not implement UserDefinedMacro. The macro undefine inserts an object into the structure that is exactly like that. Export is possible because the macro export does not care about the implemented interfaces. It merely removes the object from the map and inserts it in the map on the next stack level.