[SparForte][Banner]
[Top Main Menu] Intro | Tutorials | Reference | Packages | Examples | Contributors   [Back Page]      [Next Page]  

Interpreter Directives

Pragmas, or interpreter directives, provide additional instructions to AdaScript. This section also contains information on importing variables to and exporting variables from other software, such as the operating system environment.

The Pragmas

  pragma ada_95
  pragma advise( from, message )
  pragma annotate( [type,]"text" )
  pragma assert( condition )
  pragma assumption( referenced )
  pragma assumption( written )
  pragma clarify( from, message )
  pragma debug( `commands` )
  pragma depreciated/deprecated( "newscript" )
  pragma dispute( from, message )
  pragma error( "message" )
  pragma export( shell | local_memcache | memcache | session , var )
  pragma export_json( shell | local_memcache | memcache | session , var )
  pragma gcc_errors
  pragma import( shell | cgi | local_memcache | memcache | session, var )
  pragma import_json( shell | cgi | local_memcache | memcache | session, var )
  pragma inspect( var )
  pragma inspection_peek
  pragma inspection_point
  pragma license( license_name [, extra] )
  pragma no_command_hash
  pragma prompt_script( `commands` )
  pragma propose( from, message )
  pragma refactor( from, message )
  pragma restriction( no_annotate_todos )
  pragma restriction( annotations_not_optional )
  pragma restriction( no_auto_declarations )
  pragma restriction( no_external_commands )
  pragma restriction( no_memcache )
  pragma restriction( no_mysql_database )
  pragma restriction( no_postgresql_database )
  pragma restriction( no_unused_identifiers )
  pragma session_export_script( `commands` )
  pragma session_import_script( `commands` )
  pragma software_model( model_name )
  pragma suppress( word_quoting )
  pragma suppress( all_todos_on_release )
  pragma suppress( low_priority_todos_on_release )
  pragma template( css|html|js|json|text|wml|xml [, path] )
  pragma todo( to, story, measure, units, priority, units [, ticket] )
  pragma test( condition )
  pragma test_result( condition )
  pragma unchecked_import( shell | cgi | local_memcache | memcache | session, var )
  pragma uninspect( var )
  pragma unrestricted_template( css|html|js|json|text|wml|xml [, path] )
  pragma volatile( var )

Help Command: The List of Pragmas

The name of the pragma, and any argument identifier not in quote marks, are not treated as constants and do not have to be declared. The arguments are specific to the pragmas they refer to.

If a pragma is not recognized, it is treated as an error.

Ada: If a pragma is not recognized, it is ignored by Ada.

pragma annotate( summary, "arraysum" );
pragma annotate( description, "Compute the sum and product of an array of integers." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Sum_and_product_of_an_array" );
pragma annotate( author, "Ken O. Burtch" );

pragma license( unrestricted );

pragma software_model( shell_script );
pragma restriction( no_external_commands );
 

Example: An example of pragmas

Pragma Expressions

Some pragmas may use an expression. Depending on the pragma, the expression can be either a normal expression or a static expression.

If the pragma takes effect when a script is loaded, or if the pragma may be interpreted by the help command, the expression must be static. A static expression is one that can be computed before the program is loaded, one that uses only literals or system-defined constants. User-defined variables, constants and functions cannot be used since those things don't yet exist.

If the pragma takes effect when a script is running, and it is not interpreted by the help command, the expression can be a normal expression. User-defined variables, constants and functions can be used.

Pragma Blocks

A group of consecutive pragmas can be declared in a pragma block. A pragma block starts with "pragma is" and ends with "end pragma".

Pragma Chains

Pragmas can be repeated by chaining them together using @. Chains can be used with both standalone pragmas and pragma blocks.

pragma is
  annotate
    ( summary, "arraysum" ) @
    ( description, "Compute the sum and product of an array of integers." )@
    ( see_also, "http://rosettacode.org/wiki/Sum_and_product_of_an_array" )@
    ( author, "Ken O. Burtch" );

  license( unrestricted );

  software_model( shell_script );
  restriction( no_external_commands );
end pragma;
 

Example: An example of pragma block with a pragma chain

Architectural Pragmas

Interpreter directives addressing business concerns, data design, application design, technical design / use-of-hardware or the overall vision of a project. This includes portability, standards compliance, licensing and feature restriction.

  • pragma ada_95 - requires the script syntax be as close to Ada 95 as possible, otherwise errors will occur.
  • pragma deprecated( "newscript" ) - another name for pragma depreciated.
  • pragma depreciated( "newscript" ) - when script finishes execution, SparForte will warn that the script is obsolete and has been superceded for "newscript". The script name can be a static string expression.
  • pragma license( license_name [, "extra"] ) - declare the license for the script. license_name can be:
    • agpl - Affero GPL
    • apache - Apache Software License v1.0
    • apache_2 - Apache Software License v2.0
    • artistic - Artistic License
    • bsd_original - BSD License (Original)
    • bsd_revised - BSD License (Revised)
    • commercial - A commercial license
    • freeware- A freeware license
    • gpl - GNU General Public License
    • gplv2 - GNU General Public License v2.0
    • gplv3 - GNU General Public License v3.0
    • mit - MIT License
    • public_domain - Public Domain
    • restricted - An restricted license
    • shareware - A shareware license
    • unrestricted - An unrestricted license
    If extra exists, it is a string further describing the license (for example, commercial/"trial license" or commercial/"15 users". The extra string can also be a URL to a complex license. Only one license is permitted. The name can be read from the System package.
    GCC Ada: unrestricted, gpl and unrestricted are recognized by Ada. It doesn't support the extra string. It treats these as levels and will try to validate license compatibility where possible.
  • pragma restriction( annotations_not_options ) - if no pragma annotate's are in the script, report an error after the script runs. This is indended as a way to require developers to write documentation.
  • pragma restriction( no_annotate_todos ) - if pragma annotate todo is used, report an error after the script runs. This is intended for use in UAT or production environments where all "todo" work should be completed earlier.
  • pragma restriction( no_auto_declarations ) - disable automatic declaration at the command prompt
  • pragma restriction( no_external_commands ) - disable operating system commands. Provides portability by ensuring no commands besides SparForte's built-in commands are executed. Useful for applications using SparForte as a run-time scripting language and not for shell scripting.
  • pragma restriction( no_memcache ) - disable connections to memcached. Doesn't prevent other programs from using Memcache.
  • pragma restriction( no_mysql_database ) - disable connections to a MySQL database. Doesn't prevent the mysql client or other programs from using MySQL.
  • pragma restriction( no_postgresql_database ) - disable connections to a PostgreSQL database. Doesn't prevent the psql client or other programs from using PostgreSQL.
  • pragma restriction( no_unused_identifiers ) - normally in testing mode, SparForte will not check enumerated types to see if they are mentioned. Often the type name is not used, or not all item names are explicitly used. However, using this pragma will check to ensure every enumerated type and item is used at least one time.
  • pragma software_model( model_name ) - declare the general software pattern or model best describing this script. model_name can be:
    • application_desktop - a mouse-and-windows application
    • application_mobile - application for a small device
    • application_realtime - an application with strict time constraints
    • application_realtime_ravenscar - an application with strict time constraints adhering to the Ravenscar model
    • daemon - a server that is not an HTTP server
    • daemon_proxy - a server proxy that is not an HTTP proxy
    • http_framework - a web development library
    • http_service_external - public facing web service
    • http_service_internal - private web service
    • http_site_external - public facing web site or page
    • http_site_internal - private/intranet web site or page
    • http_proxy - a web service to direct or cache requests
    • http_form - a web script to do data entry
    • package - a library
    • shell_batch - a script to control a process
    • shell_filter_script - a script that uses standard input and output to transform data
    • shell_report_script - a script generating text reports
    • shell_script - that is, a command script
    • multimedia - media players or games
    • etl - extract, transform, load. that is, data conversion
    • monitor - a service that monitors activity
    • driver - a device driver
    Only one software model is permitted. The name can be read from the System package.
  • pragma suppress( low_priority_todos_on_release ) - allow a project with low priority pragma todo's to pass in testing and maintenance SDLC modes. Otherwise, any todo's with non-zero priorities or sizes are not allowed in these modes.
  • pragma suppress( all_todos_on_release ) - allow all todo's to pass in testing and maintenance SDLC modes. This was mainly added to aid testing the language.

Debugging Pragmas

Interpreter directives used to investigate problems in the source code or used with SparForte's breakout prompt, or directives to suppress certain error messages.

  • pragma assert( expression ) - evaluates the expression. If it isn't true, the program stops and "assertion failed" is displayed. Use this to check the expected results during development. Requires --debug or --test options or asserts will have no effect.
  • pragma assumption( used, var ) - assume a variable is used in the source code, even if it isn't, for unused variable errors. This is to be used as a work-around if the language makes a mistake.
  • pragma assumption( written, var ) - assume a variable is written to in the source code, even if it isn't, for constant/variable errors. This is to be used as a work-around if the language makes a mistake.
  • pragma debug( `commands` ) - these are a set of debugging commands to run when debugging mode (the --debug option) is turned on with --debug.  Make sure the final command ends with a semi-colon. Without a parameter, same as --debug (turn on debugging). The debugging commands are run in restricted shell mode. Because this is a pragma, it can be placed in variable declarations or other places executable statements are not normally allowed.
  • pragma gcc_errors - same as --gcc-errors.  Show simplified gcc-style errors.
  • pragma inspect( var ) - show a variable's description (as if 'env var' was used) whenever a user breaks to a command prompt. Has no effect if --break option isn't used.
  • pragma inspection_peek - like inspection_point, displaying inspect variables, except it doesn't break to a command prompt.
  • pragma inspection_point - break to a command prompt as if SIGINT (control-C) was received, displaying the call stack and any variables marked for inspection with pragma inspect. Has no effect if --break option isn't used. A "breakpoint".
  • pragma suppress( word_quoting ) - disable style errors when dollar variables expansions are not double-quoted. Dollar expansions should almost always be quoted to prevent whitespace from creating extra shell words. However, when porting shell scripts, it can be helpful to allow unquoted expansions. (e.g. "echo $HOME" will no longer be reported as an error.)
  • pragma test( `commands` ) - these are a set of testing commands to run when test mode (the --test option) is used. For example, this can be used to help with unit testing. Because this is a pragma, it can be placed in variable declarations or other places executable statements are not normally allowed. Make sure the final command ends with a semi-colon.
  • pragma test_result( expression ) - evaluates the expression. If it isn't true, a "test failed" message is written to standard error. (The format of the message is affected by --gcc-errors.) Use this to check the results in automated tests. Requires --test option or asserts will have no effect.
  • pragma uninspect( var ) - undo a pragma inspect. Don't show a variable's description whenever a user breaks to a command prompt. Has no effect if --break option isn't used.

Documentation Pragmas

Interpreter directives used to describe a project, particularily real world concerns that are not expressed in the source code.

  • pragma annotate( [type,] text ) - embed a comment. The contents of any or all annotate pragmas are shown when you use the help command on a script. The text is a static string expression. Type type of annotation field can be:
    • author - who wrote the script. (This cannot be a team.member variable
    • bugs - known bugs
    • created - when the script was first released
    • category - a user string to organize scripts into groups
    • description - a detailed description of what the script does
    • errors - errors returned from the script
    • modified - when the script was last modified
    • param - description of a parameter to the script
    • return - return value
    • see_also - a reference to another document or script
    • summary - a short description of what the script does
    • todo - unfinished work
    • version - the version of the script

Annotations are used by the help command to produce documentation.

Implementation Note: author cannot be a team.member variable because the help command scans to source for pragmas and doesn't actually perform variable declarations.

Teamwork Pragmas

These pragmas assist in team communication and code reviews. They act as comments and have no effect on the executing of the program.

  • advise - a request by a developer for assistance or advice from another developer or the team
  • blocked - the developer informs the team that progress is blocked pending the completion of another requirements or availability of a resource
  • clarify - a request for clarification or explanation to a developer or the team
  • dispute - a disagreement by a programmer to be discussed by the team
  • propose - suggest discussion on a new feature or another program change
  • refactor - a request to optimize existing, working programming, or the removal of dead/obsolete programming

These pragmas all take three parameters. The first identifies who placed the pragma (a variable of type team.member). The second is the person to whom it is addressed (a variable of type team.member). The third is a static string expression containing the message.

  team : team.member;
  amy : team.member;
  ken : team.member;
  ...
  pragma advise( ken, team, "i need some advice on memcached" );
 

Example: An example of pragma advise

During a code review, new work can be marked in the source code with pragma todo.

  • The first parameter is the person to whom the task is assigned
  • The second parameter is a static string expression describing the task
  • The third parameter is the unit of work (of type team.work_measure)
  • The fourth parameter is the amount of work
  • The fifth parameter is the unit of priority (of the type team.work_priority)
  • The sixth parameter is the priority rating
  • The seventh parameter, optional, is the ticket id for an external work tracking system.

  team : team.member;
  amy : team.member;
  ken : team.member;
  ...
  pragma todo( amy, "save the user session state", work_measure.story_points, 2, work_priority.severity, 3 );
 

Example: An example of pragma todo

work_measure.size must use a string literal with a legitimate size ( "s", "m", etc.).

work_priority.level must use a character literal with a legitimate level ( 'l', 'm', etc.).

work_priority.severity must be in the range 1..5

work_priority.risk is a natural amount of money

work_priority.cvss is a float score in the range 0.0..10.0

work_measure.unknown or work_priority.unknown must have an amount/ranking of zero.

Negative values are not allowed.

For the SDLC, test mode or maintenance mode will report an error ("priority todo task not yet completed") for any todo with a known size and priority that isn't finished. If you use pragma suppress( low_priority_todos_for_release ), only moderate or high priority todo's will produce this error. These are todo's with:

  • a priority level greater than low
  • a priority severity greater than 2
  • a priority risk greater than 0 (AdaScript doesn't know how much finanical risk is acceptable)
  • a priority CVSS score greater than 4.0

pragma suppress( all_todos_for_release ) stops checking for all todo's.

Teamwork and work estimation pragmas can be displayed using the help command.

Implementation Note: This feature is experimental. The parameters may be changed to improve these features.

Interfacing Pragmas

Interpreter directives that affect SparForte's environment or how it interacts with other software.

  • pragma export( shell | local_memcache | memcache | session, var ) - export a string variable to the O/S environment or memcached.
  • pragma export_json( shell | local_memcache | memcache | session, var ) - export a string, numeric, enumerated item, array or record variable as a JSON string to the O/S environment or memcached.
  • pragma import( shell | cgi | local_memcache | memcache | session, var ) - import a variable. For shell, from the O/S environment. For cgi and if pragma template/unrestricted_template was used previously, a HTTP CGI variable from the O/S environment. For local_memcache, get the value of the variable from a memcached server running on locahost port 11211. Put the value in the SparForte variable. If the environment variable doesn't exist, then the SparForte will report an error (see unchecked_import).
  • pragma import_json( shell | cgi | local_memcache | memcache | session, var ) - import a JSON string, converting it to a string, numeric, enumerated item, array or record variable.
  • pragma no_command_hash - SparForte normally remembers the location of a command once it has found it.  This pragma forces SparForte to search for the location of the command, ignoring the previous location.
  • pragma register_memcache_server( host, port ) - add a memcache server which will be used with memcache method imports/exports
  • pragma session_export_script( `script` ) - define a callback to write a session variable. The callback will be run as required by the language for all session export variables. Two temporary variables, session_variable_name and session_variable_value will be defined for the script to use.
  • pragma session_import_script( `script` ) - define a callback to read a session variable. The callback will be run as required by the language for all session import variables. Two temporary variables, session_variable_name and session_variable_value will be defined for the script to use. Update the value in session_variable_value.
  • pragma template( css|html|js|json|text|wml|xml [, template] ) - SparForte will act like a template processor (like PHP). When the script finishes executing, SparForte will open a file called "file.tmpl" where file is the name of the script. If an alternate file path is included in the pragma, that file is used as the template instead. A HTTP header is written and SparForte parses the template along with any embedded scripts. For security, the embedded scripts in the template will be run in a restricted shell and with the no_external_commands restriction. Errors shown in the output are affected by --gcc-errors, but errors written to standard error are always in --gcc-errors. Errors occurring in a template are shown using the line number in the template as the line number for the error. The first parameter is the template type: "css" (a style sheet), "html" (HTML web page), "js" (Javascript script), "json" (JSON encoded text), "text" (plain text), "wml" (WML text) or "xml" (XML text). The position of this pragma affects how errors are reported: SparForte doesn't know the script has a template until this pragma is read so while it can be placed anywhere it is best to place it early in a script.
  • pragma unchecked_import( shell | cgi | local_memcache | memcache | session, var ) - import a variable. For shell, from the O/S environment. For cgi and if pragma template/unrestricted_template was used previously, a HTTP CGI variable from the O/S environment. For local_memcache, get the value of the variable from a memcached server running on locahost port 11211. Put the value in the SparForte variable. If the import variable doesn't exist, then the SparForte variable is unchanged.
  • pragma unchecked_import_json( shell | cgi | local_memcache | memcache | session, var ) - the same as import_json execpt that there is no existence check. If the import variable doesn't exist, then the SparForte variable is unchanged.
  • pragma unrestricted_template( css|html|js|json|text|wml|xml [, template] ) - SparForte will act like a template processor (like PHP). This pragma is the same as pragma template except that the embedded scripts are executed in a normal shell with no security restrictions. The type parameter is described under pragma template.
  • pragma volatile( var ) - the variable is assumed to be an variable which may change unexpectedly during the script's execution. The variable's value will be updated each time it is referenced in an expression. Has no effect unless the variable is imported as well.

Miscellaneous Pragmas

Interpreter directives that don't fit in any other category.

  • pragma prompt_script( `commands` )

    This pragma specifies a set of commands to run that will draw the command prompt. The commands run in a restricted shell. By default, the prompt will be in boldface.

    There are no special escape sequences like those used by Bash. Instead, the prompt is created by running normal AdaScript commands. Some common tasks:

    • Your username - import LOGNAME or USER from the O/S environment.
    • Your current directory - use the pwd command or the PWD variable
    • No boldface - use tput sgr0
    • To use colour - use the character codes for your terminal (usually ANSI)
    • To restore the default prompt - use an empty command list

    Here are some examples:

    => pragma prompt_script( `put( "$ ");` );
    $
    $ type import_string is new string;
    $ LOGNAME : import_string;
    $ pragma import(shell, LOGNAME )
    $ pragma prompt_script( `put( LOGNAME ) @ ( "$ ");` );
    ken$
    ken$ pragma prompt_script( `put( PWD ); new_line; put( LOGNAME ) @ ( "$ " );` );
    /home/ken
    ken$
    /home/ken
    ken$ ANSI_RED : constant string := ASCII.ESC & "[0;31m";
    /home/ken
    ken$ ANSI_DEFAULT : constant string := ASCII.ESC & "[0m";
    /home/ken
    ken$ pragma prompt_script( `new_line; put( ANSI_RED ); date; put( ANSI_DEFAULT ) @ ("$ " );` );

    Sat Jan 2 21:52:59 EST 2016
    $

    Sat Jan 2 21:53:05 EST 2016
    $ pragma prompt_script( `` );
    =>
     

    Example: Examples of pragma prompt_script

    Make sure the final command ends with a semi-colon. Changing your prompt will also change the title of your terminal window.

    Of course, the pragma can be placed in a profile file so it is set each time you start SparForte.

  • pragma error( static-expression ) - always raise an error with the static expression in the message.

Shell Variables

UNIX-like operating systems have environment variables. These are variables that the operating system assign to your running program.

You can also read environment variables using the command_line package.

Importing Shell Environment Variables

Normally, SparForte will not copy your environment variables into SparForte. Instead, you request the variables using pragma import. SparForte will examine the environment variables and, if it finds one with the same name, the SparForte variable will have the same value as the environment variable.

=> JAVA_HOME : import_string
=> pragma import( shell, JAVA_HOME )
=> ? JAVA_HOME
/usr/lib64/jvm/java
 

Example: Importing an environment variable on the command line

A few variables are automatically imported when SparForte runs. These variables are needed for the proper functioning of the shell (for example, HOME). You can also use the --import-all command line option to import all the environment variables. However, --import-all is meant to be a convenience or debugging tool: it is a better technique to import only what your script needs to run.

You can examine a variable with env to see if it is imported or exported.

=> env HOME
HOME := "/home/ken"; -- imported shell environment identifier of the type string

If the variable doesn't exist, SparForte will report an error. This behaviour can be overridden using pragma unchecked_import: if the variable doesn't exist in the environment, the value will be unchanged. It is a good idea to assign a default value.

With SparForte 2.0, the type of the variable must not be a predefined type (or a subtype of one). SparForte assumes that the data being imported should be considered untrusted and unvalidated. You should use a new data type for the variable and not convert it to a predefined type unless the value has been checked and approved. This restriction is not on an unchecked_import.

If you are using SparForte as your login shell, there is nothing to import: there's no previous shell to import variable from to put them into SparForte.

Exporting Shell Environment Variables

To make your Sparforte variables visble to other programs, such as external commands, you must export the variable into the operating system environment variables with pragma export. This exporting process occurs whenever an external command is executed, the standard technique in shells.

=> JAVA_HOME : string := "/usr/lib64/jvm/java"
=> pragma export( shell, JAVA_HOME )
=> eclipse & -- a command that needs JAVA_HOME

If you use SparForte as your login shell, variables like JAVA_HOME can be set up in your SparForte profile file so they are created and exported whenever you log in.

Both Importing and Exporting, and Volatile Shell Environment Variables

Environment variables can be both imported and exported by using both pragmas.

=> DISPLAY : string;
=> pragma import( shell, DISPLAY )
=> pragma export( shell, DISPLAY )
=> env DISPLAY
DISPLAY := ":0.0"; -- imported exported shell environment identifier of the type string
 

Example: Importing and Exporting the X Windows DISPLAY variable

Pragma volatile will mark a variable as "volatile", meaning that its value can change unexpectedly and SparForte should reload the value from the environment whenever it is referenced. Although you can make volatile environment variables, it probably won't be useful: these variables are owned by the running process, which is SparForte, so it is virtually impossible to change their values except using the SparForte itself.

CGI Variables

CGI variables are the HTTP FORM tag variables submitted from a web page. If you are in a web template (if you used pragma template or pragma unrestricted_template), you can read the variables using pragma import.

If the variable doesn't exist, SparForte will report an error. This behaviour can be overridden using pragma unchecked_import: if the variable doesn't exist in the environment, the value will be unchanged. It is a good idea to assign a default value.

You cannot export CGI variables: there's nowhere to export the values to.

Pragma volatile can be used, but like shell variables, it has no meaningful effect: the CGI variables will not change while in a template.

You can also read CGI variables using the CGI package.

Session Variables

Session variables are variables that specific to a user's session. These are typically used to define session for web applications.

Since session variables can be stored in many different ways (files or databases, for example), AdaScript does not implement the storage mechanism. Instead, it will run user callback scripts whenever it needs to read or write a session variable. The scripts are responsible for loading or saving the variable.

For a typical web application, you will want create and manage some kind of session identifier, the variable name, value and when the session was started (so you can automatically expire old sessions.)

To use session variables, define the import and export callback scripts using pragma session_export_script and pragma session_import_script. There can be only one callback of each type in a program. Defining a session variable before these are defined may cause an error. Keep in mind these callbacks may be executed for global variables before the main program is run, or before all variables are intialized.

When the callbacks are run, there are two variables in the sessions package that are used as parameters: sessions.session_variable_name and sessions.session_variable_value. The first contains the name of the variable to be updated. The second contains the current value (on export) or can be written to to save the value (on import).

Then create your session variables using an import-type or export-type pragma, using a import method of "session".

pragma unchecked_import behaves the same as pragma import since SparForte isn't able to check itself for the variable's existence.

pragma volatile can be used to re-read the value whenever the variable is referenced.

Local Memcache Variables

Memcached (or the Memcache Daemon) is a general-purpose networked memory caching system that was originally developed by Danga Interactive for LiveJournal, but is now used by many other sites. It is often used to speed up dynamic database-driven websites by caching data and objects in RAM to reduce the number of times an external data source (such as a database or API) must be read. Memcached has been used by web sites including YouTube, Facebook and Twitter.

SparForte supports memcached natively (that is, you don't need to use a special package to access memcached.) The memcached support is built on the PegaSoft PegaSock socket library, which supports local memcached caching as well as distributed, redundant memcached caching clusters.

One important rule: PegaSock expects a non-empty string for all variable values (it uses an empty string to represent a cache miss.)

When importing or exporting to local_memcache, the variables will be imported or exported from your local machine. SparForte expects to find a memcached server running on localhost and port 11211 (the default memcached port).

All SparForte scripts running on the same server can access the memcache variables.

=> s : string := "test"
=> pragma export( local_memcache, s )
=> env s
s := "test"; -- exported local memcache identifier of the type string
=> unset s
=> s : string := "not test"
=> pragma import( local_memcache, s )
=> ? s
test
 

Example: A simple command line example of local_memcache

Importing with Memcache

When importing, The variable will be read from memcache when pragma import is used.

=> user_count : string
=> pragma import( local_memcache, user_count )
=> env user_count
user_count := " 3"; -- imported local memcache identifier of the type string
 

Example: Importing a memcached variable on the command line

(For example, if you import a variable named "user_count", SparForte will request the value of "user_count" from memcached hash table on the localhost using a memcached GET command.)

If the variable doesn't exist, SparForte will report an error. This behaviour can be overridden using pragma unchecked_import: if the variable doesn't exist in the environment, the value will be unchanged. It is a good idea to assign a default value.

The variable will normally be read at the time of importing, though this behaviour can be changed with pragam volatile (see below).

You can use a declare block to get the value at your discretion by using an imported variable.

declare
  -- Get current value from memcached
  status : string;
  pragma import( local_memcache, status );
begin
  -- do something with status
end;
 

Example: Using declare to import on demand

Exporting with Memcache

When exporting, the variable's final value will be stored in memcache with the memcache SET command when the varible goes out of scope or is destroyed with unset.

You can update the value at any time using a declare block and an exported variable:

new_status_value := "good";
declare
  -- Push out new value to memcached
  status : string := new_status_value;
  pragma export( local_memcache, status );
begin
  null; -- do nothing
end; -- before discarding status, write it to memcached
 

Example: Using declare to export on demand

Importing, Exporting and Volatile with Memcache

It is possible to declare a variable as both imported and exported using both import/export pragmas.

Pragma volatile will mark a variable as "volatile", meaning that its value can change unexpectedly and SparForte should reload the value from the memcached whenever it is referenced.

You can declare a variable as import, export and volatile. For example:

declare
  user_count : string;
  pragma import( local_memcache, user_count );
  pragma export( local_memcache, user_count );
  pragma volatile( user_count );
begin
-- do some other work here
  user_count := strings.image( integer( numerics.value( @ ) + 1 ) );
end;
 

Example: Using import, export and volatile

In this example, the assignment statement will get the latest value for user_count, convert it to a number, add 1 and convert the result back to a string. When the declare block ends, the value of user_count will be stored in memcached.

Bear in mind that this kind of operation is not atomic: another script could try to update user_count in memcache before the first script can write the result. If you want to lock access to the variable to guarantee exclusive access, you will need to use the lock_file package or a similar approach.

Handling Server Failures

PegaSock uses a countdown system when a memcache server cannot be found. If it cannot connect, it marks the server as off-line and will return cache misses for several commands. After enough commands have passed, it will attempt to reconnect to memcached. These "back offs" are escallating: each failed reconnect attempt will result in a longer backoff period. This is done for performance reasons: establishing new network connections is a very slow operation.

If you don't have memcached running on your local machine, it will have the same effect.

You'll periodically see warning messages from PegaSock because it is unable to establish a connection.

=> s : string
=> pragma import( local_memcache, s )
pegasock-memcache.adb:81: server localhost 11211 error - backing off for 8 tries
 

Example: The memcached server is not running or cannot be accessed

Distributed Memcache Variables

If you have memcached running on two or more servers, you can create a redundant distributed cache using the "memcache" method instead of "local_memcache". In order to use a distributed cache, inform SparForte of what servers to use with pragma register_memcache_server.

=> pragma register_memcache_server( "cachehost1", 11211 );
=> pragma register_memcache_server( "cachehost2", 11211 );
=> company_name : string
=> pragma import( memcache, company_name )
=> ? company_name
PegaSoft Canada
=> env company_name
company_name := "PegaSoft Canada"; -- imported memcache identifier of the type string
 

Example: Importing a variable stored on two hosts

With more than one server, SparForte will store the variable on two servers. If one server should fail, it wil retrieve the variable value from the other.

Managing Script Licenses

Tracking and keeping accurate information about licenses is important for large companies and organizations. Such groups may run third-party license management software which scans source code and tries to guess at what license applies. However, typos and copying errors putting license info into comments makes this an imperfect task. Software may be bundled together with multiple licenses. Licenses are further qualified by server limits, user limits, evaluation periods or other real world or legal concerns.

SparForte can help manage licenses with the license pragma. This pragma declares the license for a script in a structured way. This approach assists in automating license compliance, helps to make the best use of licenses while reducing the risk from a license audit. Since there are thousands of licenses, SparForte doesn't attempt to know, enforce or reconcile every license—it leaves these concerns for specialized license software. However, many of the most popular licenses are known by SparForte.

For example, if myscript.sp contains this pragma:

pragma license( public_domain );

then you can use the help command to see the license without running the script.

$ spar -e "help -l myscript.sp;"
public_domain

If you use license management software, configure it to run the spar help command to get an accurate license name.

If you have a commercial license, declare it as commercial and include more details in the second parameter, or use the second parameter as a URL to the text of the license.

pragma license( commercial, "bogodb license" );

The help command will show the license with the additional text.

$ spar -e "help -l myscript.sp;"
commercial: bogodb license

A script may only have one license pragma.

Other examples:

pragma license( gpl );
pragma license( freeware, "2 week evaluation" );
pragma license( gplv2, "LGPL" );
pragma license( commercial, "bogodb license: 15 users" );

Running scripts may check the license string with System.Script_License.

=> pragma license(bsd_original)
=> ? System.Script_License
bsd_original
 
[Right Submenu]

 AdaScript versus GCC

 Case Sensitivity

 Reserved Words

 Comments

 Literals

 Bourne Shell Word Expansions

 Fundamental Types

 User-defined Types

 Enumerated Types

 Arrays

 Records

 Basic Assignment

 The @ and % Operands

 Command Argument Shortcuts

 Redirection and Pipelines

 Command Line Interaction

 Built-in Shell Commands

 The Current Directory

 Database Commands

 Flow of Control

 Other Statements/ Subprograms

 External Commands

 Block Statements and Subprograms

 TCP/IP Sockets

 Numeric Formatting with Put

 Interpreter Directives

 Command Line Options

 Command Reference

 ASCII and Latin_1 Character Sets

 Common Error Messages

 Common PHP Functions and the SparForte Equivalent

[Back to Top] Back To Top [Small Forte Symbol]