Help show the power of merge and value

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Help show the power of merge and value

Post by Bernard » Sat Dec 16, 2006 5:45 pm

I'm using the 'do' command with dynamically assembled statements and it is cool. But I'm sure that there is more to be done using 'merge()' and 'value()' functions.

I'm wondering if we could start to list ways in which these latter two can be used.

Anyone care to show some cool tricks using these functions?

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Re: Help show the power of merge and value

Post by marielle » Sat Dec 16, 2006 10:48 pm

Bernard wrote:Anyone care to show some cool tricks using these functions?
Rather than merge, I prefer to use a template within a text field and then use this template replacement function:

Code: Select all

function template.fill pText 
  repeat with p = 2 to the paramCount
    put param(p) into tParam
    split tParam by "="
    replace "{{" & tolower(tParam[1]) & "}}" with tParam[2] in pText
  end repeat
  return pText
end template.fill
I use it for instance to dynamically provide values when I do xml parsing using regular expressions such as these ones:

Code: Select all

put "(?s)(<{{nodename}}[^>]*>[\s\S]*{{dummy}}[\s\S]*</{{nodename}}>)" into tPattern
-- corresponds to : <node attributes>.*dummy.*</node>
put template.fill(tPattern, "nodename=" & tNodeName) into tRegExp
get matchtext(pXMLtext, tRegExp, tParentFull)

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Re: Help show the power of merge and value

Post by marielle » Sat Dec 16, 2006 10:59 pm

Bernard wrote:value()' functions.
value allows you to call a function or execute a script in an object (card, stack, etc.) other than the one active. However, the syntax tends to be a bit cumbersome to use.

Rather than value, I prefer to use a handler wrapper.

Code: Select all

on list.removeDuplicates pForceWord
  put the listings of me into tList
  put the item_del of me into tDelim
  ----
  put list.removeDuplicates(tList, tDelim) into tList
  ---
  set the listings of me to tList
end list.removeDuplicates
----
function list.removeDuplicates pList, pDelim
  ... processing ...
  return tResult
end list.removeDuplicates
This way of doing forces me to think about how to organize my scripts into libraries and define data that should be part of the API (Application Programming Interface)

Anything within the function is purely function dependent. Anything within the handler corresponds to data within the API (which would correspond in a "usual" program to variables defined as local or global).

This is not really about dynamic scripting. This is more about allowing a system of reusable libraries.

For what concerns dynamic scripting, as you may know, there is a limit set to the number of lines you can execute dynamically within a compiled application (either via "do" or via "set the script of object to ...").

Check out under "script" and "scriptLimits"
* the number of statements permitted when changing a script (normally 10 in a standalone application)
* the number of statements permitted in a do command (normally 10 in a standalone application)
* the number of stacks permitted in the stacksInUse (normally 50 in a standalone application)
* the number of objects permitted in the frontScripts and backScripts (normally 10 in a standalone application)
Note that the send technique illustrated above allows you to bypass the later limit and to set up a real system of reusable libraries, even in compiled applications.

Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Post by Bernard » Sun Dec 17, 2006 1:11 pm

I'm not sure I completely what you are doing in those examples Marielle. It is good to be reminded of the scriptLimits -- if only to see how generous they are. I'm not looking at merge() or value() as ways to get round the scriptLimits. All of my code would easily fit within the scriptLimits anyway - I simply haven't built anything that requires that kind of script verbosity (I never put more than 1 statement in a do command, and I've never even used a single frontScript or backScript).

To me the power of merge() is that it allows one to work more flexibly with the syntax of transcript. So, whilst something as generic as this:

Code: Select all

set the loc of pControlType tCounter to the loc of pContainerName
will cause a script compilation error, but in this form it will work:

Code: Select all

do merge("set the loc of [[pControlType]] [[tCounter]] to the loc of [[pContainerName]]" )
So we can use merge() to make code more generic than Transcript strictly allows. (I expect some expert will tell now tell me of a way to make the above code work without using merge()! )

I've only just started to look at merge() and value(), and it seems to me that there must be very many ways in which they can enhance applications.

One thing I can't really understand though is how '<?return expression?>' works as part of merge().

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Sun Dec 17, 2006 2:29 pm

Bernard wrote:I'm not sure I completely what you are doing in those examples Marielle. It is good to be reminded of the scriptLimits -- if only to see how generous they are.
I confess. I used your question as a pretense. I am trying to familiarize users with that send wrapper as I believe it is a quite powerful one. Then I also used it as a pretense to link to the notion of API (writing programs the API way, by clearly defining the methods and data that classes of components should have). Don't worry, I am a teacher and I there is something I have in mind. I simply put that from time to time so that persons get used to see these terms ;-)

marielle
Livecode Opensource Backer
Livecode Opensource Backer

Post by marielle » Sun Dec 17, 2006 2:30 pm

Bernard wrote:One thing I can't really understand though is how '<?return expression?>' works as part of merge().
Did you give a try to "the result". This returns the result of the last functions that has been executed.

xApple
Posts: 113
Joined: Wed Nov 29, 2006 10:21 pm
Location: Geneva

Post by xApple » Sun Dec 24, 2006 3:16 pm

I have a cute example of the merge() function, used in conjunction with the format() function.
I couldn't stand the fact that every time I would relocate a control to a different card, the scripts that referenced the control would cause errors. So I invented the relative reference method. With this function in the stack script:

Code: Select all

function relativeRef theName
  repeat with x = 1 to the number of cards of this stack
    if exists(control theName of card x) then return "control" && quote & theName & quote && "of card" && x
  end repeat
  return "no relative referance"
end relativeRef
I can now issue commands in this way and be sure they work where-ever the control is:

Code: Select all

  do merge(format("put empty into [[relativeRef(\"coolField\")]]"))
or like this:

Code: Select all

    do format("put \"%s\" into %s",myText,relativeRef("coolField"))

Post Reply

Return to “Talking LiveCode”