5

RPGLeを使ってリフレクションができたらいいのにと思います。つまり、「実行時にオブジェクトの機能を決定するプロセスまたはメカニズム」です。

このデータ構造があると想像してください:

 D DS_Format       DS                  Qualified Based(pDS_Format)
 D  Type                         20I 0 Inz(1)
 D  Label                        50A   Inz('myLabel')
 D  Description                5000A   Inz('myDescription')        

リフレクション API を使用すると、次のことができます。

Reflection_ListSubfields(DS_Format); 

=> 次の配列を返します: { 'Type', 'Label', 'Description' }

そして、私はできる:

Reflection_GetSubfield(DS_Format : 'Label'); => return 'myLabel'

私もこれができたらいいのに:

Reflection_GetSubfieldType(DS_Format : 'Label'); => return 'A'
Reflection_GetSubfieldLength(DS_Format : 'Label'); => return 50
Reflection_GetSubfieldPrecision(DS_Format : 'Type'); => return 0

これで、次のようなことができると思います(少し作業します):

SerializeXml(DS_Format); //I build xml with one line of code !

そして得る:

<DS_Format>
    <Type>1</Type>
    <Label>myLabel</Label>
    <Description>myDescription</Description>
</DS_Format>

逆に DeserializeXml(myXml); を使用すると、

リフレクションは、本当にクールな API を構築するのに役立ちます。方法はありますか?

4

3 に答える 3

3

私はこれらの概念のいくつかを熟考しており、回避策があるかもしれません。(現時点では、完全な回答を書いて詳細を具体化する時間はまだありませんが、希望があることを確認するのを待っていました;-)ただし、チートと見なす人もいます。)

基本的な概念は次のとおりです。日構造の場合に目的の形式でテーブルを定義し、DS を外部で定義できるようにすると、埋め込み SQL を使用して、テーブルを DESCRIBE するか、SYSCOLUMNS をクエリして、できればプロシージャでフィールド定義を取得できます。

確かに、これは反射と同じことではありませんが、ほぼ同じことを達成できます。そして、これはおそらく限られた状況でのみ行うでしょう。他の人がさまざまな問題を指摘すると確信していますが、ここでのポイントはそれが可能であるということです。

于 2013-10-30T16:33:18.220 に答える
2

デバッグ API が、あなたが求めている動作の少なくとも一部を得るのに役立つかどうか疑問に思っています...

http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/apis/debug1.htm

含まれている関数の 1 つは Dump Module Variables (QteDumpModuleVariables) A​​PI です。

もちろん、これらの API を使用するにはデバッグ モードにする必要があります...

于 2014-02-19T21:13:55.427 に答える
2

以下は、WarrenT のアイデアの非常に単純な実装です。

create table ds_format
(
   Type        numeric(20, 0),
   Label       char(50),
   Description char(5000)
);

SQL 記述域の定数:

D SQL_NUM         C                   99

フィールド名の配列を返す SQLRPGLE モジュールでの Reflection_ListSubfields の実装:

P Reflection_ListSubfields...                         
P                 B                                
 *                                                 
D                 PI            80A   Dim(SQL_NUM) 
D  name                         30A   Const
 *                                                 
D tableName       S                   Like(name)   
D i               S              3S 0 Inz          
D fieldList       S             80A   Dim(SQL_NUM) 
 /free                                             
    EXEC SQL include SQLDA;                        

    // retrieve description of the table                                           
    tableName = name;                              
    EXEC SQL describe table :tableName into :sqlda;

    // loop over all fields and
    // retrieve the name                                                   
    for i = 1 to SQLD;                             
       SQLVAR = SQL_VAR(i);                        
       fieldList(i) = SQLNAME;                     
    endfor;                                        

    return fieldList;
 /end-free           
P                 E  

値を文字列として返す Reflection_GetSubfield の非常に大まかな実装:

P Reflection_GetSubfield...                                   
P                 B                                        
 *                                                         
D                 PI         32000A   Varying              
D  dataStruct                     *   Const                
D  name                         30A   Const
D  fieldName                    80A   Const                
 *                                                         
D tableName       S                   Like(name)           
D i               S              3S 0 Inz                  
D start           S              6S 0 Inz(1)               
D length          S              6S 0 Inz(1)               
D p_str           S               *                        
D str             S          32000A   Based(p_str)         
D value           S          32000A   Varying              
 /free                                                 
    EXEC SQL include SQLDA;                        

    // retrieve description of the table                                           
    tableName = name;                                  
    EXEC SQL describe table :tableName into :sqlda;    

    // loop over all fields
    for i = 1 to SQLD;                                 
       SQLVAR = SQL_VAR(i);                            

       length = SQLLEN;                                

       // Zoned decimal?
       if SQLTYPE = 489;                               
          length = SQLLEN / 256;                       
       endif;                                          

       // field found?                                                       
       if SQLNAME = fieldName;                         
          leave;                                       
       endif;

       start += length;                             
    endfor;                                            

    p_str = dataStruct;                                 

    // retrieve value from our string                                                
    value = %trim(%subst(str: start: length));  

    return value;                               
 /end-free                                      
P                 E                             

この情報があれば、他の 3 つの手順を実装するのは比較的簡単だと思います。

于 2014-04-25T08:55:44.860 に答える