16

See https://issues.scala-lang.org/browse/SI-5205 and https://github.com/scala/scala-dist/pull/20

Octal escape value leading 0 has been deprecated from scala and I don't see an idiomatic alternative.

How do you deal with octals in scala 2.10 now??

Edit - unix permissions are octal

JasonG
  • 5,794
  • 4
  • 39
  • 67
  • 2
    To quote [Seth Tisue](https://groups.google.com/d/msg/scala-debate/vG4tqdz1SgQ/DZ1Wbm8ZzNsJ): "Octal literals are horse-and-buggy stuff". Almost nobody uses them, and almost everyone has been bitten by the bizarre fact that e.g. `021 == 17`. – Travis Brown May 16 '13 at 14:45
  • 2
    unix permissions are octal – JasonG May 16 '13 at 14:47

3 Answers3

18

The literal syntax is gone (or going, I guess) and is unlikely to come back in any form, although alternatives like 0o700 have been proposed.

If you want something more like a compile-time literal in 2.10, you can use macros (this particular implementation is inspired by Macrocosm):

import scala.language.experimental.macros
import scala.reflect.macros.Context

object OctalLiterals {
  implicit class OctallerContext(sc: StringContext) {
    def o(): Int = macro oImpl
  }

  def oImpl(c: Context)(): c.Expr[Int] = {
    import c.universe._

    c.literal(c.prefix.tree match {
      case Apply(_, Apply(_, Literal(Constant(oct: String)) :: Nil) :: Nil) =>
        Integer.decode("0" + oct)
      case _ => c.abort(c.enclosingPosition, "Invalid octal literal.")
    })
  }
}

You can then write the following:

scala> import OctalLiterals._
import OctalLiterals._

scala> o"700"
res0: Int = 448

Now you don't pay for parsing the string at run time, and any invalid input gets caught at compile time.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • see my answer for an update as of Scala 2.11. I did not edit @Travis Brown's code to keep the Scala 2.10 version as requested by OP – jopasserat Jul 26 '15 at 11:54
  • this helps to use octal values but not handle values stored in csv for example or did I miss something ? – Kiwy Apr 01 '19 at 09:08
10

You can always BigInt("21",8) if you want to parse octal.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
  • And by assigning to a CONSTANT_VALUE (on an `object`, of course) your runtime overhead isn't a concern, and you've got some idea of what you're dealing with, and maybe even "why". – Richard Sitze May 17 '13 at 02:34
2

Here is an updated version of @Travis Brown's answer, as of Scala 2.11

import scala.reflect.macros.blackbox
import scala.language.experimental.macros

object OctalLiterals {
  implicit class OctallerContext(sc: StringContext) {
    def o(): Int = macro oImpl
  }

  def oImpl(c: blackbox.Context)(): c.Expr[Int] = {
    import c.universe._

    c.Expr(q"""${
      c.prefix.tree match {
        case Apply(_, Apply(_, Literal(Constant(oct: String)) :: Nil) :: Nil) ⇒
          Integer.decode("0" + oct).toInt
        case _ ⇒ c.abort(c.enclosingPosition, "Invalid octal literal.")
      }
    }""")
  }
}
jopasserat
  • 5,721
  • 4
  • 31
  • 50