0

I have to create a file loader object and I would like the file to be loaded only once at object creation.
What I did until now is create a trait with a method read that will read file and output a list of String.

trait Loader {
  protected val readSource: List[String] = {
    Source
      .fromInputStream(getClass.getResourceAsStream("filename"), "UTF-8")
      .getLines()
      .toList
  }

  def transform(delimeter: String): Vector[C] = {
    val lines = readSource
    // process the lines
  }
}

The trait is implemented by several object, and the transform method can be called multiple times in the client code.

I would like to avoid re reading the file each time the transform method is called and my first solution was to extract the val lines = readSource from the transform method and make a function of it def loadFile = readSource and to create a apply method in my objects to call loadFile like so :

object MyLoader extends Loader {
  def apply: List[String] = {
    loadFile
  }
}

I am wondering if this is the right way to do it. Thank you for your advices.

1
  • Despite the name, readSource is not a method, it is just a val that is initialised once when the object is created, so the file is not read each time you call transform. However I would make this a lazy val so that it is not initialised until it is first used, which will be after the object is initialised. Commented Jan 29, 2019 at 18:10

1 Answer 1

1

If you want the resource read once for all, then you should do that in a singleton object, which will be initialized once lazily.

Clients should use that object. "Prefer composition over inheritance" is the mantra.

If you want a mix-in that makes it easy to use the object, you can use "self-types" to constrain clients:

trait HasResource { val resource: R = TheResource }
trait Client { self: HasResource => def getR: R = resource }

This is the "cake pattern" way of making stuff available.

Sign up to request clarification or add additional context in comments.

Comments

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.