Given
case class Fruit(name: String, colour: String)
I'd like to deprecate the case class field colour
.
I tried to achieve the former by both employing Scala @deprecated
case class Fruit(name: String, @deprecated("message", "since") colour: String)
and Java @Deprecated
annotation
case class Fruit(
name: String,
/* @Deprecated with some message here */
@(Deprecated @field)
colour: String
)
Unfortunately I wasn't able to make colour
deprecated in any case and I'm not able to find any resource on that.
Indeed, I can achieve the same task using other approaches, e.g. by relaxing my case class to a normal class and provide a getter
for colour
and make the latter deprecated, but I would like to know if deprecating case class fields is actually not possible and -- eventually -- the reason why.
Thank you.
UPDATE
As Mike rightly pointed out, colour
is a required field for a case class, so the sense of setting this attribute to deprecated
is arguable. I'd like to deprecate colour
, since I'm now providing colour
information from another construct, I want to keep the user knowing that colour
is not the right instance by where fetch that information, and I will remove it from Fruit
in next releases.
By now, I'd just like warn users to not fetch colour
information from the Fruit attribute and, temporarily, I don't really care if they can create instances of fruit with colour information.
UPDATE 2
As Alexey said, I do have the deprecated warning at compile time. But why can't I observe the deprecation in my IDE code as well as I'd deprecating a method, then? I'd expect something like the following
val fruit = Fruit("peer", "green")
val colour = fruit.colour
I'm using IntelliJ.
Your first version seems to work fine: if you paste
case class Fruit(name: String, @deprecated("message", "since") colour: String)
println(Fruit("", "").colour)
at https://scastie.scala-lang.org/, you'll see the deprecation warning. Of course, you need to access the field, whether directly or through an extractor:
Fruit("", "") match { case Fruit(x, y) => y }
will also warn.
That IDEA doesn't show colour
as deprecated is I believe just a bug. In general it's quite unreliable in showing errors and warnings in Scala code inline and you should always check by actually building the project.
This is an odd use case. If a required field is deprecated, then the class itself must be deprecated too, surely? That is, assuming what you're trying to do is possible, it's impossible to use the class at all without getting a deprecation warning. (This probably explains why it's not possible.)
That said, as you indicate, there are ways to achieve what you're trying to do. Here's one of them:
case class Fruit(name: String) {
@deprecated("message", "since")
val colour: String = "some default value"
}
object Fruit {
// Deprecated factory method.
@deprecated("message", "since")
def apply(name: String, colour: String): Fruit = Fruit(name)
}
Clearly, this assumes that colour
is no longer required as an attribute of Fruit
. (If it is required, it should not be deprecated.) It works by deprecating the factory method that creates a Fruit
using a colour
value.
If this doesn't work, can you explain why the field needs to be deprecated?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With