2013-07-22 5 views
16

私はすでにこれについて質問があると思ったが、見つけられなかった。GHC:編集日を挿入

私のプログラムは、コンパイルされた日付をプリントアウトします。それを設定する最も簡単な方法は何ですか?

私はいくつかの可能性を考えることができますが、どれも「簡単」とは言えません。理想的には、私はghc --make Fooを実行し、実行するたびにFooを出力することができます。心に春

様々な非簡単な可能性:

  • はテンプレートHaskellのこちらをご覧ください。 Data.Timeを使って今日の日付を取得する方法を解説します。それを文字列に変換する方法を探します。 (今は私のプログラムでは動作させるためにTHが必要ですが、毎回そのモジュールを再コンパイルするように説得する必要があります。そうでなければ、プログラム全体ではなく決してそのモジュールのコンパイル日を取得しません)

  • システム日付を含む小さなHaskellモジュールを生成するシェルスクリプトを書く。 (今、私はそのシェルスクリプトを使用するのではなく、直接私のプログラムをコンパイルする必要があります。また、Windows上でシェルスクリプトが望まれるべきくらいの葉!)

  • 座って含む小さなHaskellのモジュールを生成し、いくつかのHaskellのコードを書きます日付。 (以前のアイデアよりも移植性が高いですが、余分なビルドステップや印刷された日付が間違っています)

  • Cabalでこれを行うにはいくつかの方法があるかもしれませんが、本当にこの小さなプログラムをパッケージ化したいのですか?日付施設を取得するには?

もっと簡単な提案はありますか?

+1

エイリアス '' GHC -DNOW = "\" 'date' \ "に相当何か"' '(つまりは、Windowsシェルのためにどのように見えるか全く分からない)にGHCし、あなたのモジュールの使用' {中 - #LANGUAGE CPP # - } 'と' now = NOW'を返します。醜いハックは、より多くの作業を必要とする、よりクリーンな選択肢にあなたを追いやるだけの醜いかもしれません。 –

+0

@DanielFischerはどうやらWindowsのシェルは、コマンドの出力から変数を設定するための任意の機能を欠いています。代わりに、stdinからテキストを読み込む 'SET/P VAR ='に関するハッキングを使用する必要があります。コマンド出力をファイルにパイプしてパイプして戻すと、あなたが望む効果を得ることができます...しかし、イエス! > _ < – MathematicalOrchid

+0

ああ、うわー。 PowerShellにもその機能はありませんか? –

答えて

26

テンプレートHaskellの使用は比較的簡単です。あなただけに必要 :テンプレートHaskellのモナド内

  1. 実行IOアクション:内全体の表現を入れ

    stringE :: String -> ExpQ 
    
  2. runIO :: IO a -> Exp a 
    
  3. は、その後で文字列リテラルを作成します準クオーツ。あなたはそれが再コンパイルされていることを確認するために他のすべてのモジュールをインポートモジュールに関連するフラグメントを置いてもよい

    {-# LANGUAGE TemplateHaskell #-} 
    import Language.Haskell.TH 
    import Data.Time 
    
    main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime)) 
    

    $(...) 
    

このプログラムは、そのコンパイルの時間を表示します。

また、現在のバージョン情報をバージョン管理システムから取得してください。参照:TemplateHaskell and IO

+1

どのような素晴らしい最初の答え!スタックオーバーフローへようこそ! – AndrewC

+0

これはちょうど最も清潔な解決策であるようです。バージョン文字列はいくつかの異なる場所で使用されているので、このコードを別のモジュールに配置します。私が予期する唯一の問題は、毎回バージョン・モジュールを再コンパイルすることです。たぶん私はTHを使って、毎回何かソースファイルに「触れる」ことができましたか? – MathematicalOrchid

+0

MathematicalOrchid:私はこのモジュールがインポート他のすべてのトップレベルのモジュールことが示唆された理由です。あるいは、このコードを 'main'モジュールに入れることもできます。その後、常に再コンパイルされます。他の解決策も同じ問題を抱えており、ソースファイルに「触れようとする」ことは、一部の人にとってはより厄介な解決策に思えるかもしれません。当然の –

7

プリプロセッサが親切(ちょうどCのように)__DATE____TIME__マクロを定義するので、この作品:

{-# LANGUAGE CPP #-} 
main = putStrLn (__DATE__ ++ " " ++ __TIME__) 

これはおそらく、テンプレートハスケルのミハエルの提案よりも簡単ですが、あなたを聞かせていません日付の形式を選択します。

+0

リテラルとしてプログラムで日付を得れば、あなたが好きしかし、ことをマングルすることができます。 – muhmuhten

+0

私はこれがケースかもしれません期待していた - しかし私は、ドキュメントでそれの一切の言及を見つけることができませんでした。また、 '' __DATE __ "'の記述は機能しませんが、それ自身の '__DATE__'はなぜですか? – MathematicalOrchid

+0

GHCはCプリプロセッサを呼び出しているだけなので、あらかじめ定義されているマクロがあることがわかります。唯一有益なものは '__DATE__'、' __TIME__'、 '__FILE__'(ソースファイル名)、' __LINE__'(ソースファイルの行番号)です。最後の2つはソースの場所を含むエラーマクロを定義するのに便利です。 'は「__DATE __」'動作しない理由について としては、プリプロセッサは、文字列リテラルの内部のマクロを展開しません。また、 '__DATE__'自体はすでに文字列リテラルに展開されています。 –

関連する問題