1
votes

I am using two imports

import org.json4s._
import org.json4s.native.JsonMethods._

I have the following source code

val json = parse("~~~~~~aklsdjfalksdjfalkdsf")
var abc = (json \\ "something").children map {
        _.extract[POJO]
    }

After I ran it I saw

Error:(32, 18) No org.json4s.Formats found. Try to bring an instance of org.json4s.Formats in scope or use the org.json4s.DefaultFormats.
        _.extract[POJO]

Error:(32, 18) not enough arguments for method extract: (implicit formats: org.json4s.Formats, implicit mf: scala.reflect.Manifest[POJO])POJO.
Unspecified value parameters formats, mf.
        _.extract[POJO]

I know I should be declaring :

 implicit val df = DefaultFormats

I learnt how to use 'implicit' for my scala code. However I need to understand how to use a library that enforces developers to define an implicit variable in their source code.

It seems a keyword 'implicit' is used in 'extract' method in ExtractableJsonAstNode class file as stated in the error message.

 def extract[A](implicit formats: Formats, mf: scala.reflect.Manifest[A]): A =
    Extraction.extract(jv)(formats, mf)

I see that that is looking for 'implicit' variable keyword to be declard in my source code.

The first question is how do I know when an implicit keyword is to be used for another implicit keyword (e.g. declared in a library), or it's going to be a switch of an operation I define (case that 'implicit' not to be declared twice) the only clue I have is, when mother source code is using 'implicit' keyword and using a variable and it's type is a trait. Then I(dev) need to declare a variable with a type of a concrete class that extends that trait. I don't know if it's true..

also I found the following source code in 'Formats.scala' file within the json library.

 class CustomSerializer[A: Manifest](
    ser: Formats => (PartialFunction[JValue, A], PartialFunction[Any, JValue])) extends Serializer[A] {

    val Class = implicitly[Manifest[A]].runtimeClass

    def deserialize(implicit format: Formats) = {
      case (TypeInfo(Class, _), json) =>
        if (ser(format)._1.isDefinedAt(json)) ser(format)._1(json)
        else throw new MappingException("Can't convert " + json + " to " + Class)
    }

    def serialize(implicit format: Formats) = ser(format)._2
  }

note that def deserialize(implicit format: Formats) is declared. once I write 'implicit val df = DefaultFormats' in my file, will it affect the whole json mechanism not only the 'extract' method? as CustomSerializer is used in json library.

to summarise.. the first question is about one of 'implicit' keyword usages. the second question is about 'implicit' keyword scope.

1
It looks like you can just import org.json4s.DefaultFormats ln the file where you are using the extract method. It should already be implicit.Charles

1 Answers

1
votes

When do I use the implicit keyword?

Implicits are used to defne the behavior of things you normally do not have control over. In your question, DefaultFormats is already an implicit. You do not need to declare a new implicit using it, you can just import it.

As for knowing when a library you're using requires some implicit in scope, that error is it. It is essentially telling you "if you're not sure what this error is about you can just import DefaultFormats.

Will an implicit affect the whole mechanism?

This is a key question that is important to understand.

When you have a function that takes an implicit, your compiler will search the scope for an implicit of that type.

Your function is looking for org.json4s.Formats. By importing DefaultFormat or writing your own implicit of type Format, you are teliing your function to use that format.

What effect does this have on the rest of your code?

Any other functions you have that rely on an implicit Format in the scope will use the same implicit. This is probably fine for you.

If you need to use multiple different Formats, you will want to split up those components from each other. You do not want to define multiple implicits of the same type in the same scope. This is confusing for humans and computers and should just be avoided.