OCaml Format 모듈을 F #으로 변환하고 OCaml Pervasives at_exit을 사용하여 문제를 다시 추적했습니다. OCaml을 F #로 변환 : F # Equivelent of Pervasives at_exit
val at_exit : (unit -> unit) -> unit
는 프로그램 종료시 호출 될 주어진 함수를 등록합니다.
at_exit
으로 등록 된 함수는 프로그램이 exit를 실행하거나 종료 될 때 정상적으로 또는 캐치되지 않는 예외로 인해 호출됩니다. 이 함수는 "최후의 선착순"순서로 호출됩니다. 가장 최근에
at_exit
을 추가 한 함수가 먼저 호출됩니다.
변환 과정에서 필자는 컴파일러가 필요하지 않은 것으로 플래그를 지정하지 않았기 때문에 코드에서 이벤트를 예상하지 못했습니다.
at_exit
에 대해 FSharp.PowerPack.Compatibility.PervasivesModule
을 확인했으며 VS 개체 브라우저를 사용하여 찾을 수 없습니다. OCaml의 코드의 디버그 세션 동안 그것의 사용에서 찾고 또한 val print_flush : (unit -> unit)
:
은 내가 OCaml의 라인 print_flush 서명
at_exit print_flush
입니다 how to run code "at_exit"? 및 How do I write an exit handler for an F# application?
을 찾았어요 , at_exit
은 초기화가 끝날 때와 모듈 호출을 사용할 때마다 호출됩니다.
제안 방법에 대한 의견이 있습니다. 이것은 F #에서의 첫 번째 행사가 될 것입니다.
편집 여기
내가 문제에 도움이 되거해야하는 형식 모듈에 대해 배운 내용 중 일부입니다.
형식 모듈은 int, bool, string과 같은 간단한 OCaml 값의 기본 예쁜 프린터 명령에 대한 함수 라이브러리입니다. 형식 모듈은 print_string
과 같은 명령을 가지고 있지만, 다음 행을 경계 상자에 넣고, 왼쪽 및 오른쪽 여백의 새로운 세트를 생각하는 명령도 있습니다. 같은 open_box
및 print_string
등
print_string "Hello"
또는
open_box 0; print_string "<<";
open_box 0; print_string "p \/ q ==> r"; close_box();
print_string ">>"; close_box()
명령은 명령을 해석 루프에 의해 처리 된 후 현재 행 또는 사전에 인쇄 시들어 결정 : 그래서 하나를 쓸 수 다음 줄. 명령은 대기열에 보관되며 왼쪽 및 오른쪽 여백과 같은 변경 가능한 값을 저장하는 상태 레코드가 있습니다.
OCaml 코드 작업에 대한 테스트 케이스 디버깅에서 모듈의 초기화가 끝난 후 첫 번째 호출이 Format 모듈의 모든 함수에 적용되기 전에 대기열과 상태를 준비해야합니다. 형식 모듈에 대한 최초 호출에 대해 마지막으로 일치하는 프레임이 제거 된 at_exit
에 대한 메커니즘을 사용하여 대기열과 상태가 정리되고 다음 명령 세트에 대해 다시 채워 지므로 at_exit
에 대한 호출이 실행됩니다 나머지 명령을 큐에 넣고 큐와 상태를 다시 초기화합니다.
따라서 print_flush
에 대한 호출 순서는 매우 중요하며 OCaml 설명서의 내용보다 많은 것으로 보입니다. 그것을 테스트
module Pervasives =
open System
open System.Threading
//
let mutable private exitFunctions : (unit -> unit) list = List.empty
//
let mutable private exitFunctionsExecutedFlag = 0
//
let private tryExecuteExitFunctions _ =
if Interlocked.CompareExchange (&exitFunctionsExecutedFlag, 1, 0) = 0 then
// Run the exit functions in last-in-first-out order.
exitFunctions
|> List.iter (fun f -> f())
// Register handlers for events which fire when the process exits cleanly
// or due to an exception being thrown.
do
AppDomain.CurrentDomain.ProcessExit.Add tryExecuteExitFunctions
AppDomain.CurrentDomain.UnhandledException.Add tryExecuteExitFunctions
//
let at_exit f =
// TODO : This function should be re-written using atomic operations
// for thread-safety!
exitFunctions <- f :: exitFunctions
그리고 몇 가지 코드를 :
당신은 당신의 main 메소드 내부 –
또 다른 아이디어를'finally'를 둘 수 있었다 - 하나에 개최 형식의 인스턴스를 만들고 소멸자가 프로그램을 종료 할 때 호출하도록하십시오. –