lightbend / config

configuration library for JVM languages using HOCON files
https://lightbend.github.io/config/
6.17k stars 965 forks source link

Add get<Type>OrNull() methods to Config #186

Open javaerb opened 10 years ago

javaerb commented 10 years ago

I often have to use boilerplate code like String value = config.hasPath("foo/bar") ? config.getString("foo/bar") : null;

Would be nice to have, for all getters in Config class, either getOptionalString(String key) or getString(String key, String defaultValue)

(I may do a pull request for this if I get some time.)

havocp commented 10 years ago

Optional is only in Scala or Java 8, though.

javaerb commented 10 years ago

I meant little-o optional, not big-O Optional. See my description.

havocp commented 10 years ago

what does it return? you are saying null?

There's a discussion here https://github.com/typesafehub/config/blob/master/README.md#how-to-handle-defaults

javaerb commented 10 years ago

Yeah, and I see this issue came up in #110 also. But in pre-1.8 Java I assert there are legitimate reasons for allowing null as a value. So we end up writing our own utility methods for this anyway. So why not just put this method in the API? You have convinced me that the getXXX(path, defaultValue) pattern should be avoided, since the default value should be in config. But I think a method like getOptionalString(path) would make sense. The name makes it clear that you are treating this property as nullable. And these optional methods would only apply to the few getters that return objects rather than simple types, which might only end up being getString and getNumber. In fact, one can argue that an optional number is not a real use case, so maybe I'm arguing only for getOptionalString. OK, getOptionalBoolean might be nice, but not critical.

javaerb commented 10 years ago

Plus if the Play framework can return null/optional, why not config?

havocp commented 9 years ago

My best idea here would be:

benburton commented 9 years ago

Sorry if this is not the right place for this comment, but what is wrong with something like this?

object ConfigImplicits {

  import com.typesafe.config._

  implicit class ConfigOptions(config: Config) {

    def getStringOpt(key: String) = getOpt[String](key, config.getString)
    def getIntOpt(key: String) = getOpt[Int](key, config.getInt)
    def getBooleanOpt(key: String) = getOpt[Boolean](key, config.getBoolean)
    // etc...

    private def getOpt[T](key: String, method: String => T) = try {
      Some(method(key))
    } catch {
      case e: ConfigException.Missing => None
      case e: Throwable => throw e
    }

  }

}

EDIT: This should use the hasPath method and not catch exceptions, but is the idea sound?

havocp commented 9 years ago

The issue there is that it's a Java library and you're writing Scala :-) but yes it's a sound idea. I think the README mentions this along with several other patterns that are an alternative to optional getters.

benburton commented 9 years ago

Oh! Oops :)

benmccann commented 9 years ago

FYI, this library is now using Java 1.8, so if you do want to use java.util.Optional, that's an option now

havocp commented 9 years ago

https://github.com/typesafehub/config/commit/aeebeaa414965069d4d8412cc21e81db9fd2cb5d is available for comment, has an example of one OrNull method. Figured I'd get some comments before cut-and-pasting it a couple dozen times.

havocp commented 9 years ago

an alternative to the couple dozen new methods would be to add hasPathOrNull to allow efficient implementation outside the library, and leave it at that.

iurisman commented 5 years ago

Java 7 has been EOL for years. Time to embrace Option(al) and forget nulls.

havocp commented 5 years ago

The sample implementation of one method above used Optional and Java 8 is now required, but iirc we decided not to do the couple dozen methods to cover a relatively rare situation. The method is called OrNull because it succeeds if the value is null but fails if the path is missing entirely.