Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

7.121.4 SUBROUTINE の使用例 - 2

     

BBUSEテンプレートを使用したSUBROUTINEのドキュメント化技法

再帰

サブルーチン変数はローカルでスコープ指定されない

命名標準を使用してローカル・スコープ指定をエミュレートする

グローバルにスコープ指定された変数の保管/復元技法

7.121.3 SUBROUTINE の使用例 - 1

Anchor
SUBROUTINE_EX8
SUBROUTINE_EX8
BBUSEテンプレートを使用したSUBROUTINEのドキュメント化技法

...

Anchor
SUBROUTINE_EX9
SUBROUTINE_EX9
再帰

直接または間接を問わず、SUBROUTINEを再帰的に呼び出すことは避けてください。 

直接または間接を問わず、SUBROUTINEを再帰的に呼び出すことは避けてください。 

以下の例では、SUBROUTINE 以下の例では、SUBROUTINE SUB_Aがそれ自体によって再帰的に呼び出されます。 Aがそれ自体によって再帰的に呼び出されます。 

     SUBROUTINE SUB_A
<< ETC >>
EXECUTE SUB_A
<< ETC >>
ENDROUTINE

この例では、Visual LANSAでは致命的エラーが発生し、LANSA/ADでは単にコンパイルに失敗します。 

以下の例では、SUBROUTINE 以下の例では、SUBROUTINE SUB_AがSUBROUTINE ASUBROUTINE SUB_Bによって再帰的に呼び出されます。 Bによって再帰的に呼び出されます。 

     SUBROUTINE SUB_A
<< ETC >>
EXECUTE SUB_B
<< ETC >>
ENDROUTINE
SUBROUTINE SUB_B
<< ETC >>
EXECUTE SUB_A
<< ETC >>
ENDROUTINE

...

     Function  Options(*Direct)
Begin_Com Role(*Extends #Prim_Form)
Define_Com Class(#Salary.Visual) Name(#Salary) DisplayPosition(1) Height(19) Left(43) Parent(#Com_Owner) TabPosition(1) Top(72) Width(278)
         
Evtroutine handling(#com_owner.Initialize)
Set       #com_owner caption(*component_desc)
Invoke    #com_owner.SUB_A A(#Salary)
Endroutine 
         
Mthroutine SUB_A
Define_Map *output #Salary #A  
Set       #A Value(17.72)
Invoke    #com_owner.SUB_B
Endroutine 
         
Mthroutine SUB_B
Define_Com Class(#Salary) Name(#A)  
Set       #A Value(42.45)
Endroutine
End_Com

この場合、メソッドSUB_Aにより17.72が返されます。 

...

    Define_Com Class(#Salary) Name(#A)
         
Mthroutine SUB_A
Define_Map *output #Salary #ReturnValue  
Set       #A Value(17.72)
Invoke    #com_owner.SUB_B
Set       #ReturnValue Value(#A)
Endroutine 
         
Mthroutine SUB_B
Set       #A Value(42.45)
Endroutine

#Aはグローバルにスコープ指定されたコンポーネントであるため、この場合もメソッドSUB_Aにより42.45が返されます。すなわち、SUB_AおよびSUB_Bの両方が同じ#Aを参照します。 

...

     Subroutine Name(SUB_A) Parms((#A_001 *received))
Define    #A_001 Reffld(#Empno)  
*<<etc>>   
Fetch     (#Deptment) from_file(pslmst) with_key(#A_001)
*<< etc >> 
Endroutine

ここで、フィールド#DEPTMENTが、すでにプログラムの複数の場所で使用されているとします。 

...

     Subroutine Name(SUB_A) Parms((#A_001 *received))
    Define    #A_001 Reffld(#Empno)  
    Define    #Save_001 Reffld(#Deptment)  
    *<< etc >> 
    Change    #Save_001 #Deptment
    *<< etc >> 
    Fetch     (#Deptment) from_file(pslmst) with_key(#A_001)
    *<< etc >> 
    Change    #Deptment #Save_001
    *<< etc >> 
    Endroutine

これにより、#DEPTMENTの値がサブルーチンの実行によって変更されることはありません。 

...

     Subroutine Name(SUB_A) Parms((#A_001 *received))
    Define    #A_001 Reffld(#Empno)  
    Define    #SavA_001 Reffld(#Deptment)  
    Define    #SavB_001 Reffld(#Section)  
    Define    #SavC_001 Reffld(#Surname)  
    Define    #SavD_001 Reffld(#Startdte)  
    *<< etc >> 
    Change    #SavA_001 #Deptment
    Change    #SavB_001 #Section
    Change    #SavC_001 #Surname
    Change    #SavD_001 #Startdte
    *<< etc >> 
    Fetch     (#Deptment) from_file(pslmst) with_key(#A_001)
    *<< etc >> 
    Change    #Deptment #SavA_001
    Change    #Section #SavB_001 
    Change    #Surname #SavC_001 
    Change    #Startdte #SavD_001 
    *<< etc >> 
    Endroutine

ただし、単純な作業リストを使用すれば、より効率的でわかりやすく、保守しやすい方法で、同じ結果を得ることができます。 

     Subroutine Name(SUB_A) Parms((#A_001 *received))
    Define    #A_001 Reffld(#Empno) 

...

     Inz_List  #Save_001 Num_Entrys(1)
    *<< etc >> 
    Fetch     (#Deptment #Section #StartDte #Surname) from_file(pslmst) with_key(#A_001)
    *<< etc >>

上書きされている可能性ある、グローバルに定義されているすべてのフィールドの値を復元します。 

     Get_Entry 1 #Save_001
    Endroutine