OptionsForEnhanceIfStatementsAndAttrsParsing

Overview

Currently, the %IF macro only allows one conditional test (i.e. if / then / else). It is proposed to:
  • Enhance the %IF macro to allow the ability to build if / elsif / elsif / else statements,
  • Enhance the parsing code in Foswiki::Attrs to allow for clean syntax for %IF (probably via creating a subclass).

There is more than one way that Foswiki::Attrs can be modified:

Store Repeated Attributes in an Array (SRA)

If an attribute of the same name is defined more than once, Foswiki::Attrs simply uses the last value to be defined. SRA would enhance / subclass Foswiki::Attrs so that all of the values for a repeated attribute can be retrieved. This would be the %IF syntax:
%IF{"condition 1"
    then="condition 1 is true."
elsif="condition 2"
    then="condition 2 is true and condition 1 is false."
elsif="condition 3"
    then="condition 3 is true and conditions 1 and 2 are false."
else="nothing is true.  all is permissible."}%

Complex Attribute Types (CAT)

Attribute passing to a macro must be done via a hash map. CAT would enhance / subclass Foswiki::Attrs so that richer data types can be passed to a macro: ordered lists, ordered lists of hashes, etc.
%IF{tests=[ 
{if="condition 1"
    then="condition 1 is true." },
{if="condition 2"
    then="condition 2 is true and condition 1 is false." },
{if="condition 3"
    then="condition 3 is true and conditions 1 and 2 are false."}]
else="nothing is true.  all is permissible."}%

Nested Ifs

Perhaps if a TML author feels the need to write a nested if, it's a sign that the TML is getting too complicated. He should break up his logic with %INLCUDE or %TMPL:P. Nevertheless, here is what nested ifs would look like:

SRA

%IF{"condition 1"
    then="$percentIF{\"condition 2\"
        then=\"c1 and c2.  Hello $percentpercentWIKIUSER$percentpercent\"
        else=\"c1 but not c2\""
else="nothing is true.  all is permissible."}%

CAT

%IF{tests=[ 
{if="condition 1"
    tests=[
    {if="condition 2"
        then="c1 and c2.  Hello $percentWIKIUSER$percent"
        else="c1 but not c2" } ] },
else="nothing is true.  all is permissible."}%

-- KipLubliner
If we are going to extend the syntax of Foswiki::Attrs to support multi-valued attributes (and I support this) then it should not be done as a subclass but be part of the standard implementation. Consistency with the existing usage of Foswiki::Attrs can be achieved through the use of wantarray.

I am very concerned about the CAT proposal. Looks like quoting hell to me.

-- CrawfordCurrie - 12 Feb 2012

I'm afraid that I probably pointed Kip down the path of doing a subclass, in a response to SvenDowdeit's comment on IRC that he didn't want to see Foswiki::Attrs become too magical. But now that I recall that conversation, perhaps he was only reacting to the idea of $params->{foo} magically becoming arrayrefs (sven?)

-- PaulHarvey - 12 Feb 2012

As Paul said, Foswiki::Attrs main interface is a raw hashref lookup. If we simply store an arrayref in there, then we are changing the semantics of repeated attribute keys. This could cause a problem for sites that rely on the current behavior. There could be code out there like:
%MACRO{value="default val" %IF{"condition" then="value=\"other val\""}%}%
This is quite odd, but legal given the currently documented behavior. I just wanted to point out the risks, and also to note that this definitely should not be included in a point release.

Crawford: I'm not clear about your comment about wantarray. We would need to use tie to get a method behind $params->{foo}. That FETCH method could use wantarray to decide whether to return a scalar or an array. That would address the issue mentioned above (in the %MACRO example). Is this what you had in mind? One thing to consider - Paul said that attrs parsing came up as a 'hot-spot' in his profiling with nytprof. I'm wary about making any changes that would degrade performance.

For the record, I was leaning towards CAT ... until I actually wrote out examples of what the syntax would look like. Now I am in favor of SRA.

-- KipLubliner - 12 Feb 2012

Perhaps Crawford means passing a wantarray option to the constructor, Eg.

my $params = Foswiki::Attrs->new($syntax, wantarrays => 1);

-- PaulHarvey - 12 Feb 2012

Keeping all attributes of the same name instead of throwing away all but the last one is very much in line with SettingAndGettingVariablesUsingMacros where %SET{"foo" value="1" value="2" value="3"}% is used to store a list. So part of that proposal already is to enhance Foswiki::Attrs in that way.

-- MichaelDaum - 13 Feb 2012

Be careful to separate the cost of parsing attributes and that of accessing the value of attributes. No, I wasn't thinking of a tie; I was thinking of providing two interfaces - ->{attr} which always returns the last attribute value and ->get('attr') which uses a =wantarray.

-- CrawfordCurrie - 13 Feb 2012
 
Topic revision: r7 - 13 Feb 2012, CrawfordCurrie
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy