Sponsored Links
Sponsored Link

sponsored links

Collapse

Announcement

Collapse
No announcement yet.

Replacing RPG III MOVE statements

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

  • Replacing RPG III MOVE statements

    Replacing old RPG III MOVE, MOVEA, and MOVEL statements with Free-format alternatives is going to drive me insane! Maybe it was just the way things were done 20-30 years ago ... but it makes me shudder! ;-)

    We have code that, depending upon some value, either Z-ADDs one numeric value to another or MOVEs one numeric value to another. I'm pretty sure that Z-ADD preserves decimal alignment, but MOVE is (dangerously) powerful. You can move character to character, numeric to numeric, numeric to character, and even character to numeric, and bytes are moved right-to-left. So we have code like this:

    Code:
    D FIELD1          S             15  3 INZ(123.456)
    D FIELD2          S             15  5
    D FIELD3          S             15  0
    
    D                 DS
    D  NUM150                 1     15  0
    D  NUM154                 1     15  4
     * Same digits interpreted two ways.
    
    C                   Z-ADD     FIELD1        FIELD2
    * FIELD2 = 123.45600.... right?
    
    C                   MOVE      FIELD1        FIELD3
     * FIELD3 = 123456[.0], implicitly multiplying by 1000
    
     * And with NUM150 as a database field filled with a READ statement,
     *   NUM154 represents this value divided by 10,000, without doing any operation at all.
    I consider these subtle operations really bad style, and can understand why conversion tools don't handle MOVE statements. As I convert to Free-format, I want to make things quite clear.

    This seems a bit "clunky" ... but is explicit:
    Code:
    FIELD3 = FIELD1 * %DECPOS(FIELD1)**10;
    FIELD2 = FIELD3 / %DECPOS(FIELD2)**10;
    // or even
    FIELD2 = FIELD1 / ( (%DECPOS(FIELD2) - %DECPOS(FIELD1) )**10;  // Yikes!
    
    // And to round one field's value to another:
    DCL-C cLenField2    %LEN(Field2);                     
    DCL-C cDecPosField1 %DECPOS(Field1);              
    
    Field2 = %DECH(Field2 : cLenField2 : cDecPosField1);
    Has anyone else seen such things, and have suggestions for how to deal with them? Are my alternatives even more obscure than the code I'm trying to replace? Have any relevant general advice on replacing MOVE statements?

  • #2
    Actually the Arcad tools do handle MOVEs. I thought that Linoma did too but it seems not - have to check on that.

    I think your conversion of the Z-ADD (which was always a bloody silly op-code) is way OTT. All you need is Field2 = Field1; Had any change in precision been needed the Z-ADD would have taken care of it the same way as EVAL.

    As to the other conversion I think a better practice is to use a DS to do the conversion and wrap it up in a subproc with a suitable name. This is a sample - it can be made more generic.

    Code:
    dcl-ds  *N;
       input    zoned(15: 5);
       output  zoned(15)  Overlay(input);
    end-ds;
    
    input =  FIELD1;
    FIELD3 = output;
    Not tested but you get the idea.

    Comment


    • #3
      Yes, JonBoy. To be fair, I should have written, "... conversion tools don't handle many MOVE statements." (For identically-defined fields, a MOVE becomes a simple EVAL/=.) And it seems to me that the Arcad tool handles more MOVEs/MOVEAs/MOVELs than the also-very-nice Linoma tool. (Considering the size of our conversion team [i.e. me], we're licensing Arcad Transformer.)

      Thanks for your comment about using a DS this way; this is actually how our current code works. Maybe once someone recognizes this is being done in a program (or an entire shop), s/he is alerted to look for such a structure when it at first appears that the code is pricing paper clips at hundreds of dollars each! ;-)

      Comment


      • #4
        As I noted - I would always wrap it in a subproc - that way the name can be meaningful and the mechanics become irrelevant because you don't need to study them.

        Comment


        • #5
          The problem with MOVE is that its very hard to follow for someone who isn't used to it. Therefore, the decision was made (20 years ago!) not to move forward with it.

          When you see a statement like this, what is it doing?
          Code:
          MOVE FIELD1 FIELD2
          Is it simply copying the value of FIELD1 into FIELD2? Or taking a substring? or padding it with blanks? Or is it a numeric field that's being multiplied or divided by shifting the digits? Or... what else?

          Its intention isn't obvious. By contrast FIELD2 = FIELD1 or FIELD2 = %SUBST(FIELD1:1:5) are very clear. Likewise FIELD2 = FIELD1 * 100 is very simple to understand... you know what that code is doing. Even in 1994 when we first got EVAL, and free-format wasn't even on the horizon, when MOVE was still widely used and accepted, I didn't use it. Not by conscious choice, because honestly, I didn't even think about it... EVAL just made for better code.

          But, even if you disagree with me on these points, its pointless to debate it today. This decision was made 20 years ago... its time to move on.

          Comment


          • #6
            After seeing all the ways MOVE is used in older code, it became my suspicion that preventing propagation of "confusing" code was why the MOVE op codes were eliminated from Free-format. (Those people in Toronto are pretty smart!) Thanks for that info, Scott.
            You shouldn't burden the next programmer with having to pore over the RPG reference to understand how MOVE 'RAT' 1234567 clears the compiler and results in 1234913. ;-) Believe me, inheriting such code, I couldn't agree with Scott more!

            Comment


            • #7
              The removal of MOVE was such a big deal for so many RPG programmers (many of who are convinced that they fully understand it - darned if I do without the manual in hand and even then ...) that I dedicate two or three charts of my "Freeform in a Nutshell" presentation to why MOVE was removed. Slowly but surely people are getting used to why it was a bad idea.

              Comment


              • #8
                Happy to see it go. An intrinsic attribute of the opcode is that since the operation performed may vary depending on the operands' definition, the opcode is error prone.

                Comment

                sponsored links

                Collapse

                Working...
                X