tags:

views:

112

answers:

1

Hi

I hope this question hasn't been answered yet somewhere else. Didn't find an answer here.

In my localisation system I've got a class named Language

class Language(val name:String, dict:HashMap[String, String]) {
  def apply(key: String):String = (dict get key) match {
    case None    => "°unknown°"
    case Some(s) => s
  } 

  //DO SOME OTHER THINGS
}

and an object named LanguageCentral

object LanguageCentral {
  private var lang:Option[Language] = None
  //SOME OTHER PRIVATE MEMBERS

  def language = lang

  def language_=(l:Option[Language]) = l match {
    case None    => {}
    case Some(l) => setLanguage(l)
  }

  def setLanguage(l:Language) {
    lang = Some(l)
    //DO SOME OTHER THINGS
  }

  //DO LOTS OF OTHER THINGS
}

I haven't written any code that's using this framework yet but trying it in an interactive session revealed a type error I don't really understand:

scala> val l = new LanguageCreator("Languages.csv").getLanguage("English")
l: Option[Language] = Some(Language@7aeb46d)

scala> LanguageCentral.language=l                                         
<console>:23: error: type mismatch;
 found   : Option[Language]
 required: Option[Language]
       LanguageCentral.language=l
                                ^

scala> LanguageCentral setLanguage (l getOrElse null)                     
<console>:24: error: type mismatch;
 found   : Language
 required: Language
       LanguageCentral setLanguage (l getOrElse null)
                                      ^

I really don't have a clue what's wrong. But from my experience with Haskell I guess that the solution is only a minor change away.;)
Could somebody help me? Thx.

P.S.: using Scala 2.8.0.final

+2  A: 

To me it looks like there are two distinct Language classes defined. One way of that happening on REPL is like this:

class Language
class LanguageCreator // using Language
// Oops, there's something that needs fixing on Language
class Language
object LanguageCentral // refers to a different Language altogether

Outside REPL, they might just be in different packages. There's a way to make REPL print fully qualified types, but I couldn't find the incantation at the moment.

EDIT

From the compiler side, you may use -uniqid and -explaintypes to get better error messages. I always use the latter, in fact. If you can't understand them, please update your question with them, and I'll take a look at it. Also, -Xprint-types may be of use, though that's a lot of information, so I'd rather avoid it if possible.

Daniel
Just to be clear: I assume REPL is the interpreter?Language, LanguageCreator and LanguageCentral all reside in the same .scala File. With currently no package declaration around them and not importing anything except standard packages and the the Wrapper around opencsv (which, as I checked, does not declare a class Language). I have to run now but in 2 hours I'll do a project wide check and/or google for that REPL option. Thanks for your answer. Much appreciated.
Agl
Oh and just to be clear about that: Currently there is NO WRITTEN CODE TRYING TO DO WHAT I DID IN THE INTERPRETER. I still have to do that but it's very likely I'll run into the same error at compile time.
Agl
@Agl Yes, REPL is the "interpreter". It stands for read-eval-print loop, and it is more accurate than "interpreter" because Scala doesn't interpret code, just compiles it. I suggested it might be a problem that happened inside REPL because you have shown the errors as displayed from inside REPL.
Daniel
@Agl I haven't found the REPL option yet, but I updated the answer with some compiler options.
Daniel
@Agl Ok, found the option. It was rather easy, once I looked for it in the right place: `settings.unwrapStrings=false`. Unfortunately, it doesn't work as I expected, so you'll probably have better luck with the compiler parameters I suggested before.
Daniel
thx for the REPL explanation and for all the work! `-Xprint-types` was weird and caused a lot of errors. But `-uniqid` helped a lot. It changed the error to `found : Language#5` and `required: $iw#39927.$iw#39934.$iw#39940.$iw#39945.Language#39950`. Guess that means that IS another class right?
Agl
@Agl Looks like it. That thing with `$iw` is something for stuff defined on REPL itself, which would seem to indicate `Language` was defined inside REPL. So I have one question and a suggestion. The question is: what are you doing to execute this on REPL? And the suggestion is to paste the code to `LanguageCreator` on one of the many paste sites (pocoo, pastie, dpaste, ideone, etc) and put the link on the question. Something weird is happening...
Daniel
And a quick test you could do. Rename your `Language` to something else. If the problem still occurs but now with the new name, it is your code thats the problem. Otherwise it might be some `Language` defined in REPL as suggested above
svrist
sorry for keeping you waiting. The problem COULD be regarded as solved . . . although another question has come to the surface. First things first: renaming `Language` didn't help and before I posted the code of `LanguageCentral` to the web, I tried to change the order of `Language` and `LanguageCentral` (as I wrote somewhere else before I keep both classes in the same source file) so that `Language` comes first in the source...and that did the trick. Never thought that would matter. A bug maybe? And `Language` has an odd long type with lots of `$iw` in it. By the way `LanguageCentral` too.
Agl
@Agl Moving `Language` to before `LanguageCentral` will ensure that `Language` in `LanguageCentral` refers to that definition, and not some other definition of `Language` that happens to be present in the context. I think there is some `Language` definition available at that point. Do you have any imports?
Daniel
yes i do. But I tripple checked them... But I have clou what's happening here: I'm starting REPL with `scala -cp .:./lib/opencsv-2.2.jar -deprecation -i LanguageSupport.scala` with `.` being necessary to find the precompiled (!!) packages. BUT as it seems class files in the working directory get loaded into REPL even if I don't tell it to do so! So somewhere here the conflict came from. Removing `.` or the `Language.class` file (situated at the base directory since packages can't be loaded into REPL) or remove any other needed class files (like the `CSVParser`) caused REPL to complain.
Agl
The only 2 things that worked where: (A) altering the source file (as explained earlier or (B) putting all the Language stuff into it's final package and start REPL with `scala -cp .:./lib/opencsv-2.2.jar -deprecation` and load the needed packages in REPL. Now that I know it, it seems kind of obvious and I feel a little bit sorry for wasting your time. ;) Thanks a lot to both of you for your patience and guidance!
Agl