<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LolocoJr &#187; scala</title>
	<atom:link href="http://www.railsguru.com/articles/category/scala/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.railsguru.com</link>
	<description>Andy Lo-A-Foe&#039;s blog</description>
	<lastBuildDate>Thu, 21 Jul 2011 13:31:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Scala scripting continued</title>
		<link>http://www.railsguru.com/articles/2009/07/13/scala-scripting-continued/</link>
		<comments>http://www.railsguru.com/articles/2009/07/13/scala-scripting-continued/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 13:08:45 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.railsguru.com/?p=4593</guid>
		<description><![CDATA[It took a day or two of blog reading and scala console try outs but I managed to create my first usable Scala script. import scala.xml._ /** Sequence number fix script. See http://fugamusic.com/docs/ingestion/ingestion.xsd **/ object FixSequence { var seq: List[Pair[Int,Int]] &#8230; <a href="http://www.railsguru.com/articles/2009/07/13/scala-scripting-continued/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It took a day or two of blog reading and scala console try outs but I managed to create my first usable Scala script.</p>
<pre class="brush:scala">
import scala.xml._

/**
  Sequence number fix script. See http://fugamusic.com/docs/ingestion/ingestion.xsd
**/

object FixSequence {
	var seq: List[Pair[Int,Int]] = List()
	var working_vol = 0

	def main(args: Array[String]) {
		val pp = new PrettyPrinter(80, 2)
		val fuga = XML.loadFile(args(0))(0)
		loadSeq(fuga)
		println(pp.format(fixSeq(fuga)))
	}

	def loadSeq(xml: Node) {
		for (t <- xml \ "tracks" \ "track")
			seq = ((t \ "on_disc" text).toInt, (t \ "sequence_number" text).toInt) :: seq
	}

	def maxSeq(vol:Int) = {
		seq.foldLeft(0){(s,v) => if(v._1 == vol &#038;&#038; v._2 > s) v._2 else s}
	}

	def maxVol: Int = {
		seq.foldLeft(0){(m,v) => if (v._1 > m) v._1 else m }
	}

	def baseVal(vol: Int): Int = {
		(for (t <- 1 to vol-1) yield maxSeq(t)).foldLeft(0) {_+_}
	}

	def fixSeq(xml: Node): Node = {
		def updateSeq(ns: Seq[Node]): Seq[Node] = {
			for (n <- ns) yield n match {
				case <on_disc>{ disc_nr }</on_disc> => {
					working_vol = disc_nr.text.toInt
					<on_disc>{ disc_nr }</on_disc>
				}
				case <sequence_number>{ seq_nr }</sequence_number> => {
					<sequence_number>{ seq_nr.text.toInt + baseVal(working_vol) }</sequence_number>
				}
				case Elem(prefix, label, attribs, scope, children @ _*) =>
					Elem(prefix, label, attribs, scope, updateSeq(children) : _*)
				case other => other
			}
		}
		updateSeq(xml.theSeq)(0)
	}
}

FixSequence.main(args)
</pre>
<p>While working on the script I rewrote several methods to be more Scala-like as I got more feeling for some of the functional traits of Scala. For instance the method:</p>
<pre class="brush:scala">
def baseVal(vol: Int): Int = {
	var base_val = 0
	for (t <- 1 to vol-1) base_val += maxSeq(t)
	base_val
}
</pre>
<p>was rewritten to be var'less:</p>
<pre class="brush:scala">
def baseVal(vol: Int): Int = {
	(for (t <- 1 to vol-1) yield maxSeq(t)).foldLeft(0) {_+_}
}
</pre>
<p>(the { } can even be omitted in this case). Thanks for the foldLeft tip <a href="http://log4p.com" target="_blank">p3t0r</a>!</p>
<p>But the hardest part was figuring out how to modify the XML structure in Scala without using DOM. Scala's XML support is quite amazing, especially the pattern matching and the ability to mix XML constructs with code!<br />
I did cheat a bit IMHO by keeping some of the state in a var while using the recursion to walk through the XML, but it seems to work quite well. See my <a href="http://www.railsguru.com/articles/2009/07/10/first-stab-at-scala-scripting-filters-do-not-work-like-my-ruby-brain-thinks-they-do/">previous post</a> for a problem description. Basically I need to modify the contents of the &lt;sequence_number&gt; based on the &lt;on_disc&gt; values. So first all (vol,sequence_number) pairs are parsed and based on the (max) values the &lt;sequence_numbers&gt; are modified.<br />
While thinking about it some more there is an issue where the script will break down if the &lt;on_disc&gt; comes after the &lt;sequence_number&gt; but this is not the case for the XML batch that needed fixing. That could be solved by doing a element lookup in the case match of &lt;sequence_number&gt;. Anyway, tastes like more.. So I'll definitely be doing more Scala coding.. I've already registered <a href="http://scalaguru.com">scalaguru.com</a>, so watch out! <img src='http://www.railsguru.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<div id="in_post_ad_bottom_1" style="clear:both;margin: 5px;padding: 0px;"><script type="text/javascript"><!--
google_ad_client = "pub-6322765154114793";
/* 300x250, created 7/3/11 */
google_ad_slot = "6228709946";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://www.railsguru.com/articles/2009/07/13/scala-scripting-continued/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>First stab at Scala scripting.. filters do not work like my Ruby brain thinks they do</title>
		<link>http://www.railsguru.com/articles/2009/07/10/first-stab-at-scala-scripting-filters-do-not-work-like-my-ruby-brain-thinks-they-do/</link>
		<comments>http://www.railsguru.com/articles/2009/07/10/first-stab-at-scala-scripting-filters-do-not-work-like-my-ruby-brain-thinks-they-do/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 15:36:23 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.railsguru.com/?p=4551</guid>
		<description><![CDATA[So I decided to pick up the Scala language. Having done Ruby for a couple of years now Scala is one of the few, if not the only language that&#8217;s gotten me excited. Being a first class citizen on the &#8230; <a href="http://www.railsguru.com/articles/2009/07/10/first-stab-at-scala-scripting-filters-do-not-work-like-my-ruby-brain-thinks-they-do/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I decided to pick up the Scala language. Having done Ruby for a couple of years now Scala is one of the few, if not the only language that&#8217;s gotten me excited. Being a first class citizen on the JVM has many advantages and I&#8217;m really liking <a href="http://liftweb.net">LiftWeb</a>.</p>
<p>I also suspect I&#8217;ll be doing a bit more Java related stuff in the very near future (stay tuned for that one <img src='http://www.railsguru.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ) so it&#8217;s a good idea to dive  into the J world again, and what better way then with Scala!</p>
<p>Problem definition: there is an issue with some XML files which came with a large batch ingest for one of our clients. In short there are a bunch of track elements in the XML which each element having a on_disc and sequence_number (think audio CDs) . However, the sequence_numbers should always be incremented e.g. if you have 2 tracks on disc 1 and 3 tracks on disc 2 the tracks on disc 2 should be have sequence numbers 3,4 and 5 respectively. The XML files we got have reset the sequence_number to 1 whenever a new disc begins.The fix is thus a simple matter of adding the highest sequence number of the previous disc to the sequence number of the current disc. Easy enough.</p>
<p>I tried to implement this in Scala and one of the helper methods calculates the highest sequence number of a given disc. This is the odd part though</p>
<pre class="brush:scala">
// The XML is first parsed to read all tracks
// These are stored in a tuple list
// Note the order of the tuples!
// Tuple values are (on_volume, sequence_number)

val sequence = List((1,2),(1,1),(2,1),(2,2),(2,3))

// Find the max value given a volume
def maxVal(vol: Int): Int = {
  var max = 1
  for (t <- sequence
    if t._1 == vol;
    if t._2 > max) max = t._2
 max
}

println(maxVal(1))
</pre>
<p>Now my Ruby brain would expect this to print out <b>2</b>, however when you run this code the result will be <b>1</b>! That&#8217;s because the filters are actually creating a new list before feeding that to for clause  so max is always 1 in the test. I did not expect this <img src='http://www.railsguru.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="in_post_ad_bottom_1" style="clear:both;margin: 5px;padding: 0px;"><script type="text/javascript"><!--
google_ad_client = "pub-6322765154114793";
/* 300x250, created 7/3/11 */
google_ad_slot = "6228709946";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://www.railsguru.com/articles/2009/07/10/first-stab-at-scala-scripting-filters-do-not-work-like-my-ruby-brain-thinks-they-do/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

