Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why XML literals yield mutable objects in Scala?

When declaring a node sequence in Scala as literals you yield a scala.xml.NodeBuffer which is mutable (it extends ArrayBuffer[scala.xml.Node] which in turn extends Seq[scala.xml.Node]):

scala> val xml = <a /><b />
xml: scala.xml.NodeBuffer = ArrayBuffer(<a></a>, <b></b>)

scala> xml += <c />
res46: xml.type = ArrayBuffer(<a></a>, <b></b>, <c></c>)

scala> xml
res47: scala.xml.NodeBuffer = ArrayBuffer(<a></a>, <b></b>, <c></c>)

This contradicts Scala's philosophy of using immutable objects and functional programming. Why collections are immutable by default, but XML literals (which are first class citizens) are not in this case?

However, is it possible to safely define an immutable node sequence by using XML literals?

like image 902
Calin-Andrei Burloiu Avatar asked Feb 15 '13 09:02

Calin-Andrei Burloiu


Video Answer


1 Answers

It seems that immutable XML literals require a single root node (as does XML). scala.xml.Group allows you to do this, using a "pacifier" root node of <xml:group />.

This is eloquently described in the API docs as "A hack to group XML nodes in one node for output."

scala> val xml = <xml:group><a /><b /></xml:group>
xml: scala.xml.Group = <a></a><b></b>

When you combine this fragment with other XML, the group node disappears:

scala> <foo>{xml}</foo>
res1: scala.xml.Elem = <foo><a></a><b></b></foo>
like image 106
Ben James Avatar answered Oct 10 '22 19:10

Ben James