challenge メソッド名一覧の表示

リフレクション系のお題の続編です。

「ある与えられたオブジェクトtargetのメソッドのうち、 "test_"で始まるものをすべて呼びだす」というコードを書いてください。 引数に関しては都合のいいように仮定して構いません(全部0個、など)。

メソッドという概念がない言語の場合は、 「複数の関数への参照を持っているようなオブジェクト(たとえばパッケージとかモジュールとか)から"test_"で始まる関数をすべて呼び出す」と読み替えても構いません。

Posted feedbacks - Haskell

コンパイルには -package ghc が必要。
引数で指定されたモジュールが export し、且つ test_ で始まる全部の IO モナドを実行する。
型は IO () でなければならず、そうでないものが存在したら実行時エラーになる。
GHC 6.6.1 以外の GHC を使う場合は ghcLibDir の値を訂正する事。

% ghc --make Main -package ghc
% ./Main Test
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import qualified GHC
import qualified DynFlags
import qualified Name
import Data.List
import System

{-
例: Test.hs

module Test where

test_foo :: IO ()
test_foo = putStrLn "called test_foo"

test_bar :: IO ()
test_bar = putStrLn "called test_bar"

% ghc --make Test -package-name test
% ar cqs libHSTest.a Test.o
% ld -r --whole-archive -o HSTest.o libHSTest.a (MacOS X 以外の場合)
% ld -r -all_load -o HSTest.o libHSTest.a       (MacOS X の場合)
-}

ghcLibDir :: String
ghcLibDir = "/usr/local/lib/ghc-6.6.1" -- % ghc --print-libdir

main = GHC.defaultErrorHandler DynFlags.defaultDynFlags $
       do [modName] <- getArgs
          session <- GHC.newSession GHC.Interactive (Just ghcLibDir)
          f0      <- GHC.getSessionDynFlags session
          GHC.setSessionDynFlags session f0 { GHC.hscTarget = GHC.HscInterpreted }

          t  <- GHC.guessTarget modName Nothing
          GHC.addTarget session t
          f  <- GHC.getSessionDynFlags session
          sf <- GHC.defaultCleanupHandler f (GHC.load session GHC.LoadAllTargets)
          case sf of
            GHC.Failed  
                -> fail "Failed to load the module!"
            GHC.Succeeded
                -> do self <- GHC.findModule session (GHC.mkModuleName modName) Nothing
                      runNullaryIOMonads session self (any (== "test_") . inits)

runNullaryIOMonads :: GHC.Session -> GHC.Module -> (String -> Bool) -> IO ()
runNullaryIOMonads session self f
    = do Just modInfo <- GHC.getModuleInfo session self
         
         let allFuncs      = map Name.getOccString $ GHC.modInfoExports modInfo
             selectedFuncs = filter f allFuncs

         GHC.setContext session [self] []
         mapM_ run selectedFuncs
    where
      run :: String -> IO ()
      run fName
          = GHC.runStmt session (fName ++ " :: IO ()")
            >> return ()

Index

Feed

Other

Link

Pathtraq

loading...