# YAML and NArray

**URL:** <https://www.ruby-forum.com/t/yaml-and-narray/112417>\
**Category:** Ruby\
**Created:** [August 18, 2007, 4:58pm UTC](https://www.ruby-forum.com/t/yaml-and-narray/112417 "2007-08-18T16:58:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 18, 2007, 4:58pm UTC](https://www.ruby-forum.com/t/yaml-and-narray/112417/1 "2007-08-18T16:58:59Z")

</div>

In the past week, I’ve been exploring a little problem that by  
Wednesday I was ready to sit down and code. Now, the details of the  
problem aren’t important, but for this problem I was going to need to  
have objects that I could read from a file, manipulate a few hundred  
times, and then write back to a file.

Now, object serialization is not really what I’d consider “fun” stuff,  
so I figured “I’ll just throw YAML at it”. Unfortunately, my objects  
contained several NArray (and NMatrix and NVector) objects, and YAML  
initially serialized them as:

irb(main):002:0\> NArray.float(3,3).to\_yaml  
=\> “— !ruby/object:NArray {}\n\n”

Not helpful. Searching the web pulled up a ruby-talk message from a  
few years ago, but apparently the YAML api for defining your own YAML  
serialization has changed since then. Although this new API appears  
to be undocumented (at least, I couldn’t find any documentation), I  
did find a few blog posts in which people showed examples with other  
classes.

So anyway, I finally integrated YAML and NArray, and present the  
solution here for other people googling in the future on how to get  
these two to work together, as well as now for comment and criticism  
by current list subscribers. Note that it handles NArray, NMatrix,  
and NVector objects:

########## narray-yaml.rb #########  
require ‘yaml’  
require ‘narray’

# First, a yaml utility routine to make the output prettier

module YAML  
class YIArray \< Array  
yaml\_as “tag:yaml.org,2002:seq”  
def to\_yaml\_style; :inline; end  
end

def YAML.inline\_array(arr)  
if Array === arr[0] then  
arr.map {|s| inline\_array(s)}  
else  
YIArray.new.concat(arr)  
end  
end  
end

class NArray

# I used a tag of my own since I wasn’t sure if

# someone else had their own serialization of

# NArray objects

yaml\_as “tag:removed\_email\_address@domain.invalid,2007:narray”  
def to\_yaml( opts = {} )  
YAML::quick\_emit( self.object\_id, opts ) do |out|  
out.map(taguri) do |map|  
map.add(‘typecode’, typecode)  
map.add(‘shape’, YAML::inline\_array(shape))  
map.add(‘data’, YAML::inline\_array(to\_a))  
end  
end  
end

def self.yaml\_new(klass, tag, val)  
result = klass.new(val[‘typecode’], \*(val[‘shape’]))  
result[] = val[‘data’]  
result  
end  
end  
**END**

The result looks like this, for a 2 by 2 by 2 NArray:

— !removed\_email\_address@domain.invalid,2007/narray  
typecode: 5  
shape: [2, 2, 2]  
data: !seq:Array

- !seq:Array
  - [0.441292242643088, 0.463176002629107]
  - [0.602508503899103, 0.155671031769272]

- !seq:Array
  - [0.558707757356912, 0.536823997370893]
  - [0.397491496100897, 0.844328968230728]

So I’m pretty happy with the output format, but not happy with how  
long it took to get there, both in terms of the amount of code and in  
terms of the amount of time spent tracking stuff down, and the amount  
of time spent looking at documentation for the wrong API trying to  
figure out why my code wasn’t working.

Any suggestions on how to clean up my code, and any pointers to  
documentation I missed?

---

<div class="post-metadata">

**Author:** ![danmcb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/13edae/32.png) [@danmcb](https://www.ruby-forum.com/u/danmcb)\
**Post date:** [August 19, 2007, 3:46pm UTC](https://www.ruby-forum.com/t/yaml-and-narray/112417/2 "2007-08-19T15:46:26Z")

</div>

Daniel M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> So anyway, I finally integrated YAML and NArray, and present the  
> solution here for other people googling in the future on how to get  
> these two to work together, as well as now for comment and criticism  
> by current list subscribers. Note that it handles NArray, NMatrix,  
> and NVector objects:

And this is what I get for posting something other than the exact code  
I tested with. Apparently there’s a bug in Syck such that email-based  
tags are treated differently from dns-based tags. Unfortunately, I  
don’t own a domain name - fortunately, I know the guy who does own  
[snowplow.org](http://snowplow.org), and I’m pretty sure he’d be okay with me using the tag  
prefix shown below.

So here’s a fixed version. Note that it is the same as before, except  
that the private tag used in the yaml\_as line is different.

########## narray-yaml.rb #########  
require ‘yaml’  
require ‘narray’

# First, a yaml utility routine to make the output prettier

module YAML  
class YIArray \< Array  
yaml\_as “tag:yaml.org,2002:seq”  
def to\_yaml\_style; :inline; end  
end

def YAML.inline\_array(arr)  
if Array === arr[0] then  
arr.map {|s| inline\_array(s)}  
else  
YIArray.new.concat(arr)  
end  
end  
end

class NArray

# I used a tag of my own since I wasn’t sure if

# someone else had their own serialization of

# NArray objects

yaml\_as “tag:snowplow.org,2007:martin/narray”  
def to\_yaml( opts = {} )  
YAML::quick\_emit( self.object\_id, opts ) do |out|  
out.map(taguri) do |map|  
map.add(‘typecode’, typecode)  
map.add(‘shape’, YAML::inline\_array(shape))  
map.add(‘data’, YAML::inline\_array(to\_a))  
end  
end  
end

def self.yaml\_new(klass, tag, val)  
result = klass.new(val[‘typecode’], \*(val[‘shape’]))  
result[] = val[‘data’]  
result  
end  
end  
**END**

Hopefully this message will be found by people googling for how to  
integrate YAML and NArray.

I’m going to make this file available at  
[http://snowplow.org/martin/narray/](http://snowplow.org/martin/narray/)

along with standard verbiage up at the top placing it under some  
variant of the MIT license or the no-attribution BSD license.
