Mon Oct 25, 2021 10:33 pm
Login Register Lost Password? Contact Us


Improving Macros

Comments and questions related to the Enterprise Control Language

Thu Feb 06, 2014 4:42 pm Change Time Zone

One of the reasons people shy away from using macros in ECL is that if you misspell a macro argument, obscure errors may result which are very hard to debug. One solution is of course to include in the macro body your own error checking so that the macro can issue an intelligible error message up front. This is not always possible in the current version of ECL because of the lack of certain primitives:

  1. We can't test for an active XML scope.
  2. We can't test for the existence of ECL attribute names in the current scope or of template variable names.
  3. We can't test to see if a valid identifier was passed as an argument.

XML Scope

Macros that use template variables don't function properly unless at least a default XML scope is defined:

    loadxml('<xml/>');
It is very perplexing if someone tries to invoke a macro and then gets the message that an XML scope is not active.

So, I would recommend that a default XML scope always be available and that instead of loadxml, we should provide the following built-in ECL functions:

    pushxml([xmlstring] | [symbol [,branch]])
      Start or load an new XML scope. If no arguments are given, start a new unnamed scope.

      If #exportxml is performed, after doing pushxml(), it simply loads that unnamed XML scope with the generated XML. Alternatively, if a pushxml() is performed, an #export and a loadxml may be called to set symbols into that unnamed scope.

    popxml()
      Return to the previous XML scope.

Existence

We may want a macro to define a name which was passed as an argument. As we all know, if we try to redefine an attribute, we often get an obscure error message depending on how that attribute was previously defined.

We also may want a macro to reference some attribute that needed to have been defined by a previous macro. If we forgot to invoke that other macro first, obscure errors result.

If we use an undefined template variable name (i.e. %A%) in an expression, it is assumed to be defined as 0. That can be useful but it would be better to know whether it was defined already because if we try to #append or #set using that variable, an error will result.

There is currently no way in ECL to test to see if a attribute or template variable is already defined.

It is true that we have the #inmodule function:

    #inmodule(module,attribute)
      Return true if attribute is defined in the module.
This function returns false if anything other than a folder name (or repository module name) is passed as the module argument or if anything other than attribute[.ecl] (file) defined in that folder is specified.

A more general solution would be to provide the following template function:

    #exists([qualifier.]identifier)
      Return true if identifier is defined in the current scope. This identifier may be qualified. For example:
        #exists(A) returns true if A is defined in the current scope.
        #exists(A.B) returns true if B is defined in A.
        #exists(^.A) returns true if A is defined in the outer scope.
        #exists(*.A) returns true if A is defined in any outer scope.
        #exists(%A%) returns true if A is defined as a template variable.

Check For a Valid Identifier or Expression

If you specify the wrong characters in a macro argument that was intended to be used as an identifier or expression in the context in which it is to be expanded, even more obscure errors may result. How about providing the following template function:

    #validname(argument)
      Return true if argument is a valid ECL identifier.
    #validexpression(argument)
      Return true if argument is a valid ECL expression.
BenJones
 
Posts: 28
Joined: Tue Jun 18, 2013 2:56 pm

Return to ECL

Who is online

Users browsing this forum: No registered users and 1 guest

cron