Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] about Obj.magic
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@k...>
Subject: Re: [Caml-list] about Obj.magic
From: "Warp" <warplayer@free.fr>

> > So, we should be very careful to use 'Obj.magic'. Can somebody tell me
> > the appropriate situation to use this function?
> 
> One case can be 'almost-legal' : downcasting an object to its implementation
> class if you're sure that it has been previously upcasted to the interface
> type class.
> 
> (* MLI file *)
> 
> class type intf =
>   sig
>     method a : unit
>   end
> 
> val new_intf : intf -> intf
> 
> (* ML file *)
> 
> class impl parent =
>   object
>     method a = ....
>     method b = ....
>   end
> 
> let new_intf i = (new impl (Obj.magic i : impl) :> intf) (* upcast impl to
> intf in order to hide method 'b' *)

And here is how to break your code:

class c = object method a : unit end
let i = new_intf (new c)

No, this is not legal in any way.
You shouldn't use Obj.magic, except if you have a formal proof that it
is correct! This supposes a deep knowledge of the type system.

By the way, here is a simple way to do downcasts, when really needed.

# let tbl : (< >, impl) Hashtbl.t = Hashtbl.create 17
  let register obj = Hashtbl.add tbl (obj :> < >) obj
  let recover obj = Hashtbl.find tbl (obj :> < >) ;;
val tbl : (<  >, impl) Hashtbl.t = <abstr>
val register : impl -> unit = <fun>
val recover : < .. > -> impl = <fun>

If you register all objects of class impl, then you can use recover to
get back their original type. If the class is not impl, you will get
an exception rather than a segmentation fault. No need to do anything
unsafe.

Jacques Garrigue
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners