docs: def write_object_array(f, data, options):
      """ Writes an array of objects recursively.
  
      Writes the elements of the given object array recursively in the
      HDF5 Group ``options.group_for_references`` and returns an
      ``h5py.Reference`` array to all the elements.
  
      Parameters
      ----------
      f : h5py.File
          The HDF5 file handle that is open.
      data : numpy.ndarray of objects
          Numpy object array to write the elements of.
      options : hdf5storage.core.Options
          hdf5storage options object.
  
      Returns
      -------
      obj_array : numpy.ndarray of h5py.Reference
          A reference array pointing to all the elements written to the
          HDF5 file. For those that couldn't be written, the respective
          element points to the canonical empty.
  
      Raises
      ------
      TypeNotMatlabCompatibleError
          If writing a type not compatible with MATLAB and
          `options.action_for_matlab_incompatible` is set to ``'error'``.
  
      See Also
      --------
      read_object_array
      hdf5storage.Options.group_for_references
      h5py.Reference
  
      """
      # We need to grab the special reference dtype and make an empty
      # array to store all the references in.
      ref_dtype = h5py.special_dtype(ref=h5py.Reference)
      data_refs = np.zeros(shape=data.shape, dtype='object')
  
      # We need to make sure that the group to hold references is present,
      # and create it if it isn't.
  
      if options.group_for_references not in f:
          f.create_group(options.group_for_references)
  
      grp2 = f[options.group_for_references]
  
      if not isinstance(grp2, h5py.Group):
          del f[options.group_for_references]
          f.create_group(options.group_for_references)
          grp2 = f[options.group_for_references]
  
      # The Dataset 'a' needs to be present as the canonical empty. It is
      # just and np.uint32/64([0, 0]) with its a MATLAB_class of
      # 'canonical empty' and the 'MATLAB_empty' attribute set. If it
      # isn't present or is incorrectly formatted, it is created
      # truncating anything previously there.
      try:
          dset_a = grp2['a']
          if dset_a.shape != (2,) \
                  or not dset_a.dtype.name.startswith('uint') \
                  or np.any(dset_a[...] != np.uint64([0, 0])) \
                  or get_attribute_string(dset_a, 'MATLAB_class') != \
                  'canonical empty' \
                  or get_attribute(dset_a, 'MATLAB_empty') != 1:
              del grp2['a']
              dset_a = grp2.create_dataset('a', data=np.uint64([0, 0]))
              set_attribute_string(dset_a, 'MATLAB_class',
                                   'canonical empty')
              set_attribute(dset_a, 'MATLAB_empty',
                            np.uint8(1))
      except:
          dset_a = grp2.create_dataset('a', data=np.uint64([0, 0]))
          set_attribute_string(dset_a, 'MATLAB_class',
                               'canonical empty')
          set_attribute(dset_a, 'MATLAB_empty',
                        np.uint8(1))
  
      # Go through all the elements of data and write them, gabbing their
      # references and putting them in data_refs. They will be put in
      # group_for_references, which is also what the H5PATH needs to be
      # set to if we are doing MATLAB compatibility (otherwise, the
      # attribute needs to be deleted). If an element can't be written
      # (doing matlab compatibility, but it isn't compatible with matlab
      # and action_for_matlab_incompatible option is True), the reference
      # to the canonical empty will be used for the reference array to
      # point to.
      grp2name = grp2.name
      for index, x in np.ndenumerate(data):
          name_for_ref = next_unused_name_in_group(grp2, 16)
          write_data(f, grp2, name_for_ref, x, None, options)
          try:
              dset = grp2[name_for_ref]
              data_refs[index] = dset.ref
              if options.matlab_compatible:
                  set_attribute_string(dset,
                                       'H5PATH', grp2name)
              else:
                  del_attribute(dset, 'H5PATH')
          except:
              data_refs[index] = dset_a.ref
  
      # Now, the dtype needs to be changed to the reference type and the
      # whole thing copied over to data_to_store.
      return data_refs.astype(ref_dtype).copy()