How to organize your code

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: Klaus, FourthWorld, heatherlaine, kevinmiller

Post Reply
uelandbob
Posts: 72
Joined: Mon Dec 29, 2014 3:28 pm

How to organize your code

Post by uelandbob » Sat Jan 17, 2015 2:08 pm

I know this is not an easy question and probably people do it differently, but still I would like to know different ways of organizing your code in LC.

Say I have a program of totally 6000 lines of code. Some in controls, some in cards, some in mainStack. Some handlers are 300 lines long others are fairly small. How would one organize such a thing?*

To organize a big project is very important, and what support the IDE provides is essential. In Cocoa you have groups, frameworks, etc. In LC I suspect you make your own organization. This is both good and bad. Good if you have a good organization, and bad if you haven't. Is there anything written about this with respect to LC?

*some ideas
1. Extract everything that could be reused and put it in a "FavouriteHandlers" stack that I can start using on another project.
2. Make an extra card in the mainStack called "Handlers" and put some named buttons, that contain the code that you can call from the other cards.
uelandbob@gmail.com

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 5561
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: How to organize your code

Post by jacque » Sat Jan 17, 2015 9:23 pm

Organization depends on the app and each one will be different. Each developer also will do it differently. There's no one answer.

My general rules are:
  • If code is needed more than once, break it out into a separate handler.
  • If a handler gets too long, break it up into separate handlers (a 300 line handler is way too long.)
  • Place handlers at the level closest to the objects that use them. If a single button uses some code, put it into the button. If all buttons on a card use it, put it in the card. If it is used in a background group, put it there. If it is used in various places around the stack, put it in the stack. I only use libraries for code that is commonly used across different projects. I don't have many of those.
That said, sometimes I put all the handlers into the stack script so they are all in one place, or they can all use the same script local variables. Depending on the stack structure, sometimes that works better.

Finally, sometimes I don't do any of those things.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

uelandbob
Posts: 72
Joined: Mon Dec 29, 2014 3:28 pm

Re: How to organize your code

Post by uelandbob » Sun Jan 18, 2015 12:29 pm

jacque wrote:My general rules are:
  • If code is needed more than once, break it out into a separate handler.
  • If a handler gets too long, break it up into separate handlers (a 300 line handler is way too long.)
  • Place handlers at the level closest to the objects that use them. If a single button uses some code, put it into the button. If all buttons on a card use it, put it in the card. If it is used in a background group, put it there. If it is used in various places around the stack, put it in the stack. I only use libraries for code that is commonly used across different projects. I don't have many of those.
Thanks Jacqueline, I agree with that :D, here are my own preferences. Observe that I only do this when dealing with large projects, that is projects containing more then 1000 lines of code.
  • handler size: less then 20 lines. If longer break up into separate handlers.

    script size: less than 100 lines: If longer break up into separate scripts, placed in other button scripts acting as mere code containers. The code container buttons are divided into two parts, one external interface part containing handlers that other scripts can call, and one internal part that are not meant for other scripts to call.

    stack size: If my end size is say 480x640 the I make my stack 480x1280 to get extra space for placing buttons, field and so on I use during the development. I'll have one or more log fields, info fields, code container buttons, etc. If the extra space is not enough I make one or several extra cards.

    structure: I take great pain to go over stack several times and refactor, looking for ways to simplify and follow the natural division that the problem dictates. I'm not satisfied until I can see the whole project "at a glance".

    testing: I try to unit test each script (sometimes even a single handler). I'll keep those test in buttons so that I can perform tests as soon as I change my code, to make sure that everything still works.

    naming: I take naming very seriously. Good names can clarify the code. However I must confess that I do not use the conventions with t, g, l and so on practiced in LC. I'll use camel-case and fairly long names telling me exactly what those variables are.

    reuse: I try to reuse as much code between the projects as possible. I go over my code looking for handlers that are general in their nature and move them to a library of code.

    adding code: When adding a new non trivial functionality to the project, I first make a new separate mini project that only tests this functionality. When I am satisfied, then and only then do I incorporate this functionality to my project.

    development order: I'll always start with the most difficult part first, in isolation. For instance, if my stack needs to communicate with external world, I'll start with a mini project that only handles the communication part. First when I have solved those "difficult" parts do I start with my project. That gives me a control over the project, that I otherwise would lack.

    docs: All IDEs have docs, to look up things. In the case of LC, the Dictionary and the User Guide are my main tools. Other than that the forum and other people can give answers.

    communicating with others: I keep an eye on the LC forum, to learn new tricks. The greatest source of knowledge is not APIs, books, or web sites. No it is the other people. If you want to become a great at any profession, you'll learn more from other people than any other source. I learn much when I read someones answer, and I also learn much when I answer myself, because answering structures my own brain paths. What was once vague, is now solid.

    cheat sheets: I make my own cheat sheet(s). These are personal and mirror my current understanding of LC. So I have a stack called "Cheat Sheet", and on the first page is a list of my own keywords. When I click on a keyword I go to to a page with examples. In this way I can quickly look up things. For instance if I click on "logical operators" I go to a card containing the following:

    Code: Select all

    if 3 = 4 then ...
    if 3 <> 4 then ... 
    if 3 <= 4 then ...
    if (there is a card "repeat") then ... 
    if ("ada" is in "madam") then ...
     if ("madam" contains "ada") then ... 
    if ("to" is among the items of "one,to") then ...
    if (45.4 is an integer) then ... 
    if ("1,1" is within "0,0,10,20") then ...
    if (the first word of the name of the target is "field") then
    sharpening the axe: I'm an automation freak. I use Keyboard Maestro (there are similar programs for PC) to automate. So for instance I use F1 to select Run tool and F2 to select Edit tool. I know that you can use Cmd+9 and Cmd+0, but for me F1 and F2 are more convenient. I'll also write my own helpers in LC (one of the benefits of LC). For instance to lock and unlock text fields I'll use this little helper code.

    Code: Select all

    on mouseEnter
       if the optionKey is down then
          set lockText of me to false
          set listBehavior of me to false
       end if
    end mouseEnter
    
    on mouseLeave
       set lockText of me to true
       set listBehavior of me to true
    end mouseLeave
uelandbob@gmail.com

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 5561
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: How to organize your code

Post by jacque » Sun Jan 18, 2015 8:34 pm

I think 100 lines per script is pretty low. I generally don't worry about script sizes (the compiler doesn't care.) I've got scripts that are a couple of thousand lines or more without ill effects. The reason I limit the length of handlers is for easier maintenance and modularity, but I find it more difficult to maintain code that is too excessively scattered in different places. That's just a personal thing though. We all have our ways.

On the other hand, if you are calling out to the scripts in buttons using "send" or "call" then it will introduce unnecessary overhead. If you are putting those scripts into a backscript, then functionally there's no difference from leaving them in one script to begin with.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

uelandbob
Posts: 72
Joined: Mon Dec 29, 2014 3:28 pm

Re: How to organize your code

Post by uelandbob » Mon Jan 19, 2015 12:24 am

jacque wrote: I generally don't worry about script sizes (the compiler doesn't care.) I've got scripts that are a couple of thousand lines or more without ill effects. The reason I limit the length of handlers is for easier maintenance and modularity, but I find it more difficult to maintain code that is too excessively scattered in different places...
...if you are calling out to the scripts in buttons using "send" or "call" then it will introduce unnecessary overhead. If you are putting those scripts into a backscript, then functionally there's no difference from leaving them in one script to begin with.
Thanks Jacqueline :D

Although the compiler doesn't care and there is no difference functionally, I sometimes do partition very long scripts. Yes there is a penalty of introducing a line or two of call or send statements but sometimes dividing a 2000 lines long script into two 1000 lines long scripts might be worth it. And yes you do have to keep track of the "scattered" back-scripts as you call them, but sometimes that is also worth it.

I say sometimes, why? Because it has happened to me when I looked over a very long script that I found a natural division. Part of the code belonging together and other part of the code also belonging together, but the parts themselves having just a simple coupling between them. So I take my analytic knife, put the point directly on that simple coupling and just tap, not hard, gently, and the whole script splits, cleaves, right in two...and the split is clean. There’s no mess. No slop. I was lucky to find a tiny, almost unnoticeable fault line; and tapped it, and the whole script came apart, so neatly it was almost unbelievable*. And putting those two parts in separate scripts made the code so much simpler and more beautiful.

So let me ask you this question. By separating the script into two parts I made the coupling between the parts visible. A person reading my stack would see that division and understand the existence and the role of the two parts. If you never separated the script, how would you expose that division?

* As you can see I'm a Pirsig fan.
uelandbob@gmail.com

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”