let bind f obj =
    let handlers =
      try
        Obj.obj (obj >>> get handlers_field >>> as_block)
      with Failure "as_block" ->
        (* first event handler *)
        let handlers = ref [] in
          obj >>> set handlers_field (inject (Block (Obj.repr handlers))) ;
          obj >>> set name
            (wrap_event
               (fun evt ->
                  let v =
                    try destruct evt with e ->
                      match default_value with
                        | Some v -> v
                        | None -> raise (Cannot_destruct e)
                  in
                    List.iter (fun f -> f v) !handlers)) ;
          handlers
    in handlers := f :: (List.filter ((!=) f) !handlers)