2009-12-21 5 views
3

J'utilise Scala 2.8 et la définition d'un Enumeration comme celui-ci:Comment ajouter une méthode à un objet Scala Enumeration?

object Stooges extends Enumeration { 
    type Stooge = Value 
    val Larry, Curly, Moe = Value 
} 

Et je veux ajouter une méthode à cette énumération que les cycles à la « prochaine » larbin. Je peux définir une telle méthode en dehors des Stooges et cela fonctionne dans un programme d'essais très bien:

def nextStooge(v:Stooges.Stooge):Stooges.Stooge = 
    Stooges((v.id+1) % Stooges.values.size) 

Ce que je voudrais vraiment est d'ajouter cette méthode pour Stooges et je l'ai essayé de faire une telle chose (en utilisant les deux Stooges .Stooge et Stooges.Value). Ces deux compilent. Mais l'exécution d'un programme comme celui-ci:

import Stooges._ 
object App extends Application { 
    println(Stooges.nextStooge(Larry)) 
} 

rendements:

Exception in thread "main" java.lang.ExceptionInInitializerError 
     at demo.App.main(Stooges.scala) 
Caused by: java.lang.IllegalArgumentException: wrong number of arguments 
     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(Method.java:592) 
     at scala.Enumeration$$anonfun$scala$Enumeration$$nameOf$2.apply(Enumeration.scala:176) 
     at scala.Enumeration$$anonfun$scala$Enumeration$$nameOf$2.apply(Enumeration.scala:171) 
     at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:1200) 
     at scala.collection.IndexedSeqLike$class.foreach(IndexedSeqLike.scala:85) 
     at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:20) 
     at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:1199) 
     at scala.Enumeration.scala$Enumeration$$nameOf(Enumeration.scala:171) 
     at scala.Enumeration$Val.toString(Enumeration.scala:237) 
     at java.lang.String.valueOf(String.java:2615) 
     at java.io.PrintStream.print(PrintStream.java:616) 
     at java.io.PrintStream.println(PrintStream.java:753) 
     at scala.Console$.println(Console.scala:198) 
     at scala.Predef$.println(Predef.scala:152) 
     at demo.App$.<init>(Stooges.scala:14) 
     at demo.App$.<clinit>(Stooges.scala) 

Est-ce un bug ou tout simplement une mauvaise idée?

Répondre

4

Cela fonctionne pour moi:

scala> object Stooges extends Enumeration { 
    | type Stooge = Value 
    | val Larry = Value("Larry") 
    | val Curly = Value("Curly") 
    | val Moe = Value("Moe") 
    | 
    | def nextStooge(v:Stooges.Stooge) = Stooges((v.id+1) % Stooges.maxId) 
    | } 
defined module Stooges 

scala> 

scala> import Stooges._ 
import Stooges._ 

scala> nextStooge(Larry) 
res0: Stooges.Value = Curly 

scala> nextStooge(Curly) 
res1: Stooges.Value = Moe 

scala> nextStooge(Moe) 
res2: Stooges.Value = Larry 

Il serait definetively plus agréable d'être en mesure de dire Larry.nextStooge au lieu de nextStooge(Larry). Je suppose que vous devez implémenter cela avec une classe scellée personnalisée.

+0

En effet, ne pas avoir besoin de passer l'argument à nextStooge (et de l'appeler next()) était mon objectif initial. Intéressant que cela fonctionne en spécifiant chaque val séparément et en le nommant. Je vais jouer un peu plus. –

+0

@AlexMiller, http://stackoverflow.com/questions/4346580/how-to-add-a-method-to-enumeration-in-scala montre comment cela peut être fait. –

2

Ceci est un bug. Cette initalisation fait quelque chose de terriblement étrange. Je vais ouvrir un ticket (fait, #2827), s'il n'en existe aucun.

+0

Merci beaucoup .... –

Questions connexes