package owee

  1. Overview
  2. Docs

Module Owee_markerSource

A module to manually instrument values and implement dynamic services based on the actual type of these values.

The idea is to put a distinguished word, of type t marker in a value of type t. This module implements tools to generate and scan for such word, and execute functions based on the type recovered.

Manipulation of markers should be done with care: if the introspection find any value with the t marker word, it will incorrectly behave as if value was of type t.

The Safe_ functors ease manipulation of markers, at the cost of wrapping values. Use the Unsafe_ ones if you know what you are doing.

Dynamic services

Services are typed queries which can be executed on arbitrary ocaml objects. The query will succeed if:

  • object has a marker
  • this marker implements the type of service being requested.
Sourcetype 'result service = ..

The extensible type of dynamic services. Add your own services to the list and run queries at runtime without knowledge of the object type.

Think of this as an extensible list of methods (and of markers as a vtable for those methods).

Sourcetype service +=
  1. | Name : string service
    (*

    A user-friendly label for your object / class of objects

    *)
  2. | Traverse : ((Obj.t -> 'acc -> 'acc) -> 'acc -> 'acc) service
    (*

    Run a fold functions on object leafs, useful to traverse structure which are partially opaque.

    *)
  3. | Locate : Owee_location.t list service
    (*

    Return a list of locations relevant to the object

    *)
Sourcetype 'a service_result =
  1. | Success of 'a
    (*

    Object implements the service, here is your answer

    *)
  2. | Unsupported_service
    (*

    Service is not supported / unknown, but object is marked

    *)
  3. | Unmanaged_object
    (*

    No marker has been found on the object, you can't run any query on it 

    *)

Possible outcomes for the execution of a service

Manipulating objects

User API to work with marked objects.

Sourcetype 'a marked

Type of object marked with the safe interface

Sourceval get : 'a marked -> 'a
Sourceval query_service : 'a -> 'result service -> 'result service_result

Query an object for a service

Cycle detection

User API to work with graph of marked objects.

Sourcetype cycle

Type storing the state needed of traversal of marked OCaml object graphs

Sourceval start_cycle : unit -> cycle

Start a fresh cycle detector

Sourceval end_cycle : cycle -> unit

Release all ressources associated to the cycle. The cycle value should not be used after that.

Sourceval mark_seen : cycle -> Obj.t -> [ `Already_seen of int | `Now_seen of int | `Unmanaged ]

Mark an object as seen in a cycle. An integer uniquely identifying the object in this cycle is returned.

Sourceval seen : cycle -> Obj.t -> [ `Seen of int | `Not_seen | `Unmanaged ]

Was the object already seen during this traversal? If seen, the integer resulting from the call to mark_seen is returned.

Sourceval fresh_name : unit -> int

Generate a fresh name, guaranteed not to collide with results of mark_seen.

Marking objects

Implementor API.

Sourcemodule type T0 = sig ... end

The signature that needs to be implemented to add service support to your objects.

Safe api

Sourcemodule Safe0 (M : T0) : sig ... end

Unsafe api

Sourcetype 'a marker
Sourcemodule Unsafe0 (M : T0) : sig ... end
Sourcemodule type T1 = sig ... end
Sourcemodule type T2 = sig ... end
Sourcemodule type T3 = sig ... end
Sourcemodule Safe1 (M : T1) : sig ... end
Sourcemodule Safe2 (M : T2) : sig ... end
Sourcemodule Safe3 (M : T3) : sig ... end
Sourcemodule Unsafe1 (M : T1) : sig ... end
Sourcemodule Unsafe2 (M : T2) : sig ... end
Sourcemodule Unsafe3 (M : T3) : sig ... end
OCaml

Innovation. Community. Security.