4

The latest updates of pureconfig in the 0.10.* series disabled automatic configuration by default.

import pureconfig.generic.auto._

needs to be manually imported. But I have a class hierarchy, where I do not want to import it every time for a child class.

import pureconfig.ConfigReader
abstract class SparkBaseRunner[T <: Product](implicit A: ConfigReader[T])extends App {}

already expects a configReader. When using this base class:

object MyOperation extends SparkBaseRunner[MyCaseClass] {}

it fails with:

could not find implicit value for parameter A: pureconfig.ConfigReader[foo.bar.my.Type]

unless the above mentioned input is specified manually at each child class. Is there a way to avoid this code duplication? Trying to specify the input in the abstract base class did not work for me as it requires already a ConfigReader object.

edit

Trying to manually get access to the config reader inside the base class also fails:

implicit val configReader = deriveReader[T]
could not find implicit value for parameter A: pureconfig.ConfigReader[T]
could not find Lazy implicit value of type pureconfig.generic.DerivedConfigReader[T]

My Scala version is: 2.11.12

Georg Heiler
  • 16,916
  • 36
  • 162
  • 292
  • Packing the implicit as a field on `SparkBaseRunner` seems to be the anti-pattern here; just add an `(implicit A: ConfigReader[T])` argument list to wherever you actually need the `ConfigReader` (with the benefit you'll only need to `import pureconfig.generic.auto._` in that place). Otherwise, I think you may be out of luck: the `auto` object contains macro implementations, so it fundamentally cannot be a trait that you could mix in (so as to avoid the import). – Alec Mar 02 '19 at 16:55
  • If I only want to pass T to the base class and have the base class infer the configuration - maybe using semi-automatic mode - could this solve the problem and prevent the duplicated imports? – Georg Heiler Mar 02 '19 at 16:57
  • The base class can't infer the configuration since all it has is a generic type `T`. – Alec Mar 02 '19 at 17:00
  • Even if it is a case class. – Georg Heiler Mar 02 '19 at 17:07
  • I'm not sure what you are suggesting. I still don't see why you can't have `def readMyConfig[T, A <: SparkBaseRunner[T])(a: A)(implicit reader: ConfigReader[T]) = ...`. Then, you only `import pureconfig.generic.auto._` wherever you call `readMyConfig`. – Alec Mar 02 '19 at 17:11
  • Indeed that would be possible and work just fine as described in the question. However, I would like to perform this import only once as it makes the code more maintainable in my opinion. Also consumers can simply implement the base class and do not need to worry about random implicit imports. – Georg Heiler Mar 03 '19 at 06:22

1 Answers1

0

I believe that the config is being read as a single operation already, and there are multiple applications, all doing the below:

object Ops extends SparkBaseRunner[MyCaseClass]

I can't see a way to avoid duplication since the base class can't infer the configuration since all it has is a generic type T.

The best solution is to not worry about it and use auto._.

import pureconfig.generic.auto._
OBarros
  • 132
  • 1
  • 9