{ }
rule translate = parse
| "current_directory" { print_string (Sys.getcwd ()) }
| _ as c { print_char c }
| eof { exit 0 }
{
let main () =
let lexbuf = Lexing.from_channel stdin in
while true do
translate lexbuf
done
let _ = Printexc.print main ()
}
Can someone please explain me how the main function works? I have understood the regexp part, and am able to get a sense of the main function, but not the exact meaning.
The main function looks like this:
let main () =
let lexbuf = Lexing.from_channel stdin in
while true do
translate lexbuf
done
It creates a lexbuf using stdin as its source, then calls translate repeatedly using this lexbuf. The type of translate is Lexing.lexbuf -> unit. It expects a lexbuf, looks for one token, and executes the associated rule. You define a rule for eof that causes the program to exit, which terminates the while.
The next line actually runs the main function:
let _ = Printexc.print main ()
What this does is call main, passing it (). If an exception is raised during execution, Printexc.print will print out a description of it. Since no exception is raised in the test, eventually you reach the end of file and the eof rule causes the program to exit.
Related
I am trying to read a log file and match some string in each line. Right now, If the line doesn't have any matching string the program exits with an error because the length of res == 0 and stops reading lines after. I want the program to continue to read the next lines even if regex doesn't match in between.
func analyzeLog(s string) (*time.Time, bool) {
res := regexp.MustCompile(LogLineRegex).FindAllStringSubmatch(s, 1)
if len(res) == 0 {
panic("Not Matching")
}
timeString := res[0][1]
description := res[0][2]
t, err := time.Parse(TimeFormat, timeString)
check(err)
return &t, strings.HasPrefix(description, ErrorTerm)
}
func readLogFile(offset int64) (*ErrorMetrics, int64, error) {
...
...
...
for {
line, _, err := r.ReadLine()
if err == io.EOF {
break
} else if err != nil {
panic(err)
}
t, hasError := analyzeLog(string(line))
if hasError {
em.Count += 1
}
}
...
...
...
}
What would be a good way to move ahead?
Don’t panic() and your program won’t exit.
You can use log.Println(err) for example and from there handle more precisely when do you want to log and when do you want to panic().
“ The panic built-in function stops normal execution of the current goroutine. When a function F calls panic, normal execution of F stops immediately. Any functions whose execution was deferred by F are run in the usual way, and then F returns to its caller. To the caller G, the invocation of F then behaves like a call to panic, terminating G's execution and running any deferred functions. This continues until all functions in the executing goroutine have stopped, in reverse order. At that point, the program is terminated with a non-zero exit code. This termination sequence is called panicking and can be controlled by the built-in function recover.”
You can also recover from the error but that would mean you have to recover and start reading your logs from the next line and I don’t think its what you want. You just use panic() in the context where you don’t want panic. Use panic where further execution is not possible.
Hope this helps.
I have returned the nil value if the returning array length is zero. Now, the function looks like below.
func analyzeLog(s string) (*time.Time, bool) {
res := regexp.MustCompile(LogLineRegex).FindAllStringSubmatch(s, 1)
if len(res) == 0 {
return nil, false
}
timeString := res[0][1]
description := res[0][2]
t, err := time.Parse(TimeFormat, timeString)
check(err)
return &t, strings.HasPrefix(description, ErrorTerm)
}
I'm making a simple space invaders in Ocaml using the graphics module. You can move the ship with 'a' and 'd', and shoot with space. My problem is that i cant make that you move and shoot at the same time. When I'm pressing 'd' to move and then i press space to shoot, the ship shoots but stop moving even if i never stop pressing 'd'.
let rec handler state old_time =
...
...
let event = Graphics.wait_next_event [ Graphics.Poll ] in
if event.Graphics.keypressed then
match (read_key ()) with
|'a' -> handler { new_state with player = ((fst new_state.player) - 20, snd new_state.player) } new_time
|'d' -> handler { new_state with player = ((fst new_state.player) + 20, snd new_state.player) } new_time
|' ' -> handler (fire_bullet new_state) new_time
| _ -> handler new_state new_time
else
handler new_state new_time
;;
I know about read_key reading from a queue and all that, but the problem is that he stops seeing that i'm holding down a key when i press another key.
Does anyone know how to solve this?
thanks.
The keyboard interface exposed by the graphics module is a bit limited.
You might consider using OCamlSDL instead. The Sdlkey and Sdlevent modules provide a more fine grained interface to the keyboard (amongst other things). In particular, you can detect KEYDOWN and KEYUP events.
let printf = Format.printf
let rec poll_keys () =
let open Sdlevent in
if has_event () then begin
match wait_event () with
| KEYDOWN {keysym=key} -> printf "keydown '%c'#." (Sdlkey.char_of_key key)
| KEYUP {keysym=key} -> printf "keyup '%c'#." (Sdlkey.char_of_key key)
| _ -> Sdltimer.delay 5
end;
poll_keys ()
let () =
Sdl.init [`VIDEO];
(* Sdlkey.enable_key_repeat (); *)
poll_keys ()
I want to get the return value of a function that I'm testing for a subsequent test. The function if defined like this:
func apple(banana: Banana) throws -> Cherry { ... }
I can test that it throws when it should:
XCTAssertThrowsError(try apple(banana: badBanana), "Didn't throw")
I can test it doesn't throw when it shouldn't:
XCTAssertNoThrow(try apple(banana: goodBanana), "Did throw")
I was hoping to do this:
XCTAssertNoThrow(let cherry = try apple(banana: goodBanana), "Did throw")
and then check cherry is what I would expect, but I get the following error: Consecutive statements on a line must be separated by ';'...
How can I get the returned value (an object of type Cherry in this case) from the XCTAssertNoThrow test? Or is there a better approach that I'm missing?
Many thanks
Simply call the function, and assert against the return value:
func test_apple_withGoodBanana_shouldReturnBingCherry() throws {
let result = try apple(banana: goodBanana)
XCTAssertEqual(result, .bing)
}
By marking the test method itself as throws we can call the try without ? or !. If it throws, the test will fail.
I'm using this static function:
func XCTAssertSuccessReturn<T>(
_ expression: #autoclosure () throws -> T,
in file: StaticString = #file,
line: UInt = #line
) -> T {
do {
return try expression()
} catch {
XCTFail(
error.localizedDescription,
file: file,
line: line
)
fatalError(error.localizedDescription)
}
}
Example:
let encryptedData = XCTAssertSuccessReturn(try encrypter.encrypt(data))
Here's one I like better; it doesn't cause testing to halt just because an unexpected error gets thrown. And it lets you add a message:
func CheckNoThrow<T>(
_ expression: #autoclosure () throws -> T,
_ message: #autoclosure () -> String = "",
file: StaticString = (#filePath),
line: UInt = #line
) -> T? {
var r: T?
XCTAssertNoThrow(
try { r = try expression() }(), message(), file: file, line: line)
return r
}
Every solution on here is nice with its own pros and cons. After trying them all out I like combining the error reporting of Dave and Vitali's answers with the simplicity of Jon's.
This gives information on the error thrown without a fatal error, returning an optional or executing subsequent XCTAssert statements after an error has been thrown.
func testApple() throws {
let result = XCTNoThrow(try apple(banana: goodBanana)
let result = try apple(banana: goodBanana)
XCTAssertEqual(result, .bing)
}
How do I write an async test method in F#?
I'm referencing the following code:
[TestMethod]
public async Task CorrectlyFailingTest()
{
await SystemUnderTest.FailAsync();
}
This is my failed attempt:
[<Test>]
let ``Correctly failing test``() = async {
SystemUnderTest.FailAsync() | Async.RunSynchronously
}
So after a bit of research, it turns out that this is more difficult than it ought to be. https://github.com/nunit/nunit/issues/34
That being said a workaround was mentioned. This seems kinda lame but, it looks like declaring a task delegate outside as a member and leveraging it is a viable work around.
The examples mentioned in the thread:
open System.Threading.Tasks
open System.Runtime.CompilerServices
let toTask computation : Task = Async.StartAsTask computation :> _
[<Test>]
[<AsyncStateMachine(typeof<Task>)>]
member x.``Test``() = toTask <| async {
do! asyncStuff()
}
And
open System.Threading.Tasks
open NUnit.Framework
let toAsyncTestDelegate computation =
new AsyncTestDelegate(fun () -> Async.StartAsTask computation :> Task)
[<Test>]
member x.``TestWithNUnit``() =
Assert.ThrowsAsync<InvalidOperationException>(asyncStuff 123 |> toAsyncTestDelegate)
|> ignore
[<Test>]
member x.``TestWithFsUnit``() =
asyncStuff 123
|> toAsyncTestDelegate
|> should throw typeof<InvalidOperationException>
XUnit had a similar problem and did come up with a solution:
https://github.com/xunit/xunit/issues/955
So you should be able to do this in xunit
[<Fact>]
let ``my async test``() =
async {
let! x = someAsyncCall()
AssertOnX
}
Sorry if this is not the most satisfying answer.
open Xunit
[<Fact>]
let ``my async test``() =
async {
do! Async.AwaitTask(someAsyncCall())|> Async.Ignore
AssertOnX
}
I asked https://github.com/fsprojects/FsUnit/issues/153 because I think that it is a responsibility of the F# unit testing framework to provide a right binding.
Meanwhile, this looks the best for me.
open System.Threading.Tasks
let runAsyncTest async = async |> Async.StartImmediateAsTask :> Task
[<Test>]
let ``Some test`` () = runAsyncTest <| async {
}
This is an old question but now can use the task builder from the Ply package for testing C# async methods in Xunit like so:
open FSharp.Control.Tasks
open System.Threading
open Xunit
let ``Test some Task returning async method`` () =
task {
let! actual = MyType.GetSomethingAsync()
Assert.Equal(expected, actual)
return ()
}
I am running the following go code and it doesn't produce output:
package main
import "fmt"
//import "strconv"
import "time"
func Wait(){
time.Sleep(2000 * time.Millisecond)
}
func Print(c chan string){
fmt.Println("Running Print go-routine")
for{
fmt.Println("len(c): ", len(c))
str := <- c
fmt.Println(str)
}
}
func main() {
c := make(chan string, 4)
c <- "0"
c <- "1"
c <- "2"
c <- "3"
Wait()
fmt.Println("Before go Print(c)")
go Print(c)
fmt.Println("After go Print(c)")
}
Is there a deadlock? The Print(c) function is not even called...? Its very strange to me.
The link to it in go playground is: http://play.golang.org/p/tDjEJKwkRJ
There isn't an error, the Print() function is called in a goroutine, but the main program is exiting right after that... so the goroutine is terminated.
Read this talk: Go Concurrency Patterns (or better, view it's video), to understand how channels and goroutines work.
Keep in mind that the program is finished when the main function returns.
When the main function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.
Call your Wait function later, after the go Print(c) statement. For example,
package main
import (
"fmt"
"time"
)
func Wait() {
time.Sleep(2000 * time.Millisecond)
}
func Print(c chan string) {
fmt.Println("Running Print go-routine")
for {
fmt.Println("len(c): ", len(c))
str := <-c
fmt.Println(str)
}
}
func main() {
c := make(chan string, 4)
c <- "0"
c <- "1"
c <- "2"
c <- "3"
fmt.Println("Before go Print(c)")
go Print(c)
Wait()
fmt.Println("After go Print(c)")
}
Output:
Before go Print(c)
Running Print go-routine
len(c): 4
0
len(c): 3
1
len(c): 2
2
len(c): 1
3
len(c): 0
After go Print(c)
The Go Programming Language Specification
Program execution
A complete program is created by linking a single, unimported package
called the main package with all the packages it imports,
transitively. The main package must have package name main and declare
a function main that takes no arguments and returns no value.
func main() { … }
Program execution begins by initializing the main package and then
invoking the function main. When that function invocation returns, the
program exits. It does not wait for other (non-main) goroutines to
complete.