YAML in limbo?


#1

When I was writing a simple DNS Sniffer/IDS (for a university project),
I wanted to be able to export DNS responses to YAML, for later
comparison (to detect spoofing). The IPAddr class was widely used within
the project - however, its YAML export looks like this:

irb(main):002:0> i = IPAddr.new(‘127.0.0.1’)
=> #<IPAddr: IPv4:127.0.0.1/255.255.255.255>
irb(main):003:0> y i
— !ruby/object:IPAddr
addr: 2130706433
family: 2
mask_addr: 340282366920938463463374607431768211455

After much effort, I figured out how to get it to export like this:

— !ruby/ipaddr 64.233.167.99

This was done with the following code:

class IPAddr
def to_yaml_type
“!ruby/ipaddr”
end
def to_yaml( opts = {} )
YAML::quick_emit(self.object_id, opts) { |out|
out << "#{to_yaml_type} "
self.to_s.to_yaml(:Emitter => out)
}
end
end

YAML.add_ruby_type(/^ipaddr/) { |type, val|
IPAddr.new(val)
}

This works just fine in Ruby 1.8.3 (Syck 0.45), but b0rks completely in
1.8.4 (Syck 0.6). The +out+ stream no longer has a << operator, and
there is a pretty obvious error in the add_ruby_type method, which seems
to be unused.

Now, _why says that the new version is much smarter about these kinds of
things, but the documentation is currently [even more] lacking [than the
previous versions’]. So my question splits into two parts:

  • How can I make my code work in the new version? (preferably
    backwards-compatibly)
  • What’s up with the docs?

#2

Ohad L. wrote:

 }

to be unused.

Here’s how you do it these days:

class IPAddr
yaml_as “tag:ruby.yaml.org,2002:ipaddr”
def to_yaml(opts = {})
YAML::quick_emit(object_id, opts) do |out|
out.scalar(taguri, self.value, :plain)
end
end
end

I started doing RDoc for everything. I keep forgetting to wrap it up.

_why


#3

why the lucky stiff wrote:

Here’s how you do it these days:

I started doing RDoc for everything. I keep forgetting to wrap it up.

_why

Much thanks. That IS simpler… how do I handle the importing though?

(BTW you rule dude :slight_smile: )