From 361953a69a94dc1f529790e3744bff3cae538c8b Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Tue, 7 Mar 2023 18:08:39 +0100 Subject: [PATCH] use early methods for tag based operations This is a follow-up of #5344, according to a comment in #4398. --- lib/methsel.g | 114 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 93 insertions(+), 21 deletions(-) diff --git a/lib/methsel.g b/lib/methsel.g index 487eda2457..d2ae5fe669 100644 --- a/lib/methsel.g +++ b/lib/methsel.g @@ -135,9 +135,10 @@ end ); ##

## Installing methods with for a tag based ## operation is possible. -## (Installing such methods with the same requirements as the ones for the -## tag based methods is not recommended, because this may lead to unwanted -## effects.) +## However, installing such methods with the same requirements as the ones +## for the tag based methods will have no effect because the handling of +## tag based methods gets installed with +## and thus has higher priority. ## ## ## <#/GAPDoc> @@ -166,25 +167,96 @@ BIND_GLOBAL( "NewTagBasedOperation", ADD_OBJ_MAP( _METHODS_TAG_BASED_DEFAULTS, oper, requirements ); # install the method for 'oper' that uses the tag handling - InstallMethod( oper, - "tag based method", - requirements, - function( requ... ) - local method; - - method:= FIND_OBJ_MAP( methods, requ[1], fail ); - if method = fail then - # Take the default method if there is one. - method:= FIND_OBJ_MAP( methods, IS_OBJECT, fail ); - fi; - if method = fail then - # Calling 'TryNextMethod' would lead to a less useful error message, - # and perhaps cause real trouble. - Error( "no default installed for tag based operation " ); - fi; + if LENGTH( requirements ) = 1 then + InstallEarlyMethod( oper, + function( req1 ) + local method; + + if not requirements[1]( req1 ) then + TryNextMethod(); + fi; + + method:= FIND_OBJ_MAP( methods, req1, fail ); + if method = fail then + # Take the default method if there is one. + method:= FIND_OBJ_MAP( methods, IS_OBJECT, fail ); + fi; + if method = fail then + Error( "no default installed for tag based operation " ); + fi; + + return method( req1 ); + end ); + elif LENGTH( requirements ) = 2 then + InstallEarlyMethod( oper, + function( req1, req2 ) + local method; + + if not ( requirements[1]( req1 ) and + requirements[2]( req2 ) ) then + TryNextMethod(); + fi; + + method:= FIND_OBJ_MAP( methods, req1, fail ); + if method = fail then + # Take the default method if there is one. + method:= FIND_OBJ_MAP( methods, IS_OBJECT, fail ); + fi; + if method = fail then + Error( "no default installed for tag based operation " ); + fi; + + return method( req1, req2 ); + end ); + elif LENGTH( requirements ) = 3 then + InstallEarlyMethod( oper, + function( req1, req2, req3 ) + local method; - return CallFuncList( method, requ ); - end ); + if not ( requirements[1]( req1 ) and + requirements[2]( req2 ) and + requirements[3]( req3 ) ) then + TryNextMethod(); + fi; + + method:= FIND_OBJ_MAP( methods, req1, fail ); + if method = fail then + # Take the default method if there is one. + method:= FIND_OBJ_MAP( methods, IS_OBJECT, fail ); + fi; + if method = fail then + Error( "no default installed for tag based operation " ); + fi; + + return method( req1, req2, req3 ); + end ); + elif LENGTH( requirements ) = 4 then + InstallEarlyMethod( oper, + function( req1, req2, req3, req4 ) + local method; + + if not ( requirements[1]( req1 ) and + requirements[2]( req2 ) and + requirements[3]( req3 ) and + requirements[4]( req4 ) ) then + TryNextMethod(); + fi; + + method:= FIND_OBJ_MAP( methods, req1, fail ); + if method = fail then + # Take the default method if there is one. + method:= FIND_OBJ_MAP( methods, IS_OBJECT, fail ); + fi; + if method = fail then + Error( "no default installed for tag based operation " ); + fi; + + return method( req1, req2, req3, req4 ); + end ); + else + Error( "tag based operations for ", LENGTH( requirements ), + " arguments are currently not supported" ); + fi; return oper; end );