3

doブロックを活用して達成したかったモジュールでセットアップを行う必要があります。奇妙なことに、私のdoブロックはヒットしないようです。

さらに奇妙なことに、モジュール コードを fsi にロードすると、ヒットします。これが私の例です:

Main.fs

[<EntryPoint>]
let main args = 
    printfn "%b" TestNamespace.M.x
    0

TestModule.fs

namespace TestNamespace

module M = 
    do
        printfn "In do"
        failwith "Error" // this is line 6

    let x  = true

コンパイルされた実行可能ファイルを実行すると、

>test.exe
 true

例外がスローされなかったのはなぜですか? モジュールを FSI で単独で実行すると、

In do
System.Exception: Error
    at <StartupCode$FSI_0006>.$FSI_0006.main@() in    C:\Projects\Personal2\Playground\fsscripts\fsscripts\TestModule.fs:line 6
Stopped due to error

したがって、例外が発生しました。

逆コンパイルでは、do イニシャライザが別のクラスにロールされることがわかります

namespace \u003CStartupCode\u0024fsscripts\u003E
{
  internal static class \u0024Library1
  {
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    [CompilerGenerated]
    [DebuggerNonUserCode]
    internal static int init\u0040;

    static \u0024Library1()
    {
      ExtraTopLevelOperators.PrintFormatLine<Unit>((PrintfFormat<Unit, TextWriter, Unit, Unit>) new PrintfFormat<Unit, TextWriter, Unit, Unit, Unit>("In do"));
      Operators.FailWith<Unit>("Error");
      bool x = M.x;
    }
  }
}

VS 実際のモジュール コード:

namespace TestNamespace
{
  [CompilationMapping(SourceConstructFlags.Module)]
  public static class M
  {
    public static bool x
    {
      [DebuggerNonUserCode] get
      {
        return true;
      }
    }
  }
}

では、do ブロックが実際に実行されるようにするにはどうすればよいでしょうか。

--

編集、上記の例が単純な定数式としてカウントされるため、監視可能な初期化が生成されない場合、次も機能しないのはなぜですか?

[<EntryPoint>]
let main args = 
    printfn "%d" (TestNamespace.M.x id 1)
    0
namespace TestNamespace

module M = 
    do
        printfn "In do"
        failwith "Error"

    let x f a = f a

これは問題なく出力され1ます。


関数が定数式と見なされるため、Tomasのコメントを再読した後、編集してください。

4

3 に答える 3

2

クラスを使用して、同じパブリック インターフェイスを維持しながら、必要な動作を取得できます。

type M private () = 
    static do
        printfn "In do"
        failwith "Error"

    static member val x  = true
于 2013-09-04T16:57:36.003 に答える