diff --git a/pkg/JuliaInterface/gap/JuliaInterface.gd b/pkg/JuliaInterface/gap/JuliaInterface.gd
index 517bfa206..64a759e42 100644
--- a/pkg/JuliaInterface/gap/JuliaInterface.gd
+++ b/pkg/JuliaInterface/gap/JuliaInterface.gd
@@ -109,8 +109,7 @@
#! However not every object living on the Julia side is in this filter.
#! For example Julia booleans and small Int values are directly
#! translated to GAP booleans and small integers, while for Julia functions
-#! and wrappers dedicated wrappers are used for improved efficiency
-#! respectively additional features.
+#! dedicated wrappers are used to improve efficiency and add features.
#! @BeginExampleSession
#! gap> JuliaEvalString( "x = 4" );;
#! gap> Julia.x;
@@ -119,8 +118,6 @@
#! false
#! gap> IsJuliaObject( Julia.sqrt );
#! false
-#! gap> IsJuliaObject( Julia.Main );
-#! false
#! @EndExampleSession
DeclareCategory( "IsJuliaObject", IsObject );
@@ -138,14 +135,10 @@ BindGlobal("TheTypeJuliaObject", NewType( JuliaObjectFamily, IsJuliaObject ));
#! This admits implementing high-level wrapper objects
#! for &Julia; objects that behave just like the &Julia; objects
#! when used as arguments in calls to &Julia; functions.
-#!
#!
#! Objects in
#! should not be in the filter
#! .
-#!
-#! For example, any Julia modules such as Julia.Base are
-#! in the filter .
DeclareCategory( "IsJuliaWrapper", IsObject );
#! @Arguments obj
@@ -153,18 +146,6 @@ DeclareCategory( "IsJuliaWrapper", IsObject );
#! is an attribute for ⪆ objects in the filter
#! .
#! The value must be a &Julia; object.
-#! @BeginExampleSession
-#! gap> Julia;
-#!
-#! gap> IsJuliaObject( Julia );
-#! false
-#! gap> IsJuliaWrapper( Julia );
-#! true
-#! gap> ptr:= JuliaPointer( Julia );
-#!
-#! gap> IsJuliaObject( ptr );
-#! true
-#! @EndExampleSession
DeclareAttribute( "JuliaPointer", IsJuliaWrapper );
#! @Arguments obj
@@ -181,10 +162,10 @@ DeclareAttribute( "JuliaPointer", IsJuliaWrapper );
#! gap> Julia.GAP.julia_to_gap;
#!
#! @EndExampleSession
-DeclareCategory( "IsJuliaModule", IsJuliaWrapper and IsRecord );
+DeclareCategory( "IsJuliaModule", IsJuliaObject and IsRecord );
BindGlobal( "TheFamilyOfJuliaModules", NewFamily( "TheFamilyOfJuliaModules" ) );
-BindGlobal( "TheTypeOfJuliaModules", NewType( TheFamilyOfJuliaModules, IsJuliaModule and IsAttributeStoringRep ) );
+BindGlobal( "TheTypeOfJuliaModules", NewType( TheFamilyOfJuliaModules, IsJuliaModule and HasName ) );
#! @Section Creating &Julia; objects
@@ -271,9 +252,7 @@ DeclareGlobalVariable( "Julia" );
#! @BeginExampleSession
#! gap> JuliaTypeInfo( Julia.GAP );
#! "Module"
-#! gap> JuliaTypeInfo( JuliaPointer( Julia.GAP ) );
-#! "Module"
-#! gap> JuliaTypeInfo( JuliaEvalString( "sqrt(2)" ) );
+#! gap> JuliaTypeInfo( Julia.sqrt(2) );
#! "Float64"
#! gap> JuliaTypeInfo( 1 );
#! "Int64"
diff --git a/pkg/JuliaInterface/gap/JuliaInterface.gi b/pkg/JuliaInterface/gap/JuliaInterface.gi
index d28a5f3c2..a58880157 100644
--- a/pkg/JuliaInterface/gap/JuliaInterface.gi
+++ b/pkg/JuliaInterface/gap/JuliaInterface.gi
@@ -4,22 +4,9 @@
# Implementations
#
-BindGlobal( "_JULIA_MODULE_TYPE", _JuliaGetGlobalVariableByModule( "Module", "Core" ) );
BindGlobal( "_JULIA_FUNCTION_TYPE", _JuliaGetGlobalVariableByModule( "Function", "Core" ) );
BindGlobal( "_JULIA_ISA", _WrapJuliaFunction( _JuliaGetGlobalVariableByModule( "isa", "Core" ) ) );
-
-BindGlobal( "_WrapJuliaModule",
- function( name, julia_pointer )
- local str;
-
- str:= Concatenation( "" );
-
- return ObjectifyWithAttributes( rec( storage := rec( ) ),
- TheTypeOfJuliaModules,
- Name, str,
- String, str,
- JuliaPointer, julia_pointer );
-end );
+BindGlobal( "_JULIA_GAP", _JuliaGetGapModule() );
InstallMethod( ViewString,
[ "IsFunction and IsInternalRep and HasNameFunction" ],
@@ -31,59 +18,78 @@ InstallMethod( ViewString,
TryNextMethod();
end );
+InstallMethod( ViewString,
+ [ "IsJuliaModule" ],
+ function( module )
+ return Concatenation( "" );
+ end );
+
+InstallMethod( Name,
+ [ "IsJuliaModule" ],
+ function( module )
+ return Concatenation( "" );
+ end );
+
InstallMethod( \.,
- [ "IsJuliaModule", "IsPosInt" ],
+ [ "IsJuliaModule", "IsPosInt and IsSmallIntRep" ],
function( module, rnum )
local rnam, var;
- if IsBound\.( module!.storage, rnum ) then
- return \.(module!.storage, rnum );
- fi;
-
rnam := NameRNam( rnum );
- var := _JuliaGetGlobalVariableByModule( rnam, JuliaPointer( module ) );
+ if IsIdenticalObj(module, Julia) and rnam = "GAP" then
+ ## Ensure that the Julia module GAP is always accessible as Julia.GAP,
+ ## even while it is still being initialized, and also if it not actually
+ ## exported to the Julia Main module
+ return _JULIA_GAP;
+ fi;
+
+ var := _JuliaGetGlobalVariableByModule( rnam, module );
if var = fail then
Error( rnam, " is not bound in Julia" );
fi;
if _JULIA_ISA( var, _JULIA_FUNCTION_TYPE ) then
var := _WrapJuliaFunction( var );
- elif _JULIA_ISA( var, _JULIA_MODULE_TYPE ) then
- var := _WrapJuliaModule( rnam, var );
- \.\:\=( module!.storage, rnum, var );
fi;
return var;
end );
InstallMethod( \.\:\=,
- [ "IsJuliaModule", "IsPosInt", "IsObject" ],
+ [ "IsJuliaModule", "IsPosInt and IsSmallIntRep", "IsObject" ],
function( module, rnum, obj )
Julia.GAP._setglobal( module, JuliaSymbol( NameRNam( rnum ) ), obj );
end );
InstallMethod( IsBound\.,
- [ "IsJuliaModule", "IsPosInt" ],
+ [ "IsJuliaModule", "IsPosInt and IsSmallIntRep" ],
function( module, rnum )
- if IsBound\.( module!.storage, rnum ) then
+ local rnam;
+
+ rnam := NameRNam( rnum );
+ if IsIdenticalObj(module, Julia) and rnam = "GAP" then
+ ## Ensure that the Julia module GAP is always accessible as Julia.GAP,
+ ## even while it is still being initialized, and also if it not actually
+ ## exported to the Julia Main module
return true;
fi;
- return fail <> _JuliaGetGlobalVariableByModule( NameRNam( rnum ), JuliaPointer( module ) );
+
+ return fail <> _JuliaGetGlobalVariableByModule( rnam, module );
end );
InstallMethod( Unbind\.,
- [ "IsJuliaModule", "IsPosInt" ],
+ [ "IsJuliaModule", "IsPosInt and IsSmallIntRep" ],
function( module, rnum )
Error( "cannot unbind Julia variables" );
end );
InstallMethod(RecNames, [ "IsJuliaModule" ],
function( obj )
- return JuliaToGAP( IsList, Julia.GAP.get_symbols_in_module( JuliaPointer( obj ) ), true );
+ return JuliaToGAP( IsList, Julia.GAP.get_symbols_in_module( obj ), true );
end);
-InstallValue( Julia, _WrapJuliaModule( "Main", _JuliaGetGlobalVariableByModule( "Main", "Main" ) ) );
+InstallValue( Julia, _JuliaGetGlobalVariableByModule( "Main", "Main" ) );
InstallGlobalFunction( "JuliaIncludeFile",
function( filename, module_name... )
diff --git a/pkg/JuliaInterface/read.g b/pkg/JuliaInterface/read.g
index 06b4ed4d3..c73e00b4c 100644
--- a/pkg/JuliaInterface/read.g
+++ b/pkg/JuliaInterface/read.g
@@ -5,11 +5,6 @@
#
ReadPackage( "JuliaInterface", "gap/JuliaInterface.gi");
-## Ensure that the Julia module GAP is always accessible as Julia.GAP,
-## even while it is still being initialized, and also if it not actually
-## exported to the Julia Main module
-Julia!.storage.GAP := _WrapJuliaModule( "GAP", _JuliaGetGapModule() );
-
ReadPackage( "JuliaInterface", "gap/adapter.gi");
ReadPackage( "JuliaInterface", "gap/calls.gi");
ReadPackage( "JuliaInterface", "gap/convert.gi");
diff --git a/pkg/JuliaInterface/src/JuliaInterface.c b/pkg/JuliaInterface/src/JuliaInterface.c
index a39223c6c..22d163464 100644
--- a/pkg/JuliaInterface/src/JuliaInterface.c
+++ b/pkg/JuliaInterface/src/JuliaInterface.c
@@ -21,6 +21,7 @@ static jl_datatype_t * JULIA_GAPFFE_type;
static jl_datatype_t * gap_datatype_mptr;
+static Obj TheTypeOfJuliaModules;
static Obj TheTypeJuliaObject;
static UInt T_JULIA_OBJ;
@@ -114,7 +115,10 @@ jl_value_t * GET_JULIA_OBJ(Obj o)
static Obj JuliaObjectTypeFunc(Obj o)
{
- return TheTypeJuliaObject;
+ if (jl_typeis(GET_JULIA_OBJ(o), jl_module_type))
+ return TheTypeOfJuliaModules;
+ else
+ return TheTypeJuliaObject;
}
Obj NewJuliaObj(jl_value_t * v)
@@ -282,6 +286,7 @@ static Int InitKernel(StructInitInfo * module)
// init filters and functions
InitHdlrFuncsFromTable(GVarFuncs);
+ InitCopyGVar("TheTypeOfJuliaModules", &TheTypeOfJuliaModules);
InitCopyGVar("TheTypeJuliaObject", &TheTypeJuliaObject);
T_JULIA_OBJ = RegisterPackageTNUM("JuliaObject", JuliaObjectTypeFunc);
diff --git a/pkg/JuliaInterface/tst/utils.tst b/pkg/JuliaInterface/tst/utils.tst
index 3df6c57e1..734a06ca6 100644
--- a/pkg/JuliaInterface/tst/utils.tst
+++ b/pkg/JuliaInterface/tst/utils.tst
@@ -56,7 +56,7 @@ gap> _JuliaGetGlobalVariableByModule("Base","sqrt");
Error, sqrt is not a module
gap> _JuliaGetGlobalVariableByModule("sqrt","Base");
-gap> _JuliaGetGlobalVariableByModule("sqrt", JuliaPointer(Julia.Base));
+gap> _JuliaGetGlobalVariableByModule("sqrt", Julia.Base);
##
@@ -85,5 +85,15 @@ gap> path:= GetJuliaScratchspace( "test_scratch" );;
gap> IsDirectoryPath( path );
true
+# Julia modules should not get cached, see #1044
+gap> JuliaEvalString("module foo x = 1 end");
+
+gap> Julia.foo.x;
+1
+gap> JuliaEvalString("module foo x = 2 end");
+
+gap> Julia.foo.x;
+2
+
##
gap> STOP_TEST( "utils.tst" );