diff --git a/hpcgap/lib/read1.g b/hpcgap/lib/read1.g index 077eac1153..cdb34878f1 100644 --- a/hpcgap/lib/read1.g +++ b/hpcgap/lib/read1.g @@ -34,7 +34,7 @@ ReadLib( "string.g" ); ReadLib( "cyclotom.g" ); ReadLib( "set.gd" ); -ReadLib( "record.g" ); +ReadLib( "record.gd" ); ReadLib( "coll.gi" ); ReadLib( "queue.g" ); @@ -56,6 +56,9 @@ ReadLib( "info.gd" ); ReadLib( "assert.gd" ); ReadLib( "files.gd" ); ReadLib( "streams.gd" ); +ReadLib( "show.gd" ); + +ReadLib( "record.gi" ); ReadLib( "matobj1.gd" ); ReadLib( "vecmat.gd" ); diff --git a/lib/read1.g b/lib/read1.g index c1d93410be..191e056687 100644 --- a/lib/read1.g +++ b/lib/read1.g @@ -34,7 +34,7 @@ ReadLib( "string.g" ); ReadLib( "cyclotom.g" ); ReadLib( "set.gd" ); -ReadLib( "record.g" ); +ReadLib( "record.gd" ); ReadLib( "coll.gi" ); ReadLib( "queue.g" ); @@ -58,6 +58,8 @@ ReadLib( "files.gd" ); ReadLib( "streams.gd" ); ReadLib( "show.gd" ); +ReadLib( "record.gi" ); + ReadLib( "matobj1.gd" ); ReadLib( "vecmat.gd" ); ReadLib( "vec8bit.gd" ); diff --git a/lib/record.g b/lib/record.g deleted file mode 100644 index 99dd90d9e0..0000000000 --- a/lib/record.g +++ /dev/null @@ -1,450 +0,0 @@ -############################################################################# -## -#W record.g GAP library Thomas Breuer -#W & Frank Celler -## -## -#Y Copyright (C) 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany -#Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland -#Y Copyright (C) 2002 The GAP Group -## -## This file contains methods for records. -## Compared to &GAP; 3, where records were used to represent domains and -## all kinds of external arithmetic objects, in &GAP; 4 there is no -## important role for records. -## So the standard library provides only methods for `PrintObj', `String', -## `=', and `<', and the latter two are not installed to compare records -## with objects in other families. -## -## In order to achieve a special behaviour of records as in &GAP; 3 such -## that a record can be regarded as equal to objects in other families -## or such that a record can be compared via `<' with objects in other -## families, one can load the file `compat3c.g'. -## - - -############################################################################# -## -#C IsRecord( ) -#C IsRecordCollection( ) -#C IsRecordCollColl( ) -## -## <#GAPDoc Label="IsRecord"> -## -## -## -## -## -## -## test -## IsRecord( rec( a := 1, b := 2 ) ); -## true -## gap> IsRecord( IsRecord ); -## false -## ]]> -## -## -## <#/GAPDoc> -## -DeclareCategoryKernel( "IsRecord", IsObject, IS_REC ); -DeclareCategoryCollections( "IsRecord" ); -DeclareCategoryCollections( "IsRecordCollection" ); - - -############################################################################# -## -#V RecordsFamily . . . . . . . . . . . . . . . . . . . . . family of records -## -## -## -## -## -## -## -## -BIND_GLOBAL( "RecordsFamily", NewFamily( "RecordsFamily", IS_REC ) ); - - -############################################################################# -## -#V TYPE_PREC_MUTABLE . . . . . . . . . . . type of a mutable internal record -## -## -## -## -## -## -## -## -BIND_GLOBAL( "TYPE_PREC_MUTABLE", - NewType( RecordsFamily, IS_MUTABLE_OBJ and IS_REC and IsInternalRep ) ); - - -############################################################################# -## -#V TYPE_PREC_IMMUTABLE . . . . . . . . type of an immutable internal record -## -## -## -## -## -## -## -## -BIND_GLOBAL( "TYPE_PREC_IMMUTABLE", - NewType( RecordsFamily, IS_REC and IsInternalRep ) ); - - -############################################################################# -## -#o \.( , ) . . . . . . . . . . . . . . . . get a component value -## -DeclareOperationKernel( ".", [ IsObject, IsObject ], ELM_REC ); - - -############################################################################# -## -#o IsBound\.( , ) . . . . . . . . . . . . . . test a component -## -DeclareOperationKernel( "IsBound.", [ IsObject, IsObject ], ISB_REC ); - - -############################################################################# -## -#o \.\:\=( , , ) . . . . . . . . . . . . . assign a value -## -DeclareOperationKernel( ".:=", [ IsObject, IsObject, IsObject ], ASS_REC ); - - -############################################################################# -## -#o Unbind\.( , ) . . . . . . . . . . . . . . . unbind component -## -DeclareOperationKernel( "Unbind.", [ IsObject, IsObject ], UNB_REC ); - - -############################################################################# -## -#A RecNames( ) -## -## <#GAPDoc Label="RecNames"> -## -## -## -## -## returns a list of strings corresponding to the names of the record -## components of the record record. -##

-## r := rec( a := 1, b := 2 );; -## gap> Set(RecNames( r )); # 'Set' because ordering depends on GAP session -## [ "a", "b" ] -## ]]> -##

-## Note that you cannot use the string result in the ordinary way to access -## or change a record component. -## You can use the record.(name) construct for that, -## see and -## . -## -## -## <#/GAPDoc> -## -DeclareAttribute( "RecNames", IsRecord ); - - -############################################################################# -## -#M RecNames( ) . . . . . . . . . . . . . . . . names of components -## -InstallMethod( RecNames, - "for a record in internal representation", - [ IsRecord and IsInternalRep ], - REC_NAMES ); - - -############################################################################# -## -#F NamesOfComponents( ) -## -## <#GAPDoc Label="NamesOfComponents"> -## -## -## -## -## For a component object comobj, -## returns a list of strings, -## which are the names of components currently bound in comobj. -##

-## For a record comobj, -## returns the result of -## . -## -## -## <#/GAPDoc> -## -BIND_GLOBAL( "NamesOfComponents", function( obj ) - if IsComponentObjectRep( obj ) then - return REC_NAMES_COMOBJ( obj ); - elif IsRecord( obj ) then - return RecNames( obj ); - else - Error( " must be a component object or a record" ); - fi; - end ); - - -############################################################################# -## -#V IdentifierLetters . . . . . . . .characters allowed in normal identifiers -## -## This is used to produce warning messages when the XxxxGlobal functions -## are applied to a name which could not be read in by the parser without -## escapes -## - -BIND_GLOBAL( "IdentifierLetters", - Immutable("0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz") ); - -IsSet( IdentifierLetters ); # ensure GAP knows that this is a set - - -############################################################################# -## -#m PrintObj( ) -## -## The record is printed by printing all its components. -## -InstallMethod( PrintObj, - "record", - [ IsRecord ], -## Changed to use sorted component names to make printing nicer to read and -## independent of session (i.e., the ordering in which component names were -## first used). Except for the sorting of components this does the same as -## the former (now removed) kernel function FuncPRINT_PREC_DEFAULT. - function( record ) - local com, i, snam, nam, names, order; - Print("\>\>rec(\n\>\>"); - com := false; - - names := List(RecNames(record)); - order := [1..Length(names)]; - SortParallel(names, order); - - for i in [1..Length(names)] do - nam := names[i]; - if com then - Print("\<\<,\n\>\>"); - else - com := true; - fi; - SET_PRINT_OBJ_INDEX(order[i]); - # easy if nam is integer or valid identifier: - if ForAll(nam, x-> x in IdentifierLetters) and Size(nam) > 0 then - Print(nam, "\< := \>"); - else - # otherwise we use (...) syntax: - snam := String(nam); - Print("("); View(snam); Print(")\< := \>"); - fi; - PrintObj(record.(nam)); - od; - Print(" \<\<\<\<)"); -end); - -############################################################################# -## -#m String( ) . . . . . . . . . . . . . . . . . . . . for a record -## -InstallMethod( String, - "record", - [ IsRecord ], - function( record ) - local str, nam, com; - - str := "rec( "; - com := false; - for nam in Set(RecNames( record )) do - if com then - Append( str, ", " ); - else - com := true; - fi; - Append( str, nam ); - Append( str, " := " ); - if IsStringRep( record.( nam ) ) - or ( IsString( record.( nam ) ) - and not IsEmpty( record.( nam ) ) ) then - Append( str, "\"" ); - Append( str, String( record.(nam) ) ); - Append( str, "\"" ); - else - Append( str, String( record.(nam) ) ); - fi; - od; - Append( str, " )" ); - # should not be necessary if all methods for components are alright - ConvertToStringRep( str ); - return str; -end ); - - -############################################################################# -## -#m ViewObj( ) . . . . . . . . . . . . . . . for a record (default) -## -InstallMethod( ViewObj, - "record", - [ IsRecord ], - function( record ) - local nam, com, i, snam, names, order; - Print("\>\>rec( \>\>"); - com := false; - - names := List(RecNames(record)); - order := [1..Length(names)]; - SortParallel(names, order); - - for i in [1..Length(names)] do - nam := names[i]; - if com then - Print("\<,\< \>\>"); - else - com := true; - fi; - SET_PRINT_OBJ_INDEX(order[i]); - # easy if nam is integer or valid identifier: - if ForAll(nam, x-> x in IdentifierLetters) and Size(nam) > 0 then - Print(nam, " := "); - else - # otherwise we use (...) syntax: - snam := String(nam); - Print("("); View(snam); Print(") := "); - fi; - ViewObj(record.(nam)); - od; - Print(" \<\<\<\<)"); -end); - - -############################################################################# -## -#m = -## -InstallMethod( \=, - "record = record", - IsIdenticalObj, - [ IsRecord, IsRecord ], - EQ_PREC ); - - -############################################################################# -## -#m < -## -InstallMethod( \<, - "record < record", - IsIdenticalObj, - [ IsRecord, IsRecord ], - LT_PREC ); - - -# methods to catch error cases - -############################################################################# -## -#m \. -## -InstallMethod(\.,"catch error",true,[IsObject,IsObject],0, -function(obj,nr) -local msg; - msg:=Concatenation("illegal access to record component `obj.", - NameRNam(nr),"'\n", - "of the object . (Objects by default do not have record components.\n", - "The error might be a relic from translated GAP3 code.) "); - Error(msg); -end); - -############################################################################# -## -#m IsBound\. -## -InstallMethod(IsBound\.,"catch error",true,[IsObject,IsObject],0, -function(obj,nr) -local msg; - msg:=Concatenation("illegal access to record component `IsBound(obj.", - NameRNam(nr),")'\n", - "of the object . (Objects by default do not have record components.\n", - "The error might be a relic from translated GAP3 code.) "); - Error(msg); -end); - -############################################################################# -## -#m Unbind\. -## -InstallMethod(Unbind\.,"catch error",true,[IsObject,IsObject],0, -function(obj,nr) -local msg; - msg:=Concatenation("illegal access to record component `Unbind(obj.", - NameRNam(nr),")'\n", - "of the object . (Objects by default do not have record components.\n", - "The error might be a relic from translated GAP3 code.) "); - Error(msg); -end); - -############################################################################# -## -#m \.\:\= -## -InstallMethod(\.\:\=,"catch error",true,[IsObject,IsObject,IsObject],0, -function(obj,nr,elm) -local msg; - msg:=Concatenation("illegal assignement to record component `obj.", - NameRNam(nr),"'\n", - "of the object . (Objects by default cannot have record components.\n", - "The error might be a relic from translated GAP3 code.) "); - Error(msg); -end); - -############################################################################# -## -#F SetNamesForFunctionsInRecord( [, ][, ]) -## -## set the names of functions bound to components of a record. -## -BIND_GLOBAL("SetNamesForFunctionsInRecord", - function( arg ) - local recname, next, record, fields, field; - if LENGTH(arg) = 0 or not IS_STRING(arg[1]) then - Error("SetNamesForFunctionsInRecord: you must give a record name"); - fi; - recname := arg[1]; - next := 2; - if LENGTH(arg) >= next and IS_REC(arg[next]) then - record := arg[2]; - next := 3; - else - record := VALUE_GLOBAL(recname); - fi; - if LENGTH(arg) >= next and IS_LIST(arg[next]) then - fields := arg[next]; - else - fields := REC_NAMES(record); - fi; - for field in fields do - if IS_STRING(field) then - if IsFunction(record.(field)) then - SetNameFunction(record.(field), Concatenation(recname,".",field)); - fi; - fi; - od; -end); - - - -############################################################################# -## -#E - diff --git a/lib/record.gd b/lib/record.gd new file mode 100644 index 0000000000..d20061d7b5 --- /dev/null +++ b/lib/record.gd @@ -0,0 +1,198 @@ +############################################################################# +## +#W record.gd GAP library Thomas Breuer +#W & Frank Celler +## +## +#Y Copyright (C) 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany +#Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland +#Y Copyright (C) 2002 The GAP Group +## +## This file contains methods for records. +## Compared to &GAP; 3, where records were used to represent domains and +## all kinds of external arithmetic objects, in &GAP; 4 there is no +## important role for records. +## So the standard library provides only methods for `PrintObj', `String', +## `=', and `<', and the latter two are not installed to compare records +## with objects in other families. +## +## In order to achieve a special behaviour of records as in &GAP; 3 such +## that a record can be regarded as equal to objects in other families +## or such that a record can be compared via `<' with objects in other +## families, one can load the file `compat3c.g'. +## + + +############################################################################# +## +#C IsRecord( ) +#C IsRecordCollection( ) +#C IsRecordCollColl( ) +## +## <#GAPDoc Label="IsRecord"> +## +## +## +## +## +## +## test +## IsRecord( rec( a := 1, b := 2 ) ); +## true +## gap> IsRecord( IsRecord ); +## false +## ]]> +## +## +## <#/GAPDoc> +## +DeclareCategoryKernel( "IsRecord", IsObject, IS_REC ); +DeclareCategoryCollections( "IsRecord" ); +DeclareCategoryCollections( "IsRecordCollection" ); + + +############################################################################# +## +#V RecordsFamily . . . . . . . . . . . . . . . . . . . . . family of records +## +## +## +## +## +## +## +## +BIND_GLOBAL( "RecordsFamily", NewFamily( "RecordsFamily", IS_REC ) ); + + +############################################################################# +## +#V TYPE_PREC_MUTABLE . . . . . . . . . . . type of a mutable internal record +## +## +## +## +## +## +## +## +BIND_GLOBAL( "TYPE_PREC_MUTABLE", + NewType( RecordsFamily, IS_MUTABLE_OBJ and IS_REC and IsInternalRep ) ); + + +############################################################################# +## +#V TYPE_PREC_IMMUTABLE . . . . . . . . type of an immutable internal record +## +## +## +## +## +## +## +## +BIND_GLOBAL( "TYPE_PREC_IMMUTABLE", + NewType( RecordsFamily, IS_REC and IsInternalRep ) ); + + +############################################################################# +## +#o \.( , ) . . . . . . . . . . . . . . . . get a component value +## +DeclareOperationKernel( ".", [ IsObject, IsObject ], ELM_REC ); + + +############################################################################# +## +#o IsBound\.( , ) . . . . . . . . . . . . . . test a component +## +DeclareOperationKernel( "IsBound.", [ IsObject, IsObject ], ISB_REC ); + + +############################################################################# +## +#o \.\:\=( , , ) . . . . . . . . . . . . . assign a value +## +DeclareOperationKernel( ".:=", [ IsObject, IsObject, IsObject ], ASS_REC ); + + +############################################################################# +## +#o Unbind\.( , ) . . . . . . . . . . . . . . . unbind component +## +DeclareOperationKernel( "Unbind.", [ IsObject, IsObject ], UNB_REC ); + + +############################################################################# +## +#A RecNames( ) +## +## <#GAPDoc Label="RecNames"> +## +## +## +## +## returns a list of strings corresponding to the names of the record +## components of the record record. +##

+## r := rec( a := 1, b := 2 );; +## gap> Set(RecNames( r )); # 'Set' because ordering depends on GAP session +## [ "a", "b" ] +## ]]> +##

+## Note that you cannot use the string result in the ordinary way to access +## or change a record component. +## You can use the record.(name) construct for that, +## see and +## . +## +## +## <#/GAPDoc> +## +DeclareAttribute( "RecNames", IsRecord ); + +############################################################################# +## +#F NamesOfComponents( ) +## +## <#GAPDoc Label="NamesOfComponents"> +## +## +## +## +## For a component object comobj, +## returns a list of strings, +## which are the names of components currently bound in comobj. +##

+## For a record comobj, +## returns the result of +## . +## +## +## <#/GAPDoc> +## +DeclareGlobalFunction( "NamesOfComponents" ); + +############################################################################# +## +#V IdentifierLetters . . . . . . . .characters allowed in normal identifiers +## +## This is used to produce warning messages when the XxxxGlobal functions +## are applied to a name which could not be read in by the parser without +## escapes +## + +BIND_GLOBAL( "IdentifierLetters", + Immutable("0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz") ); + +IsSet( IdentifierLetters ); # ensure GAP knows that this is a set + +############################################################################# +## +#F SetNamesForFunctionsInRecord( [, ][, ]) +## +## set the names of functions bound to components of a record. +## +DeclareGlobalFunction("SetNamesForFunctionsInRecord"); diff --git a/lib/record.gi b/lib/record.gi new file mode 100644 index 0000000000..08854084ef --- /dev/null +++ b/lib/record.gi @@ -0,0 +1,311 @@ +# record.g +# + +# returns names of components +InstallMethod( RecNames, + "for a record in internal representation", + [ IsRecord and IsInternalRep ], + REC_NAMES ); + + +InstallGlobalFunction( "NamesOfComponents", +function( obj ) + if IsComponentObjectRep( obj ) then + return REC_NAMES_COMOBJ( obj ); + elif IsRecord( obj ) then + return RecNames( obj ); + else + Error( " must be a component object or a record" ); + fi; +end ); + +############################################################################# +## +#m PrintObj( ) +## +## The record is printed by printing all its components. +## +InstallMethod( PrintObj, + "record", + [ IsRecord ], +## Changed to use sorted component names to make printing nicer to read and +## independent of session (i.e., the ordering in which component names were +## first used). Except for the sorting of components this does the same as +## the former (now removed) kernel function FuncPRINT_PREC_DEFAULT. + function( record ) + local com, i, snam, nam, names, order; + Print("\>\>rec(\n\>\>"); + com := false; + + names := List(RecNames(record)); + order := [1..Length(names)]; + SortParallel(names, order); + + for i in [1..Length(names)] do + nam := names[i]; + if com then + Print("\<\<,\n\>\>"); + else + com := true; + fi; + SET_PRINT_OBJ_INDEX(order[i]); + # easy if nam is integer or valid identifier: + if ForAll(nam, x-> x in IdentifierLetters) and Size(nam) > 0 then + Print(nam, "\< := \>"); + else + # otherwise we use (...) syntax: + snam := String(nam); + Print("("); View(snam); Print(")\< := \>"); + fi; + PrintObj(record.(nam)); + od; + Print(" \<\<\<\<)"); +end); + +############################################################################# +## +#m String( ) . . . . . . . . . . . . . . . . . . . . for a record +## +InstallMethod( String, + "record", + [ IsRecord ], + function( record ) + local str, nam, com; + + str := "rec( "; + com := false; + for nam in Set(RecNames( record )) do + if com then + Append( str, ", " ); + else + com := true; + fi; + Append( str, nam ); + Append( str, " := " ); + if IsStringRep( record.( nam ) ) + or ( IsString( record.( nam ) ) + and not IsEmpty( record.( nam ) ) ) then + Append( str, "\"" ); + Append( str, String( record.(nam) ) ); + Append( str, "\"" ); + else + Append( str, String( record.(nam) ) ); + fi; + od; + Append( str, " )" ); + # should not be necessary if all methods for components are alright + ConvertToStringRep( str ); + return str; +end ); + + +############################################################################# +## +#m ViewObj( ) . . . . . . . . . . . . . . . for a record (default) +## +InstallMethod( ViewObj, + "record", + [ IsRecord ], + function( record ) + local nam, com, i, snam, names, order; + Print("\>\>rec( \>\>"); + com := false; + + names := List(RecNames(record)); + order := [1..Length(names)]; + SortParallel(names, order); + + for i in [1..Length(names)] do + nam := names[i]; + if com then + Print("\<,\< \>\>"); + else + com := true; + fi; + SET_PRINT_OBJ_INDEX(order[i]); + # easy if nam is integer or valid identifier: + if ForAll(nam, x-> x in IdentifierLetters) and Size(nam) > 0 then + Print(nam, " := "); + else + # otherwise we use (...) syntax: + snam := String(nam); + Print("("); View(snam); Print(") := "); + fi; + ViewObj(record.(nam)); + od; + Print(" \<\<\<\<)"); +end); + +InstallMethod( ViewObjStream, + "for a record", + [ IsOutputStream, IsRecord ], +function(stream, record) + local nam, com, i, snam, names, order; + + PrintTo(stream, "\>\>rec( \>\>"); + + com := false; + names := List(RecNames(record)); + order := [1..Length(names)]; + SortParallel(names, order); + + for i in [1..Length(names)] do + nam := names[i]; + if com then + PrintTo(stream, "\<,\< \>\>"); + else + com := true; + fi; + SET_PRINT_OBJ_INDEX(order[i]); + # easy if nam is integer or valid identifier: + if ForAll(nam, x-> x in IdentifierLetters) and Size(nam) > 0 then + PrintTo(stream, nam, " := "); + else + # otherwise we use (...) syntax: + snam := String(nam); + PrintTo(stream, "("); + ViewObjStream(stream, snam); + PrintTo(stream, ") := "); + fi; + ViewObjStream(stream, record.(nam)); + od; + PrintTo(stream, " \<\<\<\<)"); +end); + +InstallMethod( CodeObjStream, + "for a record", + [ IsOutputStream, IsRecord ], +function( stream, record ) + local com, i, snam, nam, names, order; + + PrintTo(stream, "\>\>rec(\n\>\>"); + com := false; + + names := List(RecNames(record)); + order := [1..Length(names)]; + SortParallel(names, order); + + for i in [1..Length(names)] do + nam := names[i]; + if com then + PrintTo(stream, "\<\<,\n\>\>"); + else + com := true; + fi; + SET_PRINT_OBJ_INDEX(order[i]); + # easy if nam is integer or valid identifier: + if ForAll(nam, x-> x in IdentifierLetters) and Size(nam) > 0 then + PrintTo(stream, nam, "\< := \>"); + else + # otherwise we use (...) syntax: + snam := String(nam); + PrintTo(stream, "("); + CodeObjStream(stream, snam); + PrintTo(stream, ")\< := \>"); + fi; + CodeObjStream(stream, record.(nam)); + od; + PrintTo(stream, " \<\<\<\<)"); +end); + +InstallMethod( \=, + "record = record", + IsIdenticalObj, + [ IsRecord, IsRecord ], + EQ_PREC ); + +InstallMethod( \<, + "record < record", + IsIdenticalObj, + [ IsRecord, IsRecord ], + LT_PREC ); + + +# methods to catch error cases + +InstallMethod( \., + "catch error", + true, + [IsObject,IsObject], + 0, +function(obj,nr) + local msg; + msg:=Concatenation("illegal access to record component `obj.", + NameRNam(nr),"'\n", + "of the object . (Objects by default do not have record components.\n", + "The error might be a relic from translated GAP3 code.)"); + Error(msg); +end); + +InstallMethod( IsBound\., + "catch error",true,[IsObject,IsObject],0, +function(obj,nr) + local msg; + msg:=Concatenation("illegal access to record component `IsBound(obj.", + NameRNam(nr),")'\n", + "of the object . (Objects by default do not have record components.\n", + "The error might be a relic from translated GAP3 code.)"); + Error(msg); +end); + +InstallMethod( Unbind\., + "catch error", + true, + [IsObject,IsObject], + 0, +function(obj,nr) + local msg; + msg:=Concatenation("illegal access to record component `Unbind(obj.", + NameRNam(nr),")'\n", + "of the object . (Objects by default do not have record components.\n", + "The error might be a relic from translated GAP3 code.)"); + Error(msg); +end); + +InstallMethod( \.\:\=, + "catch error", + true, + [IsObject,IsObject,IsObject], + 0, +function(obj,nr,elm) +local msg; + msg:=Concatenation("illegal assignement to record component `obj.", + NameRNam(nr),"'\n", + "of the object . (Objects by default cannot have record components.\n", + "The error might be a relic from translated GAP3 code.)"); + Error(msg); +end); + +############################################################################# +## +#F SetNamesForFunctionsInRecord( [, ][, ]) +## +## set the names of functions bound to components of a record. +## +InstallGlobalFunction(SetNamesForFunctionsInRecord, +function(arg) + local recname, next, record, fields, field; + if LENGTH(arg) = 0 or not IS_STRING(arg[1]) then + Error("SetNamesForFunctionsInRecord: you must give a record name"); + fi; + recname := arg[1]; + next := 2; + if LENGTH(arg) >= next and IS_REC(arg[next]) then + record := arg[2]; + next := 3; + else + record := VALUE_GLOBAL(recname); + fi; + if LENGTH(arg) >= next and IS_LIST(arg[next]) then + fields := arg[next]; + else + fields := REC_NAMES(record); + fi; + for field in fields do + if IS_STRING(field) then + if IsFunction(record.(field)) then + SetNameFunction(record.(field), Concatenation(recname,".",field)); + fi; + fi; + od; +end);