Trying to understand LEAVE statement.

Dharmendra

New Member
Can anyone please explain how the following code works. I am not able to understand how LEAVE works here. I could not see either messages.
Code:
DO:
    IF YES
    THEN DO:
        LEAVE.
    END.
    MESSAGE 123
        VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
MESSAGE 456
    VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
 
Last edited by a moderator:

Osborne

Active Member
Because you are using a standard DO block when the LEAVE is reached you leave the whole lot and it does not reach them.

Try using a named block:
Code:
DO:
    Block1:
    DO:
       IF YES THEN DO:
          LEAVE Block1.
       END.
    END.
    MESSAGE 123 VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
END.
MESSAGE 456 VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
 

Rob Fitzpatrick

ProgressTalk.com Sponsor
From the docs:
LEAVE [ label ]

label:
The name of the block you want to leave. If you do not name a block, the AVM leaves the innermost iterating block that contains the LEAVE statement. If there is no such block, then the AVM leaves the procedure block.

You don't have an iterating block in your code, so the LEAVE statement causes it to leave the procedure, which is why you see no messages. Try this:
Code:
outer:
do:
  if yes then
    inner:
    do:
      leave outer.
    end.

    message "outside inner"
      view-as alert-box information buttons ok.
end.

message "outside outer"
  view-as alert-box information buttons ok.
You will see one message. Then change "leave outer" to "leave inner" and you will see both messages.
 

RealHeavyDude

Well-Known Member
The ABL is oriented in blocks to which something can be scoped - like transactions, buffers and undo. Without labeling a block the default behavior and default capabilities of blocks kick in. A simple DO does not make a block to which something can be scoped and therefore a leave statement will leave the next outer block with scoping capabilities - which in your case was the procedure block itself.

Blocks which have default scoping capabilities are REPEAT, FOR EACH, internal procedures, functions or the procedure for example.

To override the default behavior which might not be what you want it is good practice to explicitly label blocks and reference those labels when undoing or leaving.
 

Keith G.

Member
I consider the LEAVE statement something to be avoided in most cases, akin to GOTO from years gone by. It makes understanding and maintaining code more difficult.

Having said that, I will use it (with a block label) in tight FOR EACH loops where I only want to retrieve information from the first record returned.
 

TomBascom

Curmudgeon
Yes, it is sort of like a GOTO. However - the most serious problems with GOTO are that it allows you to jump INTO locations. LEAVE (and NEXT) is less dangerous that way.
 

RealHeavyDude

Well-Known Member
The same could be said about if statements - in that they should be avoided. I witnessed religious flame wars about OO design patterns vs. procedural and more recently functional programming and immutability.

IMHO it is all about clean code and comments as to why you are leaving a block early or what are the design thoughts behind an if or case statement.
In the end we translate the solution to real world business requirements into software and the business world isn't either white or black, it comes in every shades of gray you may think of.
 

Keith G.

Member
..
IMHO it is all about clean code and comments as to why you are leaving a block early or what are the design thoughts behind an if or case statement.
...

Yes, "why" comments are key. I get so frustrated when working on code that lacks comments of any kind. Especially maddening is the lack of business rules governing the programming decisions made.
 
So if I undersant you all, if we are in a situation to use a leave statement, we should try first to find another way to do it ?

Also I don't understand why "if" statement are to be avoided ? Can you be more specific @RealHeavyDude ?
 

RealHeavyDude

Well-Known Member
That is why I said religious flame wars.

If or case could be replaced by the factory design pattern in OO ( Factory method pattern - Wikipedia ) in many cases. In a nutshell: Instead of branching with an if else or case statement you can put each branch into a distinct classes which inherit from the same parent. Some purists think every if or case should be replaced by it. I use the factory pattern very often, but I also use if an case statement.

Since we don't live in a black or white world, but in a world that comes in all different shades of grey - it is up to us how we craft our code. Whatever rule you hear - you have to take it with a grain of salt because - most likely - you will encounter cases where it does not make sense to apply them as you read them in a book. Sometimes you need to come up with your own variant.

There is a subtle difference between "should be avoided" and "must no be used". Should be avoided means that you will likely come up with a case where it makes sense to use it.

Even when it falls into the "must not be used" category - like share locks - I can come up with a case where it makes perfect sense to use it to your advantage for a neat solution that otherwise wouldn't hold water ...
 

TomBascom

Curmudgeon
Keep in mind that finding an exception to an otherwise excellent rule (like RHD's example vis a vis SHARE-LOCK) is NOT an excuse to go wild and do something that you "must not" or "should not" willy nilly throughout your code base. Exceptions are *exceptions*. Their usage should be *rare* and very well documented.
 
Top