ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Difference between *OMIT and *NOPASS

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Difference between *OMIT and *NOPASS

    Hi all,

    Can someone explain me what the real difference is between *OMIT and *NOPASS?

    Thx already in advance

  • #2
    Re: Difference between *OMIT and *NOPASS

    Welcome Emo

    here is a great article on the subject from ItJungle..

    I notice that you use *nopass extensively in your free xRPG procedures to offer flexibility in your procedure calls, but you don’t seem to use *omit. I recently came across an example of a prototype that used both for the same parameter. Can you explain the difference between the two, why you use one but



    How to Use the *NOPASS and *OMIT Parameter Options


    I notice that you use *nopass extensively in your free xRPG procedures to offer flexibility
    in your procedure calls, but you don't seem to use *omit. I recently came across an
    example of a prototype that used both for the same parameter. Can you explain the
    difference between the two, why you use one but not the other, and why someone would
    use them together like this?

    --Rob

    Let me start by explaining the two options and how they differ.

    *NOPASS

    The *nopass parameter option allows you to not pass the parameter at all. Consider the
    prototype for the getDateStrUSA procedure from my xRPG Core Library :

    PHP Code:
    d getDateStrUSA   pr            10    varying
    d  date                           d   
    const options( *nopass )
    d  zero                           n   const options( *nopass )
    d  inc                            n   const options( *nopass )
    d  sep                           1    const options( *nopass 
    You'll notice right away that all the parameters use options(*nopass),
    meaning that they are completely optional. The first rule of *nopass is that
    every parameter after an optional one is also optional. This means that I have
    five different parameter lists for calling this procedure:


    PHP Code:
     /free
        
    // Get Todays Date as a USA Formatted Date String
        
    usaDateString getDateStrUSA();   

        
    // Get This Date as a USA Formatted Date String
        
    usaDateString getDateStrUSAdateField );

        
    // Get This Date as a USA Formatted Date String,
        //  not zero-suppressed
        
    usaDateString getDateStrUSAdateField : *off );

        
    // Get This Date as a USA Formatted Date String,
        //  not zero-suppressed, with separators
        
    usaDateString getDateStrUSAdateField : *off : *on );

        
    // Get This Date as a USA Formatted Date String,
        //  not zero-suppressed, with separators, use "." as separator
        
    usaDateString getDateStrUSAdateField : *off : *on '.' );
     /
    end-free 
    You'll notice the functionality changes with each parameter, again adding to
    the flexibility and usefulness of this procedure. This does require some coding
    discipline in the procedure. First of all, when you allow optional parameters,
    you must check inside the procedure to see whether the parameters were sent.
    This is done with the %parms() built-in function.

    You also must be aware that while a parameter in a procedure interface defines a
    local variable in the procedure, you must not use the parameter if it is not sent.
    The best way I've seen to handle this is to define variables within the procedure
    that match the incoming parameters and then use the parameter list to set their values.
    This also allows you to easily establish behavioral defaults for the procedure that
    are used in the absence of the sent parameters. Below is the code from my
    getDateStrUSA procedure that handles the parms coming in:

    PHP Code:
    d getDateStrUSA   pi            10    varying
    d  date                           d   
    const options( *nopass )
    d  zero                           n   const options( *nopass )
    d  inc                            n   const options( *nopass )
    d  sep                           1    const options( *nopass 

    d  dateIn         s               d
    d  zeroSuppress   s               n   inz
    ( *on )
    d  incSeps        s               n   inz( *on )
    d  sepChar        s              1    inz'/' )

     /
    free
       select 
    ;
          
    when  %parms() = ;
            
    dateIn = %date();
          
    when  %parms() = ;
            
    dateIn date ;
          
    when  %parms() = ;
            
    dateIn date ;
            
    zeroSuppress zero ;
          
    when  %parms() = ;
            
    dateIn date ;
            
    zeroSuppress zero ;
            
    incSeps inc ;
          
    when  %parms() = ;
            
    dateIn date ;
            
    zeroSuppress zero ;
            
    incSeps inc ;
            
    sepChar sep ;
        
    endsl ;
     /
    end-free 
    Notice how I set the default values in the procedure’s D–specs. These values
    are then overwritten if the parameters were sent. Now the rest of the code uses
    the Standalone fields defined in the procedure and not the parameter variables
    defined in the Procedure Interface.

    *OMIT

    The *omit parameter option allows you to not send a value for a parameter, but,
    unlike *nopass, it does require you to send a placeholder. If you are not going
    to send a value, *null must be sent in the parameter location. Using the same
    example procedure from above, had I used *omit instead of *nopass, the prototype
    would look like so:

    PHP Code:
    d getDateStrUSA   pr            10    varying
    d  date                           d   
    const options( *omit )
    d  zero                           n   const options( *omit )
    d  inc                            n   const options( *omit )
    d  sep                           1    const options( *omit 
    Using *omit would also change the way I can call this procedure:

    PHP Code:

     
    /free
        
    // Get Todays Date as a USA Formatted Date String
        
    usaDateString getDateStrUSA( *omit : *omit : *omit : *omit );   

        
    // Get This Date as a USA Formatted Date String
        
    usaDateString getDateStrUSAdateField : *omit : *omit : *omit );

        
    // Get This Date as a USA Formatted Date String,
        //  not zero-suppressed
        
    usaDateString getDateStrUSAdateField : *off : *omit : *omit );

        
    // Get This Date as a USA Formatted Date String,
        //  not zero-suppressed, with separators
        
    usaDateString getDateStrUSAdateField : *off : *on : *omit );

        
    // Get This Date as a USA Formatted Date String,
        //  not zero-suppressed, with separators, use "." as separator
        
    usaDateString getDateStrUSAdateField : *off : *on '.' );
     /
    end-free 

    I hope you agree that this is less elegant than *nopass. The good news is that,
    unlike *nopass, which requires every parameter after a nopass parameter to also
    be *nopass, you can pick and choose which parameters you want to be omittable.

    Handling the parameter checking in the procedure code is also different. Instead
    of checking for whether the parameter has been sent, you have to check whether a
    value or the *null placeholder was sent, by using the %addr() BIF.

    PHP Code:
    d getDateStrUSA   pi            10    varying
    d  date                           d   
    const options( *omit )
    d  zero                           n   const options( *omit )
    d  inc                            n   const options( *omit )
    d  sep                           1    const options( *omit 

    d  dateIn         s               d
    d  zeroSuppress   s               n   inz
    ( *on )
    d  incSeps        s               n   inz( *on )
    d  sepChar        s              1    inz'/' )

     /
    free
        
    if %addrdate ) = *NULL ;
          
    dateIn = %date();
        else ;
          
    dateIn date ;
        endif ;

        if %
    addrzero ) <> *NULL ;
          
    zeroSuppress zero ;
        endif ;

        if %
    addrinc ) <> *NULL ;
          
    incSeps inc ;
        endif ;

        if %
    addrsep ) <> *NULL ;
          
    sepChar sep ;
        endif ;
     /
    end-free 
    Again, I can rely on the default values in the procedure and only change them if
    the parameter was not omitted.

    Using Both Together

    One interesting approach is to combine *nopass and *omit:

    PHP Code:
    d getDateStrUSA   pr            10    varying
    d  date                           d   
    const options( *nopass : *omit )
    d  zero                           n   const options( *nopass : *omit )
    d  inc                            n   const options( *nopass : *omit )
    d  sep                           1    const options( *nopass : *omit 
    I now have an interesting assortment of calling parameter lists. I won't list
    them all here, but I will answer the question I'm sure you are asking right now:
    why would anyone do this?

    Take the procedure I've been using as an example. The parameters have a series
    of defaults for the optional parameters. If the programmer wants to use option 4
    to change the separator character to something other than the default, but wants
    the default behavior for parameters 1, 2, and 3, then he must know what values to
    pass to represent those defaults. Using this approach still allows the caller to
    have flexibility, without requiring the programmer to know what values to send
    to represent the default behavior. In this case, it could look like this instead:

    PHP Code:

    /free
        
    // Get This Date as a USA Formatted Date String,
        //  zero-suppressed, with separators, use "." as separator
        
    usaDateString getDateStrUSA( *omit : *omit : *omit '.' );
     /
    end-free

    Now the programmer doesn
    't have to research to remember that he should send %date(), *on, *on for the first three parameters. This could also allow the developer to change the default procedure behaviors without the programmer needing to change the calling code. I'll leave it to the reader to determine the pros and cons of that approach

    Using both options also increases the work you must do in order to handle those incoming parameters. If sentthe *omit placeholder counts as a parameterjust one whose value is nullSo basically you have to check for whether a parm was sent and whether it has a value of null

    d getDateStrUSA   pi            10    varying
    d  date                           d   
    const options( *nopass : *omit )
    d  zero                           n   const options( *nopass : *omit )
    d  inc                            n   const options( *nopass : *omit )
    d  sep                           1    const options( *nopass : *omit 

    d  dateIn         s               d
    d  zeroSuppress   s               n   inz
    ( *on )
    d  incSeps        s               n   inz( *on )
    d  sepChar        s              1    inz'/' )

     /
    free
        
    if %parms() = ;
          
    dateIn = %date();
        endif ;

        if %
    parms() > ;
          if %
    addrdate ) = *NULL ;
            
    dateIn = %date();
          else ;
            
    dateIn date ;
          endif ;
        endif ;

        if %
    parms()> ;
          if %
    addrzero ) <> *NULL ;
            
    zeroSuppress zero ;
          endif ;

        if %
    parms()> ;
          if %
    addrinc ) <> *NULL ;
            
    incSeps inc ;
          endif ;
        endif ;

        if %
    parms()> ;
          if %
    addrsep ) <> *NULL ;
            
    sepChar sep ;
          endif ;
        endif ;
     /
    end-free 
    All my answers were extracted from the "Big Dummy's Guide to the As400"
    and I take no responsibility for any of them.

    www.code400.com

    Comment


    • #3
      Re: Difference between *OMIT and *NOPASS

      Thx a lot for this clear explaination

      Comment


      • #4
        Re: Difference between *OMIT and *NOPASS

        Hi Jamief,

        I have some queries on the last eg. using both options (*Omit and *Nopass)
        1) Does that imply that when param 1 is not passed (passed with null placeholder) still any of the subsequent params can be passed (non null values)
        2) when a null placeholder is passed as parameter is that counted as a paramter value in %parms

        Comment


        • #5
          Re: Difference between *OMIT and *NOPASS

          As an aside, you must use *omit. I thought you could use colons with nothing, but I must have been mistaken.

          Code:
          /free
           
              // Compiler allows this
              myfield = getSomething(parm1 : *omit : parm3);
          
              // Compiler doesn't allow this
              myfield = getSomething(parm1 : : parm3);
          
          /end-free
          http://www.linkedin.com/in/chippermiller

          Comment

          Working...
          X