1

An old trick I used in my previous Java projects was to create e.g. a FileUtils class that offered helper functions for common file operations needed by my project and not covered by e.g. org.apache.commons.io.FileUtils. Therefore my custom FileUtils would extend org.apache.commons.io.FileUtils and offer all their functions as well.

Now I try to do the same in Scala but the apache helper functions are not seen through my FileUtils Scala object, what is wrong here?

import org.apache.commons.io.{ FileUtils => ApacheFileUtils }

object FileUtils extends ApacheFileUtils {
   // ... additional helper methods
}

val content = FileUtils.readFileToString(new File("/tmp/whatever.txt"))

here the compiler complains that readFileToString is not a member of my Scala FileUtils but it is of ApacheFileUtils and I extend from it ...

2
  • 4
    I'm guessing readFileToString is a static method in Java, so it wouldn't be inherited by extending that class. Commented Jun 19, 2014 at 14:10
  • Indeed, readFileToString is a static method. Commented Jun 19, 2014 at 14:17

1 Answer 1

5

The Scala equivalent of a class with static methods is an object, so in Scala terms, the static components of FileUtils are seen as

object FileUtils {
  def readFile(s:String) = ???
  ...
}

And in Scala, you can't extend an object. This is illegal:

object A
object B extends A // A is not a type

Therefore object FileUtils extends ApacheFileUtils only gives you access to the class-level definitions of ApacheFileUtils (that except for the base Object methods like equals and hashCode, you have none)

You might find that Scala offers more elegant ways of providing extensions. Have a look at the 'pimp up my library' pattern for good starting point.

To apply this pattern to your example:

// definition of your "pimped" methods
import java.io.File

class RichFile(file:File) {
  def readToString():String = ???
}

// companion object defines implicit conversion 
object RichFile { 
  implicit def fileToRichFile(f:File):RichFile = new RichFile(f)
}

// Usage

import RichFile._

val content = new File("/tmp/whatever.txt").readToString
Sign up to request clarification or add additional context in comments.

3 Comments

A better suggestion might be implicit class RichFile(...) extends AnyVal. I'm not sure people say "pimp my lib" anymore; but I'm pretty sure they never said "pimp up." :)
@som-snytt extends AnyVal +1. How do you bring the implicit into context when you do implicit class? I personally find the companion object method quite clean and somehow explicit. "pimp up" -> :-)
package object is ideal for implicit classes. If the package is enclosing, you do "package foo ; package bar" to pick up foo._, otherwise, the explicit import foo._.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.