Karlovsky120
Karlovsky120

Reputation: 6352

Scala Singleton not working as expected

Main.scala:

package controler

object Main {
    def main(args: Array[String]) {
      import Utilites._
      isJavaUpToDate
    }
}

Utilites.scala:

package controler

object Utilities {
  def isJavaUpToDate = { 
    val javaVersion = augmentString(System.getProperty("java.version").substring(2, 3))
    javaVersion >= 6 
  }
}

Why isn't this working? I have been trought a bunch of differenet tutorial sites where this works no problem.

I always says that val Utilites cannot be found.

P.S. Why does it keep sugesting me to change .toInt with augmentString() when it just breaks the code?

Now this gives me trouble, something about implicit ordering and method orderTOOrdered.

Upvotes: 1

Views: 233

Answers (2)

Paolo Falabella
Paolo Falabella

Reputation: 25844

Note that by calling augmentString you're explicitly transforming your string to a StringOps. StringOps does define a >= method, but it's meant to compare strings (its signature is def >=(that: String): Boolean )

If you want to compare Ints you should use the toInt method defined in StringOps.

def isJavaUpToDate = { 
    val javaVersion = augmentString(System.getProperty("java.version").substring(2, 3)).toInt
    javaVersion >= 6 
  }

Also, unless you need to disambiguate the toInt against another implicit that you defined (or is defined somewhere else in a library you're using) there should be no need to call augmentString explicitly. The following should just work (unless the compiler tells you it does not) and it should implicitly have the same effect as the code above of transforming your String to a StringOps.

def isJavaUpToDate = { 
    val javaVersion = System.getProperty("java.version").substring(2, 3)
    javaVersion.toInt >= 6 
  }

EDIT: as per @som-snytt's comment The error you're getting (No implicit Ordering defined for AnyVal) is due to the compiler reasoning more or less like this:

  • javaVersion >= 6 means javaVersion.>=(6), i.e. I must look for a method called >= on javaVersion that takes an integer
  • javaVersion is a StringOps... there is a >= method in StringOps (courtesy of the StringLike trait it's extending, that in turn extends Ordered[String]) but it takes a String argument, not an Int
  • let's see if I have an implicit in scope that supplies a suitable Ordering for StringOps. Now, since you're trying to compare a String with a Int you're looking at an Ordering that can compare two values with the nearest common ancestor that can contain both String and Int, i.e. AnyVal [EDIT: although String is an AnyRef so I don't really get this part...].
  • No luck there... give up with an error that says that no implicit Ordering was found comparing AnyVals

Upvotes: 2

fresskoma
fresskoma

Reputation: 25781

In your main method you've typed Utilites where you meant to type Utilities.

Correct: Utilities
Wrong:   Utilites

Note the missing i :) And because your brain is a powerful spelling correction tool, it pretended like the spelling was correct. The Scala compiler isn't as cool, though ;)


Also, for me, the following does not work:

scala> augmentString(System.getProperty("java.version").substring(2, 3)) >= 5
<console>:15: error: No implicit Ordering defined for AnyVal.
          augmentString(System.getProperty("java.version").substring(2, 3)) >= 5

Instead I replaced it with

System.getProperty("java.version").substring(2, 3)).toInt >= 5

The implicit ordering issue you experienced with the former code is because Scala does not know how to apply the >= method/operator to the type scala.collection.immutable.StringOps, which augmentString() returns.

Upvotes: 5

Related Questions