score:5

Accepted answer

when defining an explicit companion object for a case class (as of scala 2.11), to fully replace the compiler provided functionality in the lost implicit companion object, the basic template for the explicit companion object has two requirements:

requirements:
1. must extend a function definition which consists of a tuple (exactly matching the type and order of the case class constructor parameters) returning the type of the case class
2. must override the tostring function to provide the object class name (identical to that of the associated case class)

here's the original example code for the "empty" explicit companion object:

object streetsecondary {
  //empty for now
}

and here is the example code after implementing the above requirements:

object streetsecondary extends ((string, option[string]) => streetsecondary) {
    //replace the tostring implementation coming from the inherited class (functionn)
    override def tostring =
      getclass.getname.split("""\$""").reverse.dropwhile(x => {val char = x.take(1).head; !((char == '_') || char.isletter)}).head
}

to meet requirement 1 above, extends ((string, option[string]) => streetsecondary) is inserted right after the object name and before the first curly brace.

to meet requirement 2 above, override def tostring = getclass.getname.split("""\$""").reverse.dropwhile(x => {val char = x.take(1).head; !((char == '_') || char.isletter)}).head is inserted in the body of the object (the explicit implementation remains questionable)

deep appreciation to @drstevens for his posting the javap output to help me gain confidence the above two steps are all that are required to restore the lost functionality.

score:1

why would you think you are loosing them?

case class person(name: string, age: int)
object person {
  def apply(): person = new person("bob", 33)
}

val alice = person("alice", 20)
val bob   = person()

person.unapply(alice)    //option[(string, int)] = some((alice,20))
person.unapply(person()) //option[(string, int)] = some((bob,33))

seems like i still got extractors.

in your case you still got it all:

scala> streetsecondary.unapply _
res10: streetsecondary => option[(string, option[string])] = <function1>

score:3

scala 2.11.0

it looks like scalac is predefining the tupled function when you aren't providing additional functions in the companion

case class bb(a: int, b: int)
object bb { }

case class aa(a: int, b: int)

object cc { }
case class cc(a: int, b: int)

results in the following

public class aa implements scala.product,scala.serializable {
  public static scala.option<scala.tuple2<java.lang.object, java.lang.object>> unapply(aa);
  public static aa apply(int, int);
  public static scala.function1<scala.tuple2<java.lang.object, java.lang.object>, aa> tupled();
  public static scala.function1<java.lang.object, scala.function1<java.lang.object, aa>> curried();
  public int a();
  public int b();
  public aa copy(int, int);
  public int copy$default$1();
  public int copy$default$2();
  public java.lang.string productprefix();
  public int productarity();
  public java.lang.object productelement(int);
  public scala.collection.iterator<java.lang.object> productiterator();
  public boolean canequal(java.lang.object);
  public int hashcode();
  public java.lang.string tostring();
  public boolean equals(java.lang.object);
  public aa(int, int);
}

public final class aa$ extends scala.runtime.abstractfunction2<java.lang.object, java.lang.object, aa> implements scala.serializable {
  public static final aa$ module$;
  public static {};
  public final java.lang.string tostring();
  public aa apply(int, int);
  public scala.option<scala.tuple2<java.lang.object, java.lang.object>> unapply(aa);
  public java.lang.object apply(java.lang.object, java.lang.object);
}

public class bb implements scala.product,scala.serializable {
  public static scala.option<scala.tuple2<java.lang.object, java.lang.object>> unapply(bb);
  public static bb apply(int, int);
  public int a();
  public int b();
  public bb copy(int, int);
  public int copy$default$1();
  public int copy$default$2();
  public java.lang.string productprefix();
  public int productarity();
  public java.lang.object productelement(int);
  public scala.collection.iterator<java.lang.object> productiterator();
  public boolean canequal(java.lang.object);
  public int hashcode();
  public java.lang.string tostring();
  public boolean equals(java.lang.object);
  public bb(int, int);
}

public final class bb$ implements scala.serializable {
  public static final bb$ module$;
  public static {};
  public bb apply(int, int);
  public scala.option<scala.tuple2<java.lang.object, java.lang.object>> unapply(bb);
}

public class cc implements scala.product,scala.serializable {
  public static scala.option<scala.tuple2<java.lang.object, java.lang.object>> unapply(cc);
  public static cc apply(int, int);
  public int a();
  public int b();
  public cc copy(int, int);
  public int copy$default$1();
  public int copy$default$2();
  public java.lang.string productprefix();
  public int productarity();
  public java.lang.object productelement(int);
  public scala.collection.iterator<java.lang.object> productiterator();
  public boolean canequal(java.lang.object);
  public int hashcode();
  public java.lang.string tostring();
  public boolean equals(java.lang.object);
  public cc(int, int);
}

public final class cc$ implements scala.serializable {
  public static final cc$ module$;
  public static {};
  public cc apply(int, int);
  public scala.option<scala.tuple2<java.lang.object, java.lang.object>> unapply(cc);
}

Related Query

More Query from same tag