YAML in limbo?

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?

···

--
Posted via http://www.ruby-forum.com/.

Ohad Lutzky wrote:

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.

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

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: )

···

--
Posted via http://www.ruby-forum.com/\.