Re: porte des definitions / initialisation des variables de classe

From: Jerome Vouillon (Jerome.Vouillon@inria.fr)
Date: Wed Oct 07 1998 - 23:25:33 MET DST


Date: Wed, 7 Oct 1998 23:25:33 +0200
From: Jerome Vouillon <Jerome.Vouillon@inria.fr>
To: Serge Fantino <fantino@math.unice.fr>
Subject: Re: porte des definitions / initialisation des variables de classe
In-Reply-To: <361B6699.EFF02DF3@math.unice.fr>; from Serge Fantino on Wed, Oct 07, 1998 at 02:03:21PM +0100

On Wed, Oct 07, 1998 at 02:03:21PM +0100, Serge Fantino wrote:
> Bon. Je vais essayer de vous faire sentir ce qui me gene sur un exemple:
>
> class test1 =
> object
> val x = Random.int 1000
> method get = x
> end
>
> Je m'attends a ce que chaque nouvel objet cree a partir de test1 soit initialise
> avec une valeur différente pour x.
> En effet, l'initialisation est effectuee dans le corps de l'"object", elle ne
> devrait donc etre effectuee que lorsque j'instancie un nouvel objet.

Le contenu des enregistrements (dans le language de base) et des
structures (dans le langage de module) est évalué. Il me paraît donc
naturel que ce soit également le cas pour "object ... end" dans le
langage de classe.

> Actuellement, que ce passe-t-il ? Si je declare la classe test3:
>
> class test3 range =
> object
> val x = Random.int range
> method get = x
> end
>
> alors chaque nouvelle instance est initialisée avec une valeur
> différente de \ x, ie l'initialisation est effectuée au moment de
> l'instanciation.
>
> Si je declare maintenant:
> class test3_1000 = test3 1000;;
>
> il est logique de s'attendre a ce que test3_1000 soit une classe
> specialisée de test3, fonctionnant de facon similaire a test3. Les
> expressions suivantes devraient retourner des resultats similaires,
> ie des valeurs différentes <1000 pour chaque instance:
> let l1 = List.map (fun _ -> (new test3 1000)#get) [0;0;0;0]
> let l2 = List.map (fun _ -> (new test3_1000)#get) [0;0;0;0]
>
> Helas, la liste l2 repete la meme valeur... pourquoi ?

Je ne comprends pas trop pourquoi ce résultat te choque. Les arguments
que tu donnes pourraient tout aussi bien s'appliquer à l'exemple
suivant :

type t = { x : int }
let test3 range = { x = Random.int range }
let test3_1000 = test3 1000
let l1 = List.map (fun _ -> (test3 1000).x) [0;0;0;0]
let l2 = List.map (fun _ -> (test3_1000).x) [0;0;0;0]

En fait, je crois que ce qui apparaît comme pas très intuitif est
que deux objets puissent partager une même valeur mutable. Mais c'est
également le cas lorsque l'on utilise Oo.copy ou {< ... >}.

-- Jérôme



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:16 MET