GHC APIでは、起動前にいくつかの初期化が必要です。具体的には、parseStaticFlags
は一度だけ呼び出すことができます。HaskellのunsafePerformIOによるグローバル変数
私はいくつかのGHC APIメソッドを実行するためにrunGhc :: MaybeFilePath :: Ghc a -> IO a
を何度も呼び出すことができる関数を持っています。ただし、その初期化の一部は、関数が呼び出されたときに初めて発生する必要があります。
私はrunGhc
を呼び出すモナドアクションで私たちは、しかし
(init,flags) <- readMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
を持つことができるように
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])
のようなグローバル変数ものを作成することが可能であることをYi
ソースから覚えているようです私はそれがどのように行われたかを正確に思い出すことはできません。このコードはGhcMonad
をラップするモナドの関数runMonad
にあります。私はよくunsafePerformIO
を使用して純粋なまたは機能的ではないが、(当時)これは実際の結果を達成するための最良の方法だったことを認識しています。
は、[編集:作業溶液:
{-# NOINLINE ghcInitialised #-}
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])
runGhc
を呼び出すモナドアクションで我々は
(init,flags) <- takeMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
ああ、私は 'MVar'ではなく' IORef'を使っていたはずです。 – vivian
いいえ、MVarが良いです。実際にはMVarは並行処理でも機能するため、より優れています。 – augustss
'MVar'を使用したときに私のプログラムがハングしていました。 – vivian