Custom Commands with Parameters

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
sritcp
Posts: 431
Joined: Tue Jun 05, 2012 5:38 pm

Custom Commands with Parameters

Post by sritcp » Sat Jul 07, 2012 9:00 pm

The user guide says that "You can include parameters with a custom command by passing them after the name". It doesn't say how to define them in the handler. So I did it just the way a custom function is written. It doesn't seem to work. Here's an example:

Code: Select all

on myCommand pObject
     set the showBorder of pObject to true
end myCommand

on mouseUp
     repeat with i = 1 to the number of buttons of this card
         myCommand button i of this card
     end repeat
end mouseUp
This returns "Error in the object expression" in the line "set the showBorder of pObject to true" (or even if you replace this line with any other debugging line such as "Put the name of pObject into message box"

What am I doing wrong here?

Thanks,
Sri.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10045
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Custom Commands with Parameters

Post by FourthWorld » Sat Jul 07, 2012 9:14 pm

Change this:

myCommand button i of this card

To this:

myCommand the long id of button i of this card
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

sritcp
Posts: 431
Joined: Tue Jun 05, 2012 5:38 pm

Re: Custom Commands with Parameters

Post by sritcp » Sat Jul 07, 2012 9:25 pm

..... and it works like a charm! Thanks, Richard!

Now, for the learning part, why did I need to pass the long id of an object as opposed to the object itself (or its long name) for this to work? The user guide is no help here.

Regards,
Sri.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10045
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Custom Commands with Parameters

Post by FourthWorld » Sun Jul 08, 2012 12:58 am

sritcp wrote:Now, for the learning part, why did I need to pass the long id of an object as opposed to the object itself (or its long name) for this to work? The user guide is no help here.
Actually, searching the User Guide for "referring" takes me to section 7.1, "Referring to Objects", which describes using the object's name, ID, or ordinal number to access them.

You can use any of those, including the long name if you like. But since IDs are known to be unique to a stack and it's possible to give the same name to two different objects, I tend to use the long ID rather than the long name.

As for why we can use simply "button 1", I'm not sure I can explain that as well as others here, but I'll try:

Everything in the language boils down to commands and expressions. The command is usually the first word of a statement, followed by expressions which are evaluated to determine what the command should act on and how.

Most objects in LiveCode are also containers. For example, fields and buttons return the textual contents of the control, and even images return their imageData. So when we pass an object directly, that expression evaluates to the object's contents. This makes it easy to do things like

Code: Select all

put field 1 + field 2 into field 3
To distinguish that it's the object itself rather than its contents, we pass an explicit reference to the object, using its ID, name, or ordinal number, e.g.:

MyCommand the long name of btn 1
MyCommand the short ID of img "MyImage"
MyCommand the name of the selectedObject

The ID and name properties can be used in either long or short form, and when using "the name of ..." without either specifier it'll include the object's type, e.g. "button 1".

It can be helpful to take a little time to play around with each form, since each one is slightly different and each is useful in different circumstances.

But for a general absolute reference to an object, "the long id of ..." is usually the best bet.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

sritcp
Posts: 431
Joined: Tue Jun 05, 2012 5:38 pm

Re: Custom Commands with Parameters

Post by sritcp » Sun Jul 08, 2012 2:54 am

Thanks, Richard, that was helpful.

I noticed that
put field 1 in message box
resulted in the contents of field 1, while
put button 1 in message box
resulted in nothing; so I guess the contents of a button is empty.

Section 7.1 of the user guide seems to suggest one can reference objects by name, ID, or number (implying that these are equivalent); evidently, it did not work that way in our example; "button i" didn't work; "the long id of button i" did.

Thanks,
Sri.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Custom Commands with Parameters

Post by sturgis » Sun Jul 08, 2012 3:05 am

The reason your first effort didn't work is because the "button i of this card" is being evaluated before passing it to the command. And as you noted, if you "put button 1 into msg" you get nothing back so in affect you were sending empty to your command. Since you want to work on the control itself you need to send the string representation of the control

If you were to do
myCommand "button 1 of this card"
it would work

Since you are cycling through buttons you'd need to build the string
mycommand ("button" && i && "of this card") -- this works because the actual string "button # of this card" is being sent
sritcp wrote:The user guide says that "You can include parameters with a custom command by passing them after the name". It doesn't say how to define them in the handler. So I did it just the way a custom function is written. It doesn't seem to work. Here's an example:

Code: Select all

on myCommand pObject
     set the showBorder of pObject to true
end myCommand

on mouseUp
     repeat with i = 1 to the number of buttons of this card
         myCommand button i of this card
     end repeat
end mouseUp
This returns "Error in the object expression" in the line "set the showBorder of pObject to true" (or even if you replace this line with any other debugging line such as "Put the name of pObject into message box"

What am I doing wrong here?

Thanks,
Sri.

sritcp
Posts: 431
Joined: Tue Jun 05, 2012 5:38 pm

Re: Custom Commands with Parameters

Post by sritcp » Sun Jul 08, 2012 3:42 am

Wow, this is deep!
(and counter-intuitive to what I might have expected).

I understand that "button i" returned "empty" and so it didn't work, but I am wondering how a string would work?

Doesn't
myCommand "button 1 of this card"
pass a string to the custom command? But, as defined, the command is not expecting a string to evaluate but an object reference.
Is it not looking for
(button 1 of this card) ?
I am confused!
The reason your first effort didn't work is because the "button i of this card" is being evaluated before passing it to the command.
So did "the long id of button i of this card" get evaluated before passing, but that worked. I am not entirely convinced that this is the crux of the problem.

Regards,
Sri.

sritcp
Posts: 431
Joined: Tue Jun 05, 2012 5:38 pm

Re: Custom Commands with Parameters

Post by sritcp » Sun Jul 08, 2012 3:52 am

Hi, sturgis!

On further reflection, I think
myCommand "button 1 of this card"
may not work, but
send "myCommand button 1 of this card" to this stack
might, on your logic about the stage of evaluation of the parameter value.
Though, this would still not explain why "the long id of button i of this card" worked.

Regards,
Sri.

sturgis
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 1685
Joined: Sat Feb 28, 2009 11:49 pm

Re: Custom Commands with Parameters

Post by sturgis » Sun Jul 08, 2012 2:05 pm

"the long id of button whatever" Does get evaluated in the above example.
So this:
myCommand the long id of button i of this card

Sends THIS string (of course the numbers will change to reflect actual ids):
button id 1004 of card id 1002 of stack "Untitled 1"
to myCOmmand. Then myCommand evaluates the string and finds button id #### of card id #### of stack "stackname" and does its thing.

This is why if you build the string by hand:
put "button" && thebuttonnumber && "of this card" into myStringToPass

it works because

myCommand myStringToPass evaluates myStringToPass and passes the string it contains to "myCommand"

The other way is easier though, in my opinion. (meaning use the "the long id of button i of this card")

This works for the single specified button:
myCommand "button 1 of this card"

Because the the quotes around the thing designate it a string, so if you think of it as evaluation, the engine looks and says. Yep, a string, just pass it intact.

button 1 of this card
is a reference to a button so the engine tries to figure out what you meant. (as in the example you used of field 1 of this card... it will send the contents of field 1) If you want myCommand to actually work on field 1 rather than the contents of field 1 you would have to do as in the examples above. Either use:
the long id of field 1 of this card -- which will send something like: field id 1003 of card 1005 of stack "mystack

or the other method where you build up the string and send it that way.

sritcp
Posts: 431
Joined: Tue Jun 05, 2012 5:38 pm

Re: Custom Commands with Parameters

Post by sritcp » Mon Jul 09, 2012 2:32 am

Fascinating!
Let me see...
If the parameter is not enclosed in quotes, it is evaluated before passing it to the command.
If it is enclosed in quotes, it is evaluated after passing (actually, it is evaluated before too, but the result of the evaluation is the string itself; so what's between the quotes reaches the command execution phase intact).

Thanks for the tutorial, sturgis!

Regards,
Sri.

trevix
Posts: 1077
Joined: Sat Feb 24, 2007 11:25 pm
Contact:

Re: Custom Commands with Parameters

Post by trevix » Sat Sep 03, 2022 2:13 pm

Hello.
I reopen this old post because I have a problem: I am not sure how to solve it and am confused by what I have been reading.

I have a standalone installed on two different devices, connected with sockets.

When I enter a text on a field on device X, I want the same text to be entered on device Y, but using a generalised formula that will accomodate for different uses: the "DO" command.

Device X

Code: Select all

--on a text field
on KeyDown
  put the text of me into tText --ex "Roberto"
  put the long name of me into tLong
  put "WritePlayername" && tText,tLong into TheMessage["DATA"]
  broadcast TheMessage["DATA"] --the array is sent to device Y trough sockets
end KeyDown
Device Y -script 1 --receiving the data on a custom library substack that holds all the communication scripts

Code: Select all

....
 try
     do TheMessage["DATA"] --TheMessage["DATA"] here correctly holds  Roberto,fld "A" of group "B" of card "C" of stack "D"
catch errorVariable
      answer "Error on doscript" && errorVariable
end try
...
Device Y -script 2 in the same custom library substack

Code: Select all

On WritePlayername pText,pLong --Unfortunatly here pLong gets evaluated, containing the old text of pLong and not the path to it
  if there is a pLong then --as of before, this is not run
     put pText into pLong
  end if
end WritePlayername
The main problem is that pLong contains quotes, so that the "DO" command always valuate it.
Any suggestions on how to solve this?
Thanks
Trevix
OSX 14.6.1 xCode 15 LC 10 RC1 iOS 15> Android 7>

Zax
Posts: 519
Joined: Mon May 28, 2007 10:12 am
Contact:

Re: Custom Commands with Parameters

Post by Zax » Sat Sep 03, 2022 3:39 pm

If you want to use the long name of control, you could try:

Code: Select all

On WritePlayername pText,pLong --Unfortunatly here pLong gets evaluated, containing the old text of pLong and not the path to it
put "put there is a" && pLong && "into controlExists into myCmd
do myCmd
  if controlExists then --as of before, this is not run
     put pText into pLong
  end if
end WritePlayername
Not tested.

But in both cases, I wonder what happen if the content of the field contains a comma.
Besides, for security reasons, I wouldn't DO such a string. Let's imagine that a player has set his name as "delete this card" ;)

trevix
Posts: 1077
Joined: Sat Feb 24, 2007 11:25 pm
Contact:

Re: Custom Commands with Parameters

Post by trevix » Sat Sep 03, 2022 4:48 pm

On "WritePlayername" the pLong param gets evaluated with its content. So I don't this that line 2 of your script could work.
Anyway I decided for a different approach, seen the difficulties
Let's imagine that a player has set his name as "delete this card"
Wow...didn't think of this. Not shure if it worked but absolutely to avoid.
Thanks so much for your suggestions
Trevix
OSX 14.6.1 xCode 15 LC 10 RC1 iOS 15> Android 7>

Zax
Posts: 519
Joined: Mon May 28, 2007 10:12 am
Contact:

Re: Custom Commands with Parameters

Post by Zax » Sat Sep 03, 2022 6:16 pm

Yes, "delete this card" was just an example to show how careful you have to be when using "do", or eval() in Javascript.

If I had to write this code, I would rather do something like this:

Code: Select all

on KeyDown
local TheMessage
put "WritePlayername" into TheMessage["command"]
put the short name of me into TheMessage["field"]
put me into TheMessage["data"]
put arrayToSend into TheMessage["DATA"]
  broadcast TheMessage --the array is sent to device Y trough sockets
end KeyDown
And, on reception, something like that:

Code: Select all

switch TheMessage["command"]
case "WritePlayername"
put TheMessage["data"] into field (quote & TheMessage["field"] & quote)
break
case
...
end switch
Last edited by Zax on Sat Sep 03, 2022 8:52 pm, edited 2 times in total.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10045
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Custom Commands with Parameters

Post by FourthWorld » Sat Sep 03, 2022 7:19 pm

It's this on an isolated local network, or across the open internet.

As always, you'll want to be very careful with any open-ended system that allows arbitrary code execution across a network. LiveCode is a very powerful language.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

Post Reply