вторник, 15 октября 2013 г.

понедельник, 16 сентября 2013 г.

Readable string interpolation in Scala

Multiline strings in Scala have a well-known issue: they produce annoying leading whitespaces.
For example:
object MyApp extends App {
  val html = """
    <html>
      <body>
        <p>Lorem ipsum dolor sit amet...</p>
      </body>
    </html>
  """

  println(html)
}
Running this code produces:

····<html>
······<body>
········<p>Lorem ipsum dolor sit amet...</p>
······</body>
····</html>
··  
As you see, there are:
  • One extra line at the beginning
  • Unnecessary leading spaces before html markup
  • One extra line with two spaces at the end
This small library can solve this problem (inspired by Xtend template expressions). Everything you need is to put nice before your multiline string:
import com.github.orionll.scala.ReadableStringInterpolation._

object MyApp extends App {
  val html = nice"""
    <html>
      <body>
        <p>Lorem ipsum dolor sit amet...</p>
      </body>
    </html>
  """

  println(html)
}
Now this code produces:
<html>
  <body>
    <p>Lorem ipsum dolor sit amet...</p>
  </body>
</html>
nice also plays well with expressions inside strings:
import com.github.orionll.scala.ReadableStringInterpolation._

object MyApp extends App {
  val paragraphs = nice"""
    <p>line1</p>
    <p>line2</p>
  """

  val html = nice"""
    <html>
      <body>
        $paragraphs
      </body>
    </html>
  """

  println(html)
}
The output will be exactly you expect it to be:
<html>
  <body>
    <p>line1</p>
    <p>line2</p>
  </body>
</html>
(Now try to run this code with standard s instead of nice and compare the resulting mess with this)

понедельник, 12 августа 2013 г.

Implementing try-with-resources in Xtend

Java 7 and C# provide a convenient syntax that ensures the correct use of Closeable (IDisposable) objects. In Java 7 it is called try-with-resources. Here is an example of its usage (Java code):

try (Reader reader = new FileReader("file.txt")) {
  // do something with reader
}

Xtend does not provide this feature. However, you can implement it easily:

class Using {
  def static <T extends Closeable, R> R using(T resource, (T) => R proc) {
    // This is kept for a case when a Throwable from close()
    // overwrites a throwable from try
    var Throwable mainThrowable = null

    try {
      return proc.apply(resource)
    } catch (Throwable t) {
      mainThrowable = t
      throw t
    } finally {
      if (mainThrowable == null) {
        resource.close
      } else {
        try {
          resource.close
        } catch (Throwable unused) {
          // ignore because mainThrowable is present
        }
      }
    }
  }
}

This is sometimes called a loan pattern which is widely used in Scala. I use using as a method name, because try is a reserved keyword in Java and Xtend. The following example shows how to use the using statement:

import static org.example.xtend.Using.*

val text = using(new FileReader('file.txt')) [
  val buf = CharBuffer::allocate(1024// this is just an example
  it.read(buf)
  buf.rewind
  buf.toString
]

println(text)

One can use it keyword to refer to a passed instance of Closeable.
The nice feature is that using can also return a value. So, "Everything is an expression" principle works here as well.