How to write two dimensional array in xml in Scala 2.8.0

The following code (copied from the question about a year ago ) works fine under Scala 2.7.7, but does not behave correctly under Scala 2.8.0 (Beta 1, RC8).

import scala.xml

class Person(name : String, age : Int) {
    def toXml(): xml.Elem =
        <person><name>{ name }</name><age>{ age }</age></person>
}

def peopleToXml(people: Array[Person]): xml.Elem = {
    <people>{ for {person <- people} yield person.toXml }</people>
}

val data = Array(new Person("joe",40), new Person("mary", 35))

println(peopleToXml(data))

      

The output (according to 2.7.7) should be:

<people><person><name>joe</name><age>40</age></person><person><name>mary</name><age>35</age></person></people>

but instead it is issued as:

<people>\[Lscala.xml.Elem;@17821782</people>

How can I get myself to behave like in 2.7.x?

+2


a source to share


3 answers


This code requires two conversions. First, you need to convert Array[xml.Elem]

which is returned to understand for Seq[xml.Elem]

, and then the implicit conversion to xml.NodeSeq

converts that code to xml.NodeSeq

.

If you change peopleToXml

to the following, it works as expected:

def peopleToXml(people: Array[Person]): xml.Elem = {
  val a: Seq[xml.Elem] = for {person <- people} yield person.toXml
  <people>{a}</people>
}

      



You can also do the following if you like it :-)

def peopleToXml(people: Array[Person]): xml.Elem = {
  <people>{(for {person <- people} yield person.toXml): Seq[xml.Elem]}</people>
}

      

+3


a source


As pst says, the result is what you would expect from a real Java array. One of the changes between 2.7 and 2.8 is that Array[T]

it is now a real Java array. The new collection design means that performing Scala collection operations on a Java array (like map

in your example) will return a Java array as the result. This means that the following

for {person <- people} yield person.toXml

      

Used to not return a Java array, but now does. You can fix the problem by changing the type of people

your method argument peopleToXml

as follows:



def peopleToXml(people: Seq[Person]): xml.Elem = {
    <people>{ for {person <- people} yield person.toXml }</people>
}

      

This will mean that when you call this method with an argument Array

, the array will be implicitly converted to WrappedArray

, which behaves as you expect. This will also give you the ability to call this method with non-array-specific arrays.

+4


a source


The output returns a real Java array, which is a string according to normal Java rules. This is given by the output "[Ltype; @ref".

Perhaps you can convert it (people or result) to a list and improve the "semantics". I believe Scala 2.7.7 fully returns the collection type (not an array).

Fighting bit-rota with types talks about the new Scala 2.8 Setting up collections "in general" but not specifics. There might be more kindness on scala -lang.org and as always, welcome to visit # scala on freenode :-)

+1


a source







All Articles