0

I have a case where I wish to extend a class that takes by-name parameter in it's constructor:

class Extension(something: Something) 
  extends Base(something.doSomething(something.getSomething(false))

class Base(expression: => Result) {
  ...
}

However, the call to something.getSomething(false) causes side-effects, and so can't be called multiple times.

How can I store the result of something.getSomething(false), before passing it to the superclass' constructor?

Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
  • The code should be redesigned so that mutation and inheritance are avoided; this usually provides for a much nicer and easier to work with implementation. – Erik Kaplun Nov 05 '14 at 12:59
  • @ErikAllik In this case, it's not mutation, but rather that it involves file access - the call only works at the beginning of the file, after the executions that's no longer the case. Avoiding inheritance in this case, however, is probably a good suggestion. Either way, I felt this should be possible somehow, and it is. – Gareth Latty Nov 05 '14 at 13:03
  • File access *is* mutation :) and you can easily work around that by moving the IO bit outside of the core logic, or by using caching, or some other means. – Erik Kaplun Nov 05 '14 at 13:06
  • All I'm saying here really is that this question would not even arise if only idiomatic functional Scala were used. – Erik Kaplun Nov 05 '14 at 13:08
  • @ErikAllik Well, yes, but it's outside of my control in this case (beyond wrapping it, which is what I'm already doing here, so two layers of wrappings feels ugly). You are right that the best solution to this is probably one of design. – Gareth Latty Nov 05 '14 at 13:08

1 Answers1

0

We can do this by having two constructors - one that takes both the parameter and generated parameter, and one that takes only the parameter the user should provide.

We make the first constructor private, so people don't accidentally use it, then we use the second constructor to construct the value and pass it into the first.

class Extension private (something: Something, generatedFromSomething: Generated)
    extends Base(something.doSomething(generatedFromSomething) {
  def this(something: Something) = this(something, something.getSomething(false))
}

As ErikAllik suggests in the comments, it may be best to simply avoid inheritance if possible, as it becomes trivial to do this outside of that case:

def extended(something: Something) = {
  val generatedFromSomething = something.getSomething(false)
  new Base(something.doSomething(generatedFromSomething)
}
Community
  • 1
  • 1
Gareth Latty
  • 86,389
  • 17
  • 178
  • 183