Switching to mmreflect
Switching from 'xreflect' to 'mmreflect'
The module mmreflect now provides functional equivalence to xreflect (the latter is now deprecated), however, the usage of individual features is different given that the implementation of mmreflect relies on the recently introduced concept of unions and the possibility to work with subroutine references. The following listing compares the implementation of specific programming tasks with these two modules, using the examples from the xreflect manual. It should be noted that the functionality provided by mmreflect is more generic than the cases discussed here which focus on the portion of its functionality that matches what is accessible through xreflect. In particular, by working with unions there are no restrictions on the types or data structures that can be handled through mmreflect.
All functionality of the module xreflect is defined within the namespace xreflect to avoid clashes with functionality of the same name in mmreflect, the following code examples assume that namespace search has been specified for xreflect:
xreflect | mmreflect |
---|---|
uses "xreflect" nssearch xreflect |
uses "mmreflect" |
The type 'basicvalue'
The module xreflect defines the type basicvalue for scalar values of Mosel types boolean, integer, real, string, text. The implementation of mmreflect relies on standard Mosel union types that work with all Mosel types and arbitrary data structures. This generic implementation obviously makes it possible for users to define their own union type basicvalue (limited to the five scalar types of xreflect) with access routines matching closely the restricted functionality available through xreflect:
uses "mmreflect" ! Defining a union type 'basicvalue' to hold scalars of basic Mosel types or 'text' public declarations basicvalue = string or integer or real or boolean or text bvtrue, bvpi, bvhello: basicvalue end-declarations ! Defining xreflect-style access routines function getboolvalue(u: basicvalue):boolean returned:=u.boolean end-function public function gettype(u: basicvalue):string case u.typeid of boolean.id: returned:="boolean" integer.id: returned:="integer" real.id: returned:="real" string.id: returned:="string" text.id: returned:="string" else returned:="unsupported type" end-case end-function bvtrue := true ! Same as: bvtrue := basicvalue(true) bvpi := 3.14 ! Same as: bvpi := basicvalue(3.14) bvhello := 'hello' ! Same as: bvhello := basicvalue('hello') writeln("***Compatibility routines:") writeln('bv value=', bvtrue.boolvalue) ! Output: bv value=true writeln('bv type=', bvtrue.type) ! Output: bv type=boolean
However, unless such restrictive typing is indeed required we strongly recommend to switch to working with the generic union type any as shown in the following examples, using standard Mosel functionality and the new set of access routines provided through mmreflect.
The following Mosel code example shows correspondence of standard union type handling for
- type xreflect∼basicvalue
- subroutines xreflect∼get[bool|int|real|string|text]value and xreflect∼gettype
xreflect | mmreflect |
---|---|
!*** Working with type basicvalue public declarations bvtrue, bvseven, bvpi, bvhello, bvname: basicvalue end-declarations bvtrue := basicvalue(true) bvseven := basicvalue(7) bvpi := basicvalue(3.14) bvhello := basicvalue('hello') bvname := basicvalue(text('my name')) writeln('boolvalue=', bvtrue.boolvalue) ! Output: boolvalue=true writeln('is boolean:', bvtrue.type=XREFLECT_TYP_BOOL) ! Output: is boolean:true writeln('intvalue=', bvseven.intvalue) ! Output: intvalue=7 writeln('is integer:', bvseven.type=XREFLECT_TYP_INT) ! Output: is integer:true writeln('realvalue=', bvpi.realvalue) ! Output: realvalue=3.14 writeln('is real:', bvpi.type=XREFLECT_TYP_REAL) ! Output: is real:true writeln('stringvalue=' ,bvhello.stringvalue) ! Output: stringvalue=hello writeln('is string:', bvhello.type=XREFLECT_TYP_STRING) ! Output: is string:true writeln('textvalue=', bvname.textvalue) ! Output: textvalue=my name writeln('is string:', bvname.type=XREFLECT_TYP_STRING) ! Output: is string:true |
!*** Working with union types public declarations bvtrue, bvseven, bvpi, bvhello, bvname: any end-declarations bvtrue := true bvseven := 7 bvpi := 3.14 bvhello := 'hello' bvname := text('my name') writeln('boolvalue=', bvtrue.boolean) ! Output: boolvalue=true writeln('is boolean:', bvtrue.typeid=boolean.id) ! Output: is boolean:true writeln('intvalue=', bvseven.integer) ! Output: intvalue=7 writeln('is integer:', bvseven is integer) ! Output: is integer:true writeln('realvalue=', bvpi.real) ! Output: realvalue=3.14 writeln('is real:', bvpi is real) ! Output: is real:true writeln('stringvalue=', bvhello.string) ! Output: stringvalue=hello writeln('is string:', bvhello is string) ! Output: is string:true writeln('textvalue=', bvname.text) ! Output: textvalue=my name writeln('is text:', bvname is text) ! is text:true writeln('is string:', bvname is string) ! is string:false |
Accessing scalars, retrieving type and structural information
The subroutines of xreflect search for model entities by their name. With mmreflect the entities are first retrieved into a union via a call to findident and all subsequent operations are carried out directly on this union.
The following Mosel code example shows mmreflect correspondence for
- subroutines xreflect∼getscalarvalue, xreflect∼setscalarvalue, xreflect∼getvaluetype, xreflect∼getstructtype, and xreflect∼getindexsettypes
xreflect | mmreflect |
---|---|
public declarations mystr: string myarr: array(range) of real myset: set of integer mylst: list of integer mydate: date mybool=true myrng=1..5 end-declarations !*** Retrieving and setting scalar values mystr := 'hello' writeln('mystr=',getscalarvalue('mystr')) ! Output: myvar=hello setscalarvalue('mystr',basicvalue('world')) writeln('mystr=',mystr) ! Output: myvar=world !*** Accessing structural information writeln('myvar=', getvaluetype('mystr')) ! Output: mystr=string writeln('mystr struct is variable:', getstructtype('mystr')=XREFLECT_STR_REF) ! Output: mystr struct is variable:true writeln('myarr=', getvaluetype('myarr')) ! Output: myarr=real writeln('myarr struct is array:', getstructtype('myvar')=XREFLECT_STR_REF) ! Output: mystr struct is variable:true writeln('myset=', getvaluetype('myset')) ! Output: myset=integer writeln('myset struct is set:', getstructtype('myset')=XREFLECT_STR_SET) ! Output: mystr struct is variable:true writeln('myrng=', getvaluetype('myrng')) ! Output: myrng=integer writeln('myrng struct is set:', getstructtype('myrng')=XREFLECT_STR_SET) ! Output: mystr struct is variable:true writeln('mydate=', getvaluetype('mydate')) ! Output: mydate=unsupported writeln('mydate struct is variable:', getstructtype('mydate')=XREFLECT_STR_REF) ! Output: mydate struct is variable:true writeln('mybool=',getvaluetype('mybool')) ! Output: mybool=boolean writeln('mybool struct is const:', getstructtype('mybool')=XREFLECT_STR_CONST) ! Output: mystr struct is variable:true writeln('mylst=', getvaluetype('mylst')) ! Output: mylst=integer writeln('mylst struct is unsupported:', getstructtype('mylst')=XREFLECT_STR_UNSUPPORTED) !*** Index set type information public declarations myarr2: array(set of integer,set of string) of real end-declarations writeln('index set types=', getindexsettypes('myarr2')) ! Output: index set types=[`integer',`string'] |
public declarations mystr: string myarr: array(range) of real myset: set of integer mylst: list of integer mydate: date mybool=true myrng=1..5 a: any end-declarations !*** Retrieving and assigning scalar values mystr := 'hello' asproc(findident('mystr', a)) writeln('mystr=',a) ! Output: mystr=hello a := 'world' writeln('mystr=',mystr) ! Output: mystr=world !*** Accessing structural information res:=findident('mystr', a) writeln(testtype(res,STRUCT_REF+string.id)) ! Output: true writeln('mystr=string: ', a is string) ! Output: mystr=string: true writeln('mystr struct is variable:', a.struct=STRUCT_REF) ! Output: mystr struct is variable:true asproc(findident('myarr', a)) writeln('myarr=real: ', a.eltype=real.id) ! Output: myarr=real: true writeln('myarr struct is array:', a.struct=STRUCT_ARRAY) ! Output: myarr struct is array:true asproc(findident('myset', a)) writeln('myset=integer: ', a.eltype=integer.id) ! Output: myset=integer: true writeln('myset struct is set:', a.struct=STRUCT_SET) ! Output: myset struct is set:true asproc(findident('myrng', a)) writeln('myrng=integer: ', a.eltype=integer.id) ! Output: myrng=integer: true writeln('myrng struct is set:', a.struct=STRUCT_SET) ! Output: myrng struct is set:true asproc(findident('mydate', a)) writeln('mydate=date: ', a.typeid=date.id) ! Output: mydate=date: true writeln('mydate struct is variable:', a.struct=STRUCT_REF) ! Output: mydate struct is variable:true asproc(findident('mybool', a)) writeln('mybool=boolean: ', a.eltype=boolean.id) ! Output: mybool=boolean: true writeln('mybool struct is const:', a.struct=STRUCT_CONST) ! Output: mybool struct is const:true asproc(findident('mylst', a)) writeln('mylst=integer: ', a.eltype=integer.id) ! Output: mylst=integer: true writeln('mylst struct is list:', a.struct=STRUCT_LIST) ! Output: mylst struct is list:true !*** Index set type information public declarations myarr2: array(set of integer,set of string) of real lst: list of integer end-declarations asproc(findident('myarr2', a)) forall(i in 1..a.array.nbdim) lst+=[a.array.index(i).eltype] writeln('index set types=',lst) ! Output: index set types=[1,3] |
Accessing sets
Since the set access routines in mmreflect work on unions, the type of the set must be specified when accessing the corresponding set.
The following Mosel code example shows mmreflect correspondence for
- subroutines xreflect∼addsetelement, xreflect∼finaliseset, xreflect∼checksetcontains, xreflect∼getsetelements, and xreflect∼copysetelements
xreflect | mmreflect |
---|---|
public declarations dlst: list of basicvalue end-declarations myset := {1,3} addsetelement('myset', basicvalue(4)) writeln('myset=', myset) ! Output: myset={1,3,4} finaliseset('myset') ! No further changes !addsetelement('myset',basicvalue(6)) ! Error writeln('contains 6=', checksetcontains('myset', basicvalue(6))) ! Output: contains 6=false writeln('myset=', getsetelements('myset')) ! Output: myset=[1,3,4] dlst:=[] copysetelements('myset', dlst) writeln(dlst) ! Output: [1,3,4] |
public declarations dlst: list of any mysettype=set of integer end-declarations myset := {1,3} asproc(findident('myset', a)) if a is not mysettype then ! Alternatively: !if findident('myset', a, mysettype.id)=0 then writeln("Unexpected type"); exit(1) end-if a.mysettype+={4} writeln('myset=', myset) ! Output: myset={1,3,4} finalise(a.set) ! No further changes !a+={6} ! Results in an error writeln('contains 6=', 6 in a.mysettype) ! Output: contains 6=false writeln('myset=', a) ! Output: myset={1,3,4} dlst:=[] dlst:=list(a.set) writeln(dlst) ! Output: [1,3,4] |
Accessing arrays
When accessing arrays via mmreflect functionality the type of array elements needs to be stated, with the exception of the routines delcell, exists, and create for which it is sufficient to state the generic type any.
The following Mosel code example shows mmreflect correspondence for
- Subroutines xreflect∼arrayentryexists, xreflect∼getarrayentry, xreflect∼setarrayentry, xreflect∼getindexsetelements, xreflect∼copyindexsetelements, xreflect∼delarray, and xreflect∼delarrayentry
xreflect | mmreflect |
---|---|
public declarations myarr4: dynamic array(range,set of integer) of real dlst: list of basicvalue end-declarations myarr4(1,100) := 5.0 myarr4(1,101) := 5.1 myarr4(2,101) := 5.2 writeln('exists(2,100)=', arrayentryexists('myarr4', [basicvalue(2),basicvalue(100)])) ! Output: exists(2,100)=false !*** Accessing array elements writeln('myarr4(2,101)=', getarrayentry('myarr4', [basicvalue(2),basicvalue(101)])) ! Output: myarr4(2,101)=5.2 setarrayentry( 'myarr4', [basicvalue(1), basicvalue(101)], basicvalue(17.5) ) writeln('myarr4(1,101)=', myarr4(1,101)) ! Output: myarr4(1,101)=17.5 setarrayentry( 'myarr4', [basicvalue(3), basicvalue(100)], basicvalue(2.0) ) writeln('myarr4_i1=', getindexsetelements('myarr4',1)) ! Output: myarr4_i1=[1,2,3] copyindexsetelements('myarr4',1,dlst) writeln(dlst) ! Output: [1,2,3] delarrayentry('myarr4', [basicvalue(1),basicvalue(101)]) writeln('exists(1,101)=', arrayentryexists('myarr4', [basicvalue(1),basicvalue(101)])) ! Output: exists(1,101)=false delarray('myarr4') writeln('size=', myarr4.size) ! Output: size=0 |
public declarations myarr4: dynamic array(range,set of integer) of real dlst: list of any end-declarations myarr4(1,100) := 5.0 myarr4(1,101) := 5.1 myarr4(2,101) := 5.2 stat:= findident('myarr4', a) if not testtype(stat, STRUCT_ARRAY) then exit(1); end-if writeln('exists(2,100)=', exists(a.array(2,100).any)) ! Output: exists(2,100)=false !*** Array element access using standard union handling writeln('myarr4(2,101)=', a.array(2,101).real) ! Output: myarr4(2,101)=5.2 a.array(1,101).real := 17.5 writeln('myarr4(1,101)=', myarr4(1,101)) ! Output: myarr4(1,101)=17.5 !*** Alternative forms using array element access routines setarrval(a, 7.5, 1,101) getarrval(myarr4, u, 1,101) writeln('myarr4(1,101)=', u) ! Output: myarr4(1,101)=7.5 setarrval(myarr4, 2.5, [1,101]) getarrval(a, u, [1,101]) writeln('myarr4(1,101)=', u) ! Output: myarr4(1,101)=2.5 a.array(3,100).real := 2.0 writeln('myarr4_i1=', a.array.index(1)) ! Output: myarr4_i1=1..3 dlst:= list(a.array.index(1)) writeln(dlst) ! Output: [1,2,3] delcell(a.array(1,101).any) writeln('exists(1,101)=', exists(a.array(1,101).real)) ! Output: exists(1,101)=false reset(a.array) ! Same as: delcell(a.array) writeln('size=', myarr4.size) ! Output: size=0 |
Array iterators
The module mmreflect defines the type iterator that can be used in a similar way as the type arrayiterator of xreflect for enumerating the entries defined for a Mosel array.
The following Mosel code example shows mmreflect correspondence for
- type xreflect∼arrayiterator
- subroutines xreflect∼gethasvalue, xreflect∼getindices, xreflect∼getvalue, xreflect∼iteratorinit, and xreflect∼nextvalue
xreflect | mmreflect |
---|---|
public declarations myarray:dynamic array(range,set of string) of real end-declarations ! Populate our example data-set myarray(100,'fred') := 100.1 myarray(100,'jim') := 101.5 myarray(101,'fred') := 215.7 ! Iterate through array entries using the arrayiterator declarations it:arrayiterator end-declarations iteratorinit(it, 'myarray') writeln(it.hasvalue) ! Output: false (before start) while (nextvalue(it)) do write('myarray(', it.indices) ! Index tuple: list of basicvalue writeln(') = ', it.value) end-do ! Output: ! myarray([100,fred]) = 100.1 ! myarray([100,jim]) = 101.5 ! myarray([101,fred]) = 215.7 writeln(it.hasvalue) ! Output: false (after end) |
public declarations myarray:dynamic array(range,set of string) of real end-declarations ! Populate our example data-set myarray(100,'fred') := 100.1 myarray(100,'jim') := 101.5 myarray(101,'fred') := 215.7 ! Iterate through array entries using the iterator declarations it:iterator u:any end-declarations inititer(it, myarray) writeln(it.status) ! Output: 0 (before start) writeln(exists(myarray(it))) ! Output: false while (nextcell(it)) do write('myarray(', it.indices) ! Index tuple: list of any writeln(') = ', myarray(it)) !*** Alternative form: using getarrval with iterator ! getarrval(myarray,u,it.indices) ! write(') = ',u) end-do ! Output: ! myarray([100,fred]) = 100.1 ! myarray([100,jim]) = 101.5 ! myarray([101,fred]) = 215.7 writeln(it.status) ! Output: 2 (after end) writeln(exists(myarray(it))) ! Output: false |
Accessing subroutines
The module mmreflect generalizes the handling of subroutines to include subroutine arguments and it also adds functionality for handling functions.
The following Mosel code example shows mmreflect correspondence for
- subroutines xreflect∼findproc and xreflect∼callproc
xreflect | mmreflect |
---|---|
!*** Calling a procedure public procedure myproc writeln('hello world'); end-procedure callproc('myproc') ! Output: hello world public procedure myproc1 writeln('hello'); end-procedure public procedure myproc2(xyz:string) writeln('world: ', xyz); end-procedure ! Subroutines with arguments are not supported !*** Checking for a subroutine writeln('findproc(myproc1)=', findproc('myproc1')) ! Output: findproc(myproc1)=true ! Calling the subroutine callproc('myproc') ! Output: hello world writeln('findproc(myproc2)=', findproc('myproc2')) ! myproc2 will not be found as it takes an argument ! Output: findproc(myproc2)=false !*** Functions are not supported public function myfunc: text returned:=text('-')*10 end-function writeln('findproc(myfunc)=', findproc('myfunc')) ! Output: findproc(myfunc)=false |
!*** Calling a procedure public procedure myproc writeln('hello world'); end-procedure callproc('myproc') ! Output: hello world public procedure myproc1 writeln('hello'); end-procedure public procedure myproc2(xyz:string) writeln('world: ', xyz); end-procedure ! Calling a subroutine with an argument callproc('myproc2', 'my text') ! Output: world: my text !*** Checking for a subroutine declarations srtype=procedure ! Type definition for 'findident' srtype2=procedure(string) end-declarations writeln('findproc(myproc1)=', getstruct(findident('myproc1',a,srtype.id))=STRUCT_ROUTINE) ! Output: findproc(myproc1)=true ! Calling the subroutine that has been retrieved callproc(a) ! Output: hello world writeln('findproc(myproc2)=', getstruct(findident('myproc2',a,srtype.id))=STRUCT_ROUTINE) ! Output: findproc(myproc2)=false writeln('findproc(myproc2)=', getstruct(findident('myproc2',a,srtype2.id))=STRUCT_ROUTINE) ! Output: findproc(myproc2)=true !*** Support for functions public function myfunc: text returned:='-'*10 end-function writeln('findproc(myfunc)=', testtype(findident('myfunc',a), STRUCT_ROUTINE+text.id)) ! Output: findproc(myfunc)=true declarations res: any end-declarations callfunc(a,res) writeln("Result=", res) ! Output: Result=---------- |
© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.