Last active
December 14, 2016 08:05
-
-
Save maasg/dc9712eb6221be536e93f1927ddacd9c to your computer and use it in GitHub Desktop.
Idiomatic try/catch in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "metadata": { | |
| "name": "StreamPrinter", | |
| "user_save_timestamp": "1970-01-01T01:00:00.000Z", | |
| "auto_save_timestamp": "1970-01-01T01:00:00.000Z", | |
| "language_info": { | |
| "name": "scala", | |
| "file_extension": "scala", | |
| "codemirror_mode": "text/x-scala" | |
| }, | |
| "trusted": true, | |
| "customLocalRepo": null, | |
| "customRepos": null, | |
| "customDeps": null, | |
| "customImports": null, | |
| "customArgs": null, | |
| "customSparkConf": null | |
| }, | |
| "cells": [ | |
| { | |
| "metadata": { | |
| "id": "961A49B1A51943E483905702B5A07BCE" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "created with the [Spark Notebook](http://spark-notebook.io)" | |
| }, | |
| { | |
| "metadata": { | |
| "id": "76EC80764DD042A78AC30191B5ACF1FF" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "# Idiomatic way of handling a resource\nAnd closing resources after use, in good and bad times" | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true, | |
| "input_collapsed": false, | |
| "collapsed": false, | |
| "id": "A8FD796E38FC4C85B3053CA8F4DED0BC" | |
| }, | |
| "cell_type": "code", | |
| "source": "import scala.util.Try\nimport java.io._\nimport scala.io.Source", | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": "import scala.util.Try\nimport java.io._\nimport scala.io.Source\n" | |
| }, | |
| { | |
| "metadata": {}, | |
| "data": { | |
| "text/html": "" | |
| }, | |
| "output_type": "execute_result", | |
| "execution_count": 46, | |
| "time": "Took: 362 milliseconds, at 2016-12-14 9:1" | |
| } | |
| ] | |
| }, | |
| { | |
| "metadata": { | |
| "id": "0FB87676AA634923AFB9C778919C7C50" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "### Modified version of safeFilePrint, with added \"println\" to get hints of the execution paths" | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true, | |
| "input_collapsed": false, | |
| "collapsed": false, | |
| "id": "CEB8110F704E4EC79759227D1B9AAB09" | |
| }, | |
| "cell_type": "code", | |
| "source": "def safeFilePrint(tf: => OutputStream)(op: PrintWriter => Unit): Try[Unit] = {\n val os = Try(tf) \n val write = {\n val writer = os.map(f => new PrintWriter(f))\n val writeOp = writer.map{w => \n println(\"writing to stream\")\n op(w)}\n val flush = writer.map(_.flush)\n writeOp.flatMap(_=> flush)\n }\n val close = os.map{stream =>\n println(\"closing stream\")\n stream.close} \n \n write.flatMap(_ => close)\n}", | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": "safeFilePrint: (tf: => java.io.OutputStream)(op: java.io.PrintWriter => Unit)scala.util.Try[Unit]\n" | |
| }, | |
| { | |
| "metadata": {}, | |
| "data": { | |
| "text/html": "" | |
| }, | |
| "output_type": "execute_result", | |
| "execution_count": 47, | |
| "time": "Took: 297 milliseconds, at 2016-12-14 9:1" | |
| } | |
| ] | |
| }, | |
| { | |
| "metadata": { | |
| "id": "B9090044AB984CC99329931BAAE2C8FC" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "### Happy writing" | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true, | |
| "input_collapsed": false, | |
| "collapsed": false, | |
| "id": "BC18FA01A9D0424EABB92178F625A66B" | |
| }, | |
| "cell_type": "code", | |
| "source": "safeFilePrint(new FileOutputStream(new File(\"/tmp/fo-test\"))){writer => \n (1 to 17).foreach(i => writer.print(s\"record $i\"))\n}", | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": "writing to stream\nclosing stream\nres87: scala.util.Try[Unit] = Success(())\n" | |
| }, | |
| { | |
| "metadata": {}, | |
| "data": { | |
| "text/html": "Success(())" | |
| }, | |
| "output_type": "execute_result", | |
| "execution_count": 53, | |
| "time": "Took: 341 milliseconds, at 2016-12-14 9:1" | |
| } | |
| ] | |
| }, | |
| { | |
| "metadata": { | |
| "id": "A7247BA3DC9E439D9FBEE099C3FC49CC" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "Did we actually write anything?" | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true, | |
| "input_collapsed": false, | |
| "collapsed": false, | |
| "id": "10C513DC928F46D9938B75EA067CD429" | |
| }, | |
| "cell_type": "code", | |
| "source": "Source.fromFile(\"/tmp/fo-test\").getLines.mkString", | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": "res89: String = record 1record 2record 3record 4record 5record 6record 7record 8record 9record 10record 11record 12record 13record 14record 15record 16record 17\n" | |
| }, | |
| { | |
| "metadata": {}, | |
| "data": { | |
| "text/html": "record 1record 2record 3record 4record 5record 6record 7record 8record 9record 10record 11record 12record 13record 14record 15record 16record 17" | |
| }, | |
| "output_type": "execute_result", | |
| "execution_count": 54, | |
| "time": "Took: 408 milliseconds, at 2016-12-14 9:1" | |
| } | |
| ] | |
| }, | |
| { | |
| "metadata": { | |
| "id": "CAFD5CBED74640B0810F6379EB15EB3F" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "## Exception while writing\nNote how the file is closed even in the event of an exception while writing" | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true, | |
| "input_collapsed": false, | |
| "collapsed": false, | |
| "id": "58EC0172EAF8443193147034AE5E35EE" | |
| }, | |
| "cell_type": "code", | |
| "source": "safeFilePrint(new FileOutputStream(new File(\"/tmp/bar-test\"))){writer => \n throw new RuntimeException(\"boem, nothing here\")\n}", | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": "writing to stream\nclosing stream\nres91: scala.util.Try[Unit] = Failure(java.lang.RuntimeException: boem, nothing here)\n" | |
| }, | |
| { | |
| "metadata": {}, | |
| "data": { | |
| "text/html": "Failure(java.lang.RuntimeException: boem, nothing here)" | |
| }, | |
| "output_type": "execute_result", | |
| "execution_count": 55, | |
| "time": "Took: 322 milliseconds, at 2016-12-14 9:1" | |
| } | |
| ] | |
| }, | |
| { | |
| "metadata": { | |
| "id": "E6DDE8CD43DD419D88DC8C8E80D660D2" | |
| }, | |
| "cell_type": "markdown", | |
| "source": "## Exception while creating the stream\nIn this case, we have no stream, so we do nothing more than return the failure" | |
| }, | |
| { | |
| "metadata": { | |
| "trusted": true, | |
| "input_collapsed": false, | |
| "collapsed": false, | |
| "id": "FB1AD537A1DF49419A5F4F3EFDE4D59F" | |
| }, | |
| "cell_type": "code", | |
| "source": "safeFilePrint(throw new RuntimeException(\"Sorry, no streaming on this wall\")){_.write(\"pee\")}", | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": "res93: scala.util.Try[Unit] = Failure(java.lang.RuntimeException: Sorry, no streaming on this wall)\n" | |
| }, | |
| { | |
| "metadata": {}, | |
| "data": { | |
| "text/html": "Failure(java.lang.RuntimeException: Sorry, no streaming on this wall)" | |
| }, | |
| "output_type": "execute_result", | |
| "execution_count": 56, | |
| "time": "Took: 321 milliseconds, at 2016-12-14 9:1" | |
| } | |
| ] | |
| } | |
| ], | |
| "nbformat": 4 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment