I'm trying to call PureConfig's loadOrThrow from method with generic type:
def load[T: ClassTag](path: String): T = {
import pureconfig.generic.auto._
ConfigSource.file(path).loadOrThrow[T]
}
When I try to call it from main class, i got following error:
could not find implicit value for parameter reader: pureconfig.ConfigReader[T]
ConfigSource.file(path).loadOrThrow[T]
Can I fix this without import pureconfig.generic.auto._ in main class.
To summarize comments and explain how this codec thing works.
When you do:
you are using syntax sugar for
On the call site when you write:
compiler actually does
So basically it is type-based dependency injection supported by compiler. And dependency injection has to get the value to pass from somewhere.
How can compiler obtain that value to pass it over? It has to find it by its type in the scope. There should be one, unambiguously nearest value (or
defreturning this value) of this type marked asimplicit(Scala 2) orgiven(Scala 3).You have to define this value/method yourself or import it - in the scope that requires it - otherwise compiler will only try to look into companion objects of all types that contribute to your type
T- ifTis specific. (Or fail if it cannot find it anywhere like in your compiler error message).If
Tis generic, then you have to pass thatimplicit/givenas a parameter - but then you are only deferring the moment where you have to specify it and let the compiler find/generate it.In PureConfig's case,
pureconfig.generic.autocontainsimplicit defs which generate the value for a specifiedT. If you want to have it generated, you have to import it in the place which will turn require that specific instance. You might do it in a companion object, to make it auto-importable wherever thisConfigReaderwould be needed for this particular type or import it in main (or any other place which specifies the T to something). One way or the other, you will have to derive it somewhere and then add this[T: ConfigReader]or(implicit configReader: ConfigReader[T])in signatures of all the methods which shouldn't hardcodeTto anything.Summarizing your options are:
Tto a specific type in the main)implicitsomewhere else and then import it from there (some people do it intraits and then mix-in them, but I am not a fan of this approach)implicitin companion objectAs long as you want your configs to be parsed values rather than untyped JSON (HOCON) without writing these codecs yourself, you have to perform that automatic (or semiautomatic) derivation somewhere.