Raymond Chenon
Raymond Chenon

Reputation: 12722

Scala case class, modify a parameter in constructor

I have a case class

case class SiteID(channel: String, locale: String)

Locale can be "en-GB" or "en_GB" . So I want to replace the hyphen by underscore.

The idea is to transform , so there is this equality

SiteID("blabla","en-GB") == SiteID("blabla","en_GB")

I tried with the following code

case class SiteID(channel: String, locale: String)

object SiteID{

  def apply(channel: String, locale: String):SiteID =  SiteID(channel,locale.replace("-","_") )
}

Upvotes: 0

Views: 1307

Answers (3)

18446744073709551615
18446744073709551615

Reputation: 16872

Here is something that's rather close to what you want (you can make the Point's constructor protected):

case class Point(x: Double, y: Double)
class PolarPoint(r: Double, alpha: Double) extends Point(r*Math.cos(alpha), r*Math.sin(alpha))

and

@main def main(): Unit = {
  println(Point(10,10))
  println(PolarPoint(10, Math.PI/4))
}

prints:

Point(10.0,10.0)
Point(7.0710678118654755,7.071067811865475)

and r and alpha do not become members of PolarPoint:

public class PolarPoint extends Point {
    public PolarPoint(final double r, final double alpha) {
        super(r * Math.cos(alpha), r * Math.sin(alpha));
    }
}

If it's ok to reference objects as Foos but create FooImpls. you can do something like:

case class Foo protected(x:Int)
class FooImpl(x0:Int) extends Foo(myFunc(x0))

Upvotes: 0

Ali H.
Ali H.

Reputation: 371

With the Scala case class construct, the compiler automatically generates an apply method for you with the declared parameters. If you declare another one with the same parameter types as your case class, it takes precedence over the compiler's generated one.

So as stated in another answer your apply method is calling itself recursively; a solution was provided. If you additionally need to ensure that no SiteID("bla","en-GB") value will get instantiated, you should declare the constructor of your case class as private:

case class SiteID private(channel: String, locale: String)

object SiteID {
    def apply(channel: String, locale: String):SiteID =
        new SiteID(channel,locale.replace("-","_") )
}

SiteID("bla","en-GB") //SiteID(a,en_GB)
new SiteID("bla","en-GB") //error

Upvotes: 2

fusion
fusion

Reputation: 1287

You are probably calling recursively the apply method of the companion object. Try using the new operator.

 object SiteID {
    def apply(channel: String, locale: String):SiteID =
       new SiteID(channel,locale.replace("-","_") )
 }

Upvotes: 3

Related Questions