Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with INCLUDE TYPE statement and extended syntax check in classes

michał_badura
Participant

Hi all,

I just stumbled across an issue with the INCLUDE TYPE statement in a method and the extended syntax check. Here's the scenario: I have a method, in which I define a local type (for selection from data base; there are more fields selected than exported, since I want to check the authorizations and so on). My SELECT statement uses FOR ALL ENTRIES addition, so I use CHECK lines( i_itab ) NE 0 at the beginnig of the method. Since the result table is passed by reference, I clear it before any other actions are taken (CLEAR e_itab).

That's how I came to this issue, but actually You can check it on Your own with the following coding:

REPORT zmb_rp_community_test.

CLASS local_class DEFINITION FINAL ##needed.

  PUBLIC SECTION.
    CLASS-METHODS:
      method_1 IMPORTING i_just_a_text   TYPE csequence OPTIONAL
               EXPORTING e_just_a_number TYPE i ##called,
      method_2 IMPORTING i_just_a_text   TYPE csequence OPTIONAL
               EXPORTING e_just_a_number TYPE i ##called.

ENDCLASS.

CLASS local_class IMPLEMENTATION.

  METHOD method_1.

    TYPES:
      BEGIN OF local_type ##needed.
        INCLUDE TYPE t000.
    TYPES:
      END   OF local_type.

    CLEAR: e_just_a_number.

    CHECK strlen( i_just_a_text ) GT 1.

  ENDMETHOD.


  METHOD method_2.

    TYPES:
      BEGIN OF local_type ##needed,
        component TYPE i,
      END   OF local_type.

    CLEAR: e_just_a_number.

    CHECK strlen( i_just_a_text ) GT 1.

  ENDMETHOD.

ENDCLASS.

Now when I run the extended syntax check, I get the following information regarding programming guidelines:

slin.jpg(31.8 kB)

Both methods differ only in the definiton of the local type – the one uses INCLUDE TYPE statement, and causes problems, the other not. One can observe the same issue with DATA and STATICS and with INCLUDE STRUCTURE in all three cases.

So the primary question was: why? Is there any explanation, or is it just a bug? I know the documentation discourages from using INCLUDEs in type definition, but I think in my scenario it's valid to use it.

I encountered this problem in a customer system (7.51 SP02). But as I wanted to prepare the above coding in my company's system (7.40 SP11), I noticed yet antoher problem: here I'm forced to use the order first CHECK then CLEAR. By my customer it was the other way round. So I checked some other systems too: in 7.50 SP05 it's first CLEAR then CHECK and in 7.30 SP08 it's like in 7.40. And I think the use of CHECK outside of loops, even at the beginnig of a procedure, was also notifed by SLIN prior to 7.30, but maybe I'm wrong.


So now there is also a secondary question: how am I supposed to write clear (i.e. error-, warning- and information-free) code, when SAP is changing the rules? Is there any documentation on these changes, so that developers can pay attention to constructs in question in advance? What was the reason for this particular change? As for me, the order prior to 7.50 made more sense: if importing parameters are not accurate, then the method should take no actions at all, not even clear the parameters passed by reference. Or am I wrong, and the new order is reasonable, but it's me, who doesn't understand it?


I would appreciate Your answers.

6 REPLIES 6

raymond_giuseppi
Active Contributor

So the good old syntax with positive check...

    " CHECK something to do, continue
    CHECK strlen( i_just_a_text ) GT 1.
    " IF nothing to do, exit
    IF strlen( i_just_a_text ) EQ 0.
      RETURN.
    ENDIF.

0 Kudos

But it's a workaround!

Well, I just put the CLEAR and CHECK statements before type definition.

But I would like to understand, why is this particular statement – INCLUDE TYPE – causing problems.

iftah_peretz
Active Contributor

Hey

The CHECK command is not encouraged by the help manual outside of LOOPS, unless for cases that coincide with the logic of the LOOP restriction.

The logic behind it is to use IF - RETURN - ELSE ... ENDIF statements instead, for a more readable flow and not to accidentally miss out on other code (that's why inside a loop, you'll just miss the rest of the LOOP iteration at worse and not exit the whole processing block). It is stated clearly (no pun intended - get it CLEAR?) under the "Bad example" in the programming guidelines:

"The following source code shows how a method is left early with a CHECK statement, whose meaning cannot be identified by simply looking at it. You have to know that CHECK exits the procedure if the following logical expression is wrong, which is why a double negation is necessary here."

There is a caveat that I stated in the beginning:

"This example shows a case where CHECK can be used outside a loop. Right at the start of a procedure, a prerequisite for executing the procedure is checked (and the procedure exited if the check is not successful). In this case, the procedure cannot be executed in the background."

CLASS demo DEFINITION.   
PUBLIC SECTION.     
CLASS-METHODS main. 
ENDCLASS. 

CLASS demo IMPLEMENTATION.  
 METHOD main.     
CHECK sy-batch IS INITIAL.  
   ...   
ENDMETHOD. 
ENDCLASS. 

START-OF-SELECTION.  
 demo=>main( ).

You have provided some code before the CHECK command making the compiler assume that this is not the first thing that you check ("...Right at the start of a procedure, a prerequisite for executing the procedure..."). The CLEAR statement first is processed and is leading the compiler to assume that. Because a compiler has different versions on different SPs, it can be the case that in some of them only a line before the CHECK command is still accepted the "...Right at the start..." guideline.

As for writing flawless code, it's a work in progress and more of an idea to reach to and not a tangible thing - you can always improve, syntax changes, you are under time constraints, fitting into someone's else code and the list of excuses never ends. The fun is to keep trying. That's my two cents on that.

I hope I managed to get across the point and answer your question and sorry if I got all "motivational speaking" on you 🙂 .

0 Kudos

I know the programming guidelines and that CHECK should only be used in loops or at the beginning of a procedure. But in my example it is the beginnig of the procedure! Alright, I have the type definition, but it's not executable code; and I have the CLEAR statement, but just because SLIN wants me to have it before CHECK. And take a look at the coding in my origial post: I have two methods there, both begin with type definition, followed by CLEAR and CHECK statements. But only one is causing problems!


I don't think that it could be that in different compiler versions on different SPs a line before CHECK statement would or would not be accepted as right at the start. It's only this one parcticular statement (CLEAR) that is accepted (from 7.50 on).

nomssi
Active Contributor

Hello Michał,

0) where is INCLUDE TYPE usage discouraged? maybe INCLUDE STRUCTURE, but I cannot imagine working without INCLUDE TYPE .. AS ...

1) I have decided long ago to ignore the warnings when I use CHECK as a guard clause anywhere in a method that is small. In the mean time, the checks behavior have changed from not allowed to allowed as first line in a method to allowed at the beginning of the method.

The definition of beginning is open to discussion. I have moved the local type definition to the class and the warning is gone (7.51 SP02). Since this is not fully documented, I cannot call it a bug. Anyhow, you decide which policies to follow

CLASS local_class DEFINITION FINAL ##needed.
  PUBLIC SECTION.
    CLASS-METHODS:
      method_1 IMPORTING i_just_a_text   TYPE csequence OPTIONAL
               EXPORTING e_just_a_number TYPE i ##called.

  PRIVATE SECTION.
    TYPES: BEGIN OF local_type ##needed.
             INCLUDE TYPE t000.
    TYPES: END   OF local_type.
ENDCLASS.

CLASS local_class IMPLEMENTATION.

  METHOD method_1.
    CLEAR e_just_a_number.
    CHECK strlen( i_just_a_text ) GT 1.
  ENDMETHOD.

ENDCLASS.

Most of the time I use CHECK at the beginning of a method like this

  METHOD my_method.
  CLEAR returning/exporting parameter.
  CHECK logical expression/prerequisites.
  ENDMETHOD.

but I have no problem to use it at the end. I worry more about small methods. The right size is, as Uncle Bob says, smaller than that.

regards,

JNN

@0:

The statement INCLUDE described here should no longer be used for the following reasons…

@1:

As I answered to Raymond: it's one of possible workarounds. Personally, I wouldn't like to move the definition of type, which should be used only in this particular method, to the class definition.

I agree that it's not fully documented. Nevertheless, SLIN notifications are not consistent at this point, and thats quite a bug for me. Unless I didn't get something, but that's why I'm asking a question. In other words: it would be fine, if I was always notified, when CHECK is not the first statement. But it seems to me, that no matter how many nonexecutable statements I have, it's alright to put the CHECK statement below them; unless I use the INCLUDE TYPE statement. As if the SLIN check checked for INCLUDE statement, but made no exception for INCLUDE TYPE / STRUCTURE.