« Fraction(): approximate a number as a common fraction | Main | Modular XSLT, part 2: Simple export »

Options

Here are two functions I use to pass parameters to scripts: Option() and Get Option():

Option( key, value )

Substitute( "¶" 
  & Substitute( key; [ "^"; ".^" ]; [ "¶"; ".^^" ] ) & "¶" 
  & Substitute( value; [ "^"; ".^" ]; [ "¶"; ".^^" ] ) & "¶";
  [ "^"; ".^" ]; [ "¶"; ".^^" ] ) & "¶"

Get Option( options, key )

Case(
  IsEmpty( options ) or IsEmpty( key ); 
    NULL;

  Let( [ 
    unwrapped options = Substitute( options; [ "¶"; "" ]; [ ".^^"; "¶" ]; [ ".^"; "^" ] );
    key position = Position( "¶" & options; "¶.^^" & key & ".^^"; 1; 1 ) ];

    If( key position = 0; NULL;
      Let( [ 
        value position = ValueCount( Left( options; key position ) );
        option string = MiddleValues( options; value position; 1 );
        start = Position( option string; ".^^"; 1; 2 ) + Length( ".^^" );
        end = Position( option string; ".^^"; 1; 3 ) ];

        Substitute( Middle( option string; start; end - start ); 
          [ ".^^"; "¶" ]; [ ".^"; "^" ]; [ "¶"; "" ]; [ ".^^"; "¶" ]; [ ".^"; "^" ] ) ) ) ) )

The first function makes a single “option”: it takes a pair of any text-based key and value and stores both as text. It wouldn't make much sense if you could store only one pair, so the function is written in such a way that several options can be joined together:

Option( "first name", "John" ) & Option( "last name", "Doe" ) & ...

The result is also text, so the whole construct can be stored in a single text field or passed as a script parameter. Later you can retrieve any value by its key using the Get Option() function. If the value contains carriage returns, they are preserved.

How the functions are used?

  • The main use of these functions is to pass multiple parameters to scripts. To do this you simply enter the list of options in the script parameter field:

    20060205-01.png

    And then get these values either by

    Get Option( Get( ScriptParameter ), "name" )

    or if you're like me, you'll wrap it in a custom function

    Script Param( key )

    Get Option( Get( ScriptParameter ), key )
  • Since the options can be easily joined together, it's possible to pass the parameter further, either unchanged

    20060205-02.png

    or augmented with additional parameters

    20060205-03.png
  • If necessary, you can store the result in a field.

Background

When I was writing these functions, I thought I'll be using them for complex things, like storing hierarchies of objects. This means the functions can build nested options:

Option( "pack", 
  Option( "first field", "first value" ) 
  & Option( "next field", "next value" ) )

If you now Get Option( value, "pack" ) you'll get a packed or wrapped string; to get the first field you'll have to use Get Option() on the result. I also wrote Set Option() to replace an option in such a string; I wrote functions to traverse the hierarchy and do lots of funny stuff.

Then I found I have no use for them, at least for now, so they are postponed; only the simplest applications, such as passing parameters and maybe storing multiple values in a field or passing multiple values to a custom function are used.

I believe that they may be not necessary in v8 because of variables, but haven't yet established a workflow.

Test for the Function Tester

Let( [
  A1 = Option( "A", 1 );
  B2 = Option( "B", 2 );
  empty = Option( "X", "" );
  single CR = Option( "X", "¶" );
  text with CRs = Option( "X", "x¶x¶x¶" );
  AA1 = Option( "A", A1 );
  AAA1 = Option( "A", AA1 );
  CA1B2 = Option( "C", A1 & B2 ) ];

  Assert Equals( Get Option( A1, "A" ), 1 ) &
  Assert Equals( Get Option( A1, 1 ), "" ) & 
  Assert Equals( Get Option( A1, "B" ), "" ) & 

  Assert Equals( Get Option( B2, "B" ), 2 ) &
  Assert Equals( Get Option( B2, 2 ), "" ) & 
  Assert Equals( Get Option( B2, "A" ), "" ) &

  Assert Equals( Get Option( A1 & B2, "A" ), 1 ) &
  Assert Equals( Get Option( A1 & B2, "B" ), 2 ) &
  Assert Equals( Get Option( B2 & A1, "A" ), 1 ) &
  Assert Equals( Get Option( B2 & A1, "B" ), 2 ) &

  Assert Equals( Get Option( empty, "X" ), "" ) &
  Assert Equals( Get Option( single CR, "X" ), "¶" ) &
  Assert Equals( Get Option( text with CRs, "X" ), "x¶x¶x¶" ) &

  Assert Equals( Get Option( AA1, "A" ), A1 ) &   
  Assert Equals( Get Option( AAA1, "A" ), AA1 ) &   
  Assert Equals( Get Option( 
    Get Option( AAA1, "A" ), "A" ), A1 ) &
  Assert Equals( Get Option( CA1B2, "C" ), A1 & B2 ) )

Technorati Tags:

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/t/trackback/510343/4229929

Listed below are links to weblogs that reference Options: