[Haskell-cafe] mueval leaving behind tmp files

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Wed Apr 4 15:15:33 CEST 2012


Johannes Waldmann wrote:
> The following program prints   Right ("test","Bool","True")
> as it should, but it leaves behind in /tmp 
> two files (name is a long string of digits)
> and an empty directory (name is ghcNNNNN_N).

I have a partial solutions for this; see the attached patch for hint.
It cleans up the numbered files, which are generated for "phantom
modules". There are two phantom modules generated -- one that defines
a _show function for hint's internal use, and one that provides a
bunch of pre-imported modules for mueval. The latter will not be
generated if the 'modules' mueval option is set to Nothing.

For some reason, cleaning the ghc* directory fails if the executed
code fails (for example, using 'test = undefined' in Johannes' code).
Can anybody explain why? The `finally` handler is run, and the
phantom module files are actually deleted.

> ... and it deletes the input file (/tmp/Main.hs).

That appears to be an undocumented mueval feature. It's not a good one,
I think.

> That's not nice. Ideally, I would want to read input
> from a String (instead of the file), and not write to disk at all.

I suppose that ghc's interface does not support this, but I have
not checked.

Best regards,

Bertram
-------------- next part --------------
1 patch for repository http://darcsden.com/jcpetruzza/hint:

Wed Apr  4 14:59:33 CEST 2012  Bertram Felgenhauer <int-e at gmx.de>
  * clean temporary files in runInterpreterT(withArgs)

New patches:

[clean temporary files in runInterpreterT(withArgs)
Bertram Felgenhauer <int-e at gmx.de>**20120404125933
 Ignore-this: ff9abed505645f81131a57182d371861
] hunk ./src/Hint/Context.hs 10
 
       PhantomModule(..), ModuleText,
       addPhantomModule, removePhantomModule, getPhantomModules,
+      cleanPhantomModules,
 
       allModulesInContext, onAnEmptyContext,
 
hunk ./src/Hint/Context.hs 254
        --
        onState (\s ->s{qual_imports = quals})
 
--- | All imported modules are cleared from the context, and
---   loaded modules are unloaded. It is similar to a @:load@ in
---   GHCi, but observe that not even the Prelude will be in
---   context after a reset.
-reset :: MonadInterpreter m => m ()
-reset =
+-- | 'cleanPhantomModules' works like 'reset', but skips the
+--   loading of the support module that installs '_show'. Its purpose
+--   is to clean up all temporary files generated for phantom modules.
+cleanPhantomModules :: MonadInterpreter m => m ()
+cleanPhantomModules =
     do -- Remove all modules from context
        runGhc2 Compat.setContext [] []
        --
hunk ./src/Hint/Context.hs 280
                         import_qual_hack_mod = Nothing,
                         qual_imports         = []})
        liftIO $ mapM_ (removeFile . pm_file) (old_active ++ old_zombie)
-       --
-       -- Now, install a support module
-       installSupportModule
+
+-- | All imported modules are cleared from the context, and
+--   loaded modules are unloaded. It is similar to a @:load@ in
+--   GHCi, but observe that not even the Prelude will be in
+--   context after a reset.
+reset :: MonadInterpreter m => m ()
+reset = do -- clean up context
+           cleanPhantomModules
+           --
+           -- Now, install a support module
+           installSupportModule
 
 -- Load a phantom module with all the symbols from the prelude we need
 installSupportModule :: MonadInterpreter m => m ()
hunk ./src/Hint/InterpreterT.hs 164
   ifInterpreterNotRunning $
     do s <- newInterpreterSession `catch` rethrowGhcException
        -- SH.protectHandlers $ execute s (initialize args >> action)
-       execute s (initialize args >> action)
+       execute s (initialize args >> action `finally` cleanSession)
     where rethrowGhcException   = throw . GhcException . showGhcEx
 #if __GLASGOW_HASKELL__ < 610
           newInterpreterSession =  do s <- liftIO $
hunk ./src/Hint/InterpreterT.hs 170
                                              Compat.newSession GHC.Paths.libdir
                                       newSessionData s
+          cleanSession = cleanPhantomModules -- clean ghc session, too?
 #else
           -- GHC >= 610
           newInterpreterSession = newSessionData ()
hunk ./src/Hint/InterpreterT.hs 174
+          cleanSession =
+               do cleanPhantomModules
+                  runGhc $ do dflags <- GHC.getSessionDynFlags
+                              GHC.defaultCleanupHandler dflags (return ())
 #endif
 
 {-# NOINLINE uniqueToken #-}

Context:

[bump to version 0.3.3.4
jcpetruzza at gmail.com**20111220224039
 Ignore-this: 23d55959cc61ebbd20f5ebd4f2a86bd9
] 
[authors file updated
jcpetruzza at gmail.com**20111220224018
 Ignore-this: e4f66f8324ac599e74e665a1e2292c12
] 
[compile with ghc 7.4 snapshot
Mark Wright <gienah at gentoo.org>**20111220114907
 Ignore-this: cc43ccb4e716324ccfbfbb1d38f2668c
] 
[TAG 0.3.3.3
jcpetruzza at gmail.com**20111104192050
 Ignore-this: f2f8da08437fa759cb41f0f4e35a11a
] 
Patch bundle hash:
7ee3dacd0f2fd8713494534c000231ed2e85b783


More information about the Haskell-Cafe mailing list