0

I am trying to write a given string into a new file in SCALA.

I have imported

java.io._
java.nio._

This is my code:

implicit class PathImplicits(p: Path) {
     def write(str:String, file:String):Path = Paths.get(file)
     p.write(str,file)
    }

However, the compile says it does not recognize the 'file' variable.

user274065
  • 97
  • 1
  • 10

1 Answers1

0

First of all, you are missing a pair of braces around your function. I think, you intended it to look like this:

 def write(str:String, file:String):Path = { 
   Paths.get(file)
   p.write(str,file)
 }

It looks like it, because str and file are parameters to the function, and you are trying to use them outside of it (a function body without braces is just one statement).

Now, the way I "fixed" it for you, still doesn't make very much sense. First, Paths.get(file) doesn't do anything, it just returns the Path object, which you do not assign to anything, so, this call does not have any effect. Second, Path does not have a method, called write, so the second line isn't going to work. Perhaps, you intended it to implicitly end up calling PathImplicits.write, but that won't work (you'd have to be outside of that class), and that's a good thing, because you are actually inside that function, and, if that line called it again, you'd get into infinite recursion.

Let's break your problem into two parts. First, let's forget about implicits and other fancy stuff, and just figure out how to write a string into a file. There is a whole lot of different ways to do it. Here is one for instance:

 def writeToFile(file: File, str: String): Unit = {
    val writer = new FileWriter(file)
    try { writer.append(str).append("\n") }
    finally { writer.close }        
 }

Now, if you want to make it work with Path implicitly, you'd need something like this:

 object PathImplicits {
   implicit class RichPath(p: Path) extends AnyVal {
      def write(str: String) = writeToFile(p.toFile, str)
   }
 }

That's it. Now, you should be able to write something like this:

import PathImplicits._
Paths.get("/some/path/to/file.txt").write("Foo!")    
Dima
  • 39,570
  • 6
  • 44
  • 70
  • All good, but why does `RichPath` extend `AnyVal`? – Tzach Zohar Apr 11 '16 at 13:58
  • 1
    @TzachZohar that's a trick you can do to avoid instantiating of implicit classes: if it did not extend `AnyVal`, then `path.write("foo")` would result in a creation of intermediate object for `RichPath` before invoking `write` on it, and discarding. With `extends AnyVal` trick, this redundant instantiation is avoided, same way as `3.toString` does not create an instance of `Integer` – Dima Apr 11 '16 at 14:24
  • nifty trick, thanks @Dima! – Tzach Zohar Apr 11 '16 at 14:26