Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enumeration.maxId reporting wrong value? #3687

Closed
scabug opened this issue Jul 19, 2010 · 11 comments
Closed

Enumeration.maxId reporting wrong value? #3687

scabug opened this issue Jul 19, 2010 · 11 comments
Assignees
Labels

Comments

@scabug
Copy link

scabug commented Jul 19, 2010

Please verify if it is a bug:

Scaladoc defines Enumeration.maxId as:
"The highest integer amongst those used to identify values in this enumeration."

In the case below, should not maxId be 3 instead of 4?

Thank you.

scala> object EnumTest extends Enumeration {  val aa, bb, cc, dd = Value  }

scala> EnumTest(0)
res3: EnumTest.Value = aa

scala> val mm = EnumTest.maxId
mm: Int = 4

scala> EnumTest(mm)
java.util.NoSuchElementException: key not found: 4
        at scala.collection.MapLike$$class.default(MapLike.scala:223)
        at scala.collection.mutable.HashMap.default(HashMap.scala:39)
        at scala.collection.MapLike$$class.apply(MapLike.scala:134)
        at scala.collection.mutable.HashMap.apply(HashMap.scala:39)
        at scala.Enumeration.apply(Enumeration.scala:144)
        at .<init>(<console>:8)
        at .<clinit>(<console>)
        at RequestResult$$.<init>(<console>:9)
        at RequestResult$$.<clinit>(<console>)
        at RequestResult$$scala_repl_result(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Me...
@scabug
Copy link
Author

scabug commented Jul 19, 2010

Imported From: https://issues.scala-lang.org/browse/SI-3687?orig=1
Reporter: Eduardo Moritz Cavalcanti (eduardocavalcanti)
See #5211

@scabug
Copy link
Author

scabug commented Jul 19, 2010

@paulp said:
Seems like a bug in the documentation (and a bug in the name of the method) but not a bug in the result. The highest used id is not a useful thing to report in the public API. There are no methods which return the highest index in a sequence. And returning the max id forces a nonsense answer on the empty sequence. Returning -1 would be tantamount to breaking into peoples' homes to add bugs.

@scabug
Copy link
Author

scabug commented Jul 20, 2010

Eduardo Moritz Cavalcanti (eduardocavalcanti) said:
I was looking for Enumeration.size, but there was only maxId. Now I see that I can use
theEnumeration.values.size.
Thank you.

@scabug
Copy link
Author

scabug commented Aug 7, 2010

@lrytz said:
there seems to be more problems with the current Enumeration implementation. Adding some println to the Val constructor reveals that this one runs much more often than expected. Also the following:

scala> object t extends Enumeration { val a, b = Value }
defined module t

scala> t.values
res0: t.ValueSet = t.ValueSet(a, b)

scala> t.values
res1: t.ValueSet = t.ValueSet(a, b, Value)

@scabug
Copy link
Author

scabug commented Aug 10, 2010

@lrytz said:
Somebody needs to look at Enumeration in general, there are three bugs: the two reported here and #3719. hubert, do you want to have a look?

@scabug
Copy link
Author

scabug commented Oct 15, 2010

Eduardo Moritz Cavalcanti (eduardocavalcanti) said:
The problems reported stand for 2.8.1 RC3.

The second situation reported affects values.size:

scala> object t extends Enumeration { val a, b = Value }

defined module t

scala> t.values.size

res0: Int = 2

scala> t.values.size

res1: Int = 2

scala> t.values

res2: t.ValueSet? = t.ValueSet?(a, b)

scala> t.values.size

res3: Int = 3

scala> t.values

res4: t.ValueSet? = t.ValueSet?(a, b, Value)

Regards

@scabug
Copy link
Author

scabug commented Dec 13, 2010

Trond Olsen (tolsen) said:
The problem seems to lie in the Enumeration.populateNameMap() method. It uses reflections to collect all methods that matches the signature () => Value, so it accidentally picks up the Value method of Enumeration.

Here's a print dump:

populateNameMap:enter nmap='Map()'
populateNameMap name='a' m='public scalatest.Enumeration$$Value line4$$object$$$$iw$$$$iw$$$$iw$$t$$.a()' value='0'
populateNameMap declaringClass='class line4$$object$$$$iw$$$$iw$$$$iw$$t$$'
populateNameMap name='b' m='public scalatest.Enumeration$$Value line4$$object$$$$iw$$$$iw$$$$iw$$t$$.b()' value='1'
populateNameMap declaringClass='class line4$$object$$$$iw$$$$iw$$$$iw$$t$$'
populateNameMap name='Value' m='public final scalatest.Enumeration$$Value scalatest.Enumeration.Value()' value='2'
populateNameMap declaringClass='class scalatest.Enumeration'
populateNameMap:exit nmap='Map(2 -> Value, 1 -> b, 0 -> a)'

A quick fix could be just to filter away the method from the Enumeration class:

private def populateNameMap() {
...
  val methods = getClass.getMethods filter (m => m.getParameterTypes.isEmpty && classOf[Value].isAssignableFrom(m.getReturnType) && classOf[Enumeration] != m.getDeclaringClass)
...
}

@scabug
Copy link
Author

scabug commented Dec 13, 2010

Trond Olsen (tolsen) said:
Besides that, there's something funky going on since

@scabug
Copy link
Author

scabug commented Dec 16, 2010

Steve Jenson (stevej) said:
We just ran into this with 2.8.1. Our workaround is using named Values.

$$ scala
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> object Blar extends Enumeration {
| val A = Value("A")
| val B = Value("B")
| }
defined module Blar

scala> println(Blar.values)
Blar.ValueSet(A, B)

scala> println(Blar.values)
Blar.ValueSet(A, B)

@scabug
Copy link
Author

scabug commented Jan 1, 2011

Pablo Oliveira (pablo) said:
I concur with the analysis of tolsen.
His fix seems to solve the problem of an additional value "Value"
been created after printing twice enum.values (#4045).

@scabug
Copy link
Author

scabug commented Jan 4, 2011

@hubertp said:
(In r23893) Closes #3687, #3719, #3950, #3616. Plus removed some deprecated stuff for 2.9. Review by extempore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants