Below is code snippet that does some URL normalization. How to rewrite it to use immutable variables only?
Of course, without making it larger or more complex.
private def normalizeUrl(url0: String) = {
var url = url0
if (url.endsWith("/")) {
url = url.dropRight(1)
}
if (url.indexOf(':') < 0 ||
url.indexOf(':') == 1) { //windows absolute path
url = "file:" + url;
}
url = url.replaceAll("\\\\", "/");
url
}
If you wanted to chain a bunch of these if/then conditions together to modify a string you could consider adding an implicit class to handle the if/then evaluations like so:
object UrlPimping{
implicit class PimpedUrl(val url:String) extends AnyVal{
def changeIf(condition:String => Boolean)(f:String => String):String = {
if (condition(url)) f(url)
else url
}
}
}
private def normalizeUrl(url: String) = {
import UrlPimping._
url.
changeIf(_.endsWith("/"))(_.dropRight(1)).
changeIf(u => u.indexOf(':') < 0 || u.indexOf(':') == 1)(u => s"file:$u").
replaceAll("\\\\", "/")
}
This would be overkill if you only had these two conditions to evaluate, but might be nice if you had more and this was a common pattern.
Consider name of functional programming! The whole point is that you replace variables with functions.
private def normalizeProtocol(url: String) =
if (url.endsWith("/")) url.dropRight(1) else url
private def removeEndingSlash(url: String) =
if (url.indexOf(':') < 0 ||
url.indexOf(':') == 1) //windows absolute path
"file:" + url
else
url
private def replaceSlash(url: String) =
url.replaceAll("\\\\", "/");
private def normalizeUrl(url: String) =
replaceSlash(normalizeProtocol(removeEndingSlash(url)))
CM Baxter points out, the last function could also be written as
private val normalizeUrl =
removeEndingSlash _ andThen
normalizeProtocol andThen
replaceSlash
I leave it to you to decide which is more legible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With