Arc Forumnew | comments | leaders | submitlogin
3 points by rocketnia 5207 days ago | link | parent

The "append" requirement is pretty specific. The file has to be opened for appending, if that's possible. The Python 2 and Groovy examples have complaints along these lines in the comments.

Furthermore, even though I think it was vague in the original description of the problem, the complaints indicate that the "world" line should be read into a variable.

So the first thing I tried was this, riffing off of evanrmurphy's version:

  (w/stdout (outfile "fileio.txt") prn!hello)
  (w/stdout (outfile "fileio.txt" 'append) prn!world)
  (pr:= line (string:cadr:readfile "fileio.txt"))
No luck. The file contains "helloworld" on one line. It doesn't even have a trailing newline. This is thanks to a lack of flushing, which is fixed on Anarki.

Speaking of bugs, do we even close these file handles?

And what if someone's mysteriously edited the file in between our commands, and we end up reading in a million-line file or barfing on a paren mismatch?

Also, most of the responses seem to use "putStrLn", "println", etc. for displaying the line that was read, even though that sacrifices two characters' worth of brevity. :-p

Let's try that again.

  (w/outfile f "fileio.txt" (disp "hello\n" f))
  (w/appendfile f "fileio.txt" (disp "world\n" f))
  (w/infile f "fileio.txt" (repeat 2 (= line readline.f)))
  prn.line
Whoops, I have a stray #\return at the end, 'cause I'm on Windows. To account for that, I can use Anarki and thereby take advantage of aw's 'readline fix and the flushing fix I mentioned earlier. If I use Anarki and take garply's lib/util.arc suggestion, this is what I get:

  (load "lib/util.arc")
  
  ; to be consistent
  (mac w/stdappendfile (name . body)
    (w/uniq gf
      `(w/appendfile ,gf ,name (w/stdout ,gf ,@body))))
  
  (w/stdoutfile "fileio.txt" prn!hello)
  (w/stdappendfile "fileio.txt" prn!world)
  (w/stdinfile "fileio.txt" (repeat 2 (= line (readline))))
  prn.line
That's what I'd settle for in this I/O demonstration, but if it were my own code I'd end up using Lathe, just so I could continue to support official Arc on Windows:

  (= lathe-dir* "my/path/to/lathe/arc/")
  (load:+ lathe-dir* "loadfirst.arc")
  (use-fromwds-as ut (+ lathe-dir* "utils.arc"))
  
  (w/outfile f "fileio.txt" (disp "hello\n" f))
  (w/appendfile f "fileio.txt" (disp "world\n" f))
  (w/infile f "fileio.txt" (repeat 2 (= line ut.readwine.f)))
  prn.line
Unfortunately, this code will break on Jarc 17 and Rainbow, and it's really their fault. :-p Mainly, both of them seem to overwrite the file rather than appending to it, and no workaround for that is coming to mind--well, except for ignoring that part of the problem statement. I'll start a new bug report thread.

For what it's worth, here's how I'd write it in Groovy:

  def file = "fileio.txt" as File
  file.withWriter { it.writeLine "hello" }
  file.withWriterAppend { it.writeLine "world" }
  def line = file.withReader { it.readLine(); it.readLine() }
  println line
My favorite posted answer is this PowerShell one. The comments lead me to believe it's cheating somehow, but the brevity is really impressive. This is pretty much what I'd expect a file I/O DSL to look like.

  sc fileio.txt 'hello'
  ac fileio.txt 'world'
  $line = (gc fileio.txt)[1]
  $line