我希望我能用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)相反;
反思会帮助我建立真正酷的apis。 有什么办法吗?
答案 0 :(得分:3)
我一直在考虑其中的一些概念,并可能有一个解决方法。 (我现在还没有时间写完整的答案并充实细节,但是等着你看到有一些希望;-)虽然有些人可能认为这是骗子。)
基本概念是这样的:如果您定义了一个具有所需格式的表,如果您的日期结构,使DS能够在外部定义,那么使用嵌入式SQL,您可以对表进行DESCRIBE或查询SYSCOLUMNS以获取您的字段定义,最好是在程序中。
当然,这与反思不同,但可以完成同样的事情。人们可能只会在有限的情况下这样做。我相信其他人会指出各种各样的问题,但这里的重点是它是可能的。
答案 1 :(得分:2)
我想知道调试API是否可以帮助您获得至少一些您要求的行为......
http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/apis/debug1.htm
其中一个功能是 转储模块变量(QteDumpModuleVariables)API
当然,你的工作必须处于调试模式才能使用这些API ......
答案 2 :(得分: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
我想有了这些信息,实现其他三个程序相对容易。