Overloading the existing `toInt` method
Asked Answered
C

2

7

The toInt method in StringLike doesn't take any arguments, and can only parse in decimal. So to parse binary, hex etc we need to resort to Java's Integer#parseInt(String s, int radix).

In an attempt to remedy this state of affairs, I tried the following

implicit def strToToIntable(s: String) = new {
  def toInt(n: Int) = Integer.parseInt(s, n)
}

However,

"101".toInt(2)

causes the REPL compiler to "crash spectacularly" and doesn't work in compiled code either.

Is there some restriction on overloading existing methods using the "enrich my library" pattern?

Carbonation answered 27/10, 2011 at 19:29 Comment(3)
Are you sure your new tag, "pimping", is appropriate?Masto
@tomasz: if I got an upvote for every time I crashed the REPL, I'd have 100000 reputation by now..Lorrimor
A compiler crash is never* the result of bad code, only of bad compiler. Or, in other words, the bug is in the compiler. * Well, there's a few exceptions where, though the compiler really shouldn't crash, the code is not correct either.Freyah
G
3

Without the implicit, running "101".toInt(2) causes REPL to tell me that Int does not take parameters. So I guess what is happening is that it's running "101".toInt, then trying to call apply(2) on that, which doesn't make sense. I'd suggest a subtle rename of your pimped toInt to avoid the problem.

edit

I just had some success of my own. I explicitly defined a pimped string class as

class StrToRadixInt(s:String) {
  def toInt(radix: Int) = Integer.parseInt(s,radix)
}

implicit def strToToIntable(s:String) = new StrToRadixInt(s)

And REPL was happy:

scala> "101".toInt(2)
res4: Int = 5
Greathearted answered 27/10, 2011 at 20:5 Comment(2)
It seems that scala does not want to facilitate overloading methods via implicits: see #4480750 and #4444283Greathearted
The answer is in the links provided above, so accepting this oneCarbonation
C
1

The REPL shouldn't crash--that's a bug. But even so, overloading of names is somewhat discouraged and also not supported in some contexts. Just use a different name:

implicit def parseBase(s: String) = new { def base(b: Int) = Integer.parseInt(s,b) }

scala> "10110" base 2
res1: Int = 22
Cassatt answered 27/10, 2011 at 23:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.