Custom yaml deserializing with psych

Hello to everyone,
I'm trying to convert my program from using syck to using psych. In my program,
I use yaml to store user settings to a file and read them back. Unfortunately,
some of these settings correspond to objects defined in a C extension (Qtruby).

For example, let's take the Qt::Point class, which represents a point with two
coordinates, x and y. With syck I could serialize and deserialize it using yaml
with the following code:

class Qt::Point

yaml_as "tag:ruby.yaml.org,2002:Qt::Point"
    
  def self.yaml_new cls, tag, val
    x, y= val['x'], val['y']
    Qt::Point.new(x, y)
  end
  
  def to_yaml opts = {}
    YAML.quick_emit(self, opts) do |out|
      out.map(taguri, to_yaml_style) do |map|
        map.add 'x', self.x
        map.add 'y', self.y
      end
    end
  end

end

With psych, however, things get more complicated. For serializing, I did the
following:

class Qt::Point

  def encode_with coder
    coder['x'] = self.x
    coder['y'] = self.y
  end

end

This correctly serializes a Qt::Point:

puts YAML.dump(Qt::Point.new 2, 3)
=> --- !ruby/object:Qt::Point
x: 2
y: 3

To deserialize this object, I tried defining the corresponding decode_with
method:

class Qt::Point

  def init_with coder
    self.x = coder['x']
    self.y = coder['y']
  end

end

However, this doesn't work, as the program crashes with a segmentation fault in
the first line of init_with. Looking at the source code for psych, it seems that
to deserialize such an object (which yaml sees as a mappgin), the method
Psych::Visitors::ToRuby#visit_Psych_Nodes_Mapping is used. In turn, this method
calls Psych::Visitors::ToRuby#revive with the corresponding class (in this case,
Qt::Point). revive then calls Qt::Point.allocate, followed by
Qt::Point#init_with.

Here lies the problem. As far as I understand, QtRuby doesn't use the usual way
to instantiate objects from its classes (allocate followed by initialize or
analogous methods, such as init_with) and doesn't define an allocate method for
them. This means that when Qt::Point.allocate is called, it calls
Class.allocate which, of course, knows nothing of QtRuby internals and of how
correctly allocate a QtRuby instance. Obviously, as soon as I try to call one of
Qt::Point's instance method for the incorrectly allocated instances, ruby
crashes.

It seems that this issue can be solved if I manually define Qt::Point.allocate
having return an instance created by Qt::Point.new (this doesn't cause an
endless recursion because Qt::Point.new *doesn't* call allocate):

class Qt::Point

  def self.allocate
    new
  end

end

However, I was wandering if Psych didn't offer a better way to define a custom
way of deserializing an instance. Does anyone know of one?

Sorry for the long mail.

Thanks in advance

Stefano