Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Enumeration
    • Labels:
      None

      Description

      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...
      

        Issue Links

          Activity

          Hide
          Trond Olsen added a comment -

          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)
          ...
          }
          
          Show
          Trond Olsen added a comment - 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) ... }
          Hide
          Trond Olsen added a comment -

          Besides that, there's something funky going on since

          Show
          Trond Olsen added a comment - Besides that, there's something funky going on since
          Hide
          Steve Jenson added a comment -

          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)

          Show
          Steve Jenson added a comment - 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)
          Hide
          Pablo Oliveira added a comment -

          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 (SI-4045).

          Show
          Pablo Oliveira added a comment - 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 ( SI-4045 ).
          Hide
          Hubert Plociniczak added a comment -

          (In r23893) Closes SI-3687, SI-3719, SI-3950, SI-3616. Plus removed some deprecated stuff for 2.9. Review by extempore

          Show
          Hubert Plociniczak added a comment - (In r23893) Closes SI-3687 , SI-3719 , SI-3950 , SI-3616 . Plus removed some deprecated stuff for 2.9. Review by extempore

            People

            • Assignee:
              Hubert Plociniczak
              Reporter:
              Eduardo Moritz Cavalcanti
              TracCC:
              hanna, Ismael Juma, Pablo Oliveira, Paul Phillips, Seth Tisue, Steve Jenson, Trond Olsen
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development