[comp.lang.eiffel] global objects

wsineel@lso.win.tue.nl (e.vriezekolk) (02/20/90)

We are working on a small Eiffel project, but we don't have
a local Eiffel expert overhere...

We want to define some classes, and create only one object of
each class. The object names must be global, so that they can
be used in all the class definitions and all refer to the same
(only one) object. Each object must be able to call routines
of any other object.
I realize that this conflicts with the pure object oriented
principle, but it seems to be necessary in our project.

Can anyone help us out? Are such global object possible in
Eiffel?

Eelco Vriezekolk: wsineel@lso.win.tue.nl

sakkinen@tukki.jyu.fi (Markku Sakkinen) (02/21/90)

In article <925@tuewsd.lso.win.tue.nl> wsineel@lso.win.tue.nl (e.vriezekolk) writes:
>
>We want to define some classes, and create only one object of
>each class. The object names must be global, so that they can
> ...
>I realize that this conflicts with the pure object oriented
>principle, but it seems to be necessary in our project.

I cannot see any necessary conflict: there can well be useful and
"natural" classes such that they always have exactly one instance.
(That's one of the main reasons why some people claim prototype-based
object models to be better than class-based ones.)
If your design truly abounds with such classes, then its object
orientation may be questionable.

>Can anyone help us out? Are such global object possible in
>Eiffel?
> ...

The largest part of your problem can probably be solved by
"once functions" (OOSC 13.3). Some Eiffel expert please suggest
an elegant way to inhibit creating additional instances of
those classes.

Markku Sakkinen
Department of Computer Science
University of Jyvaskyla (a's with umlauts)
Seminaarinkatu 15
SF-40100 Jyvaskyla (umlauts again)
Finland
          SAKKINEN@FINJYU.bitnet (alternative network address)

stephan@eiffel.UUCP (Philippe Stephan) (02/22/90)

In article <925@tuewsd.lso.win.tue.nl>, Eelco Vriezekolk asks:

> We want to define some classes, and create only one object of each
> class. The object names must be global, so that they can be used
> in all the class definitions and all refer to the same only one)
> object. Each object must be able to call routines of any other
> object.

   Assume that you want to define classes A, B, C, and create
only one object of each, the name of the objects being global.

   The general solution is to make all your classes inherit from a
class PARENT (or use class HERE) where you declare:

   a: A is once Result.Create end;
   b: B is once Result.Create end;
   c: C is once Result.Create end

   However:

   1) You have to be careful not to generate any creation
loop calling some of these once functions in the creation routines
of class A, B and C, e.g. do NOT use:

   class A inherit PARENT feature create is do foo (b) end end
   class B inherit PARENT feature create is do bar (a) end end

   2) Another problem with this is that if you want arguments in
the creation routines of classes A, B and C, you need them to be
shared, i.e accessible from class PARENT, which has probably nothing
else to do with them.

   In order to avoid this clumsiness, use something like:

in class PARENT:

   a: A is once Result := aa end;
   aa: A is deferred end;
   (aa: A is do end;)

in class INIT_A:

   class INIT_A
	  inherit
	     PARENT
			(redefine aa)
	  feature
	     Create is do
	        aa := a_initialized (arguments);
	        foo (a)
            -- The first call to ``a'' sets it for good.
	     end;
         a_initialized (...): A is
	            -- Instance of A, initialized with ``arguments''.
            do
            ...
            end;
	     aa: A
                -- (Re)defined as an attribute
      end

   As you have guessed, the programmer has to take care, in this
case, to create an instance of INIT_A at the right time, in order
to properly set the reference ``a'', which would always be void
if called before that.

Hoping this helps,

-- Philippe Stephan
-- stephan@eiffel.com

wsttss@lso.win.tue.nl (Steven van der Smagt) (02/22/90)

In article <3477@tukki.jyu.fi> sakkinen@jytko.jyu.fi (Markku Sakkinen) writes:
>
>>Can anyone help us out? Are such global object possible in
>>Eiffel?
>> ...
>
>The largest part of your problem can probably be solved by
>"once functions" (OOSC 13.3). Some Eiffel expert please suggest
>an elegant way to inhibit creating additional instances of
>those classes.
>

Gary Wright proposed an 'elegant' solution to inherit from a class 
Global:

>Create a class that contains only once functions (let's call the class GLOBAL).
>Each function in GLOBAL returns a reference to a shared object.  So
>in GLOBAL you would have:

features
	obj1 : CLASS1 is
	once
			Result.Create;
		end;

	obj2 : CLASS2 is
		once
			Result.Create;
		end;
	...

>For every class that needs access to these shared objects, inherit
>from GLOBAL.  If you anticipate almost every object needing access
>to objects in GLOBAL, then put your feature definitions in HERE instead
>of GLOBAL.  By definition every class inherits from HERE so you don't
>need to do anything special in you classes in order to obtain 
>access to the shared objects.

Using the once mechanism to obtain shared objects, depends on
the knowledge how Eiffel is implemented. Eiffel creates 
multiple instances of attributes, but only one
(shared) instance of the methods.
This confusion arises
because of the 'natural' side effects of methods on the
attributes of the object: you do not specify the attributes of
an object as a parameter when you call a method.

Isn't more logical to use the following syntax:
	method(object.attribute)
instead of
	object.method

Steven van der Smagt	wsttss@lso.win.tue.nl
Eelco Vriezekolk		wsineel@lso.win.tue.nl

jos@cs.vu.nl (Jos Warmer) (02/22/90)

wsttss@lso.win.tue.nl (Steven van der Smagt) writes:

>In article <3477@tukki.jyu.fi> sakkinen@jytko.jyu.fi (Markku Sakkinen) writes:
	
>>>Can anyone help us out? Are such global object possible in Eiffel?

>Gary Wright proposed an 'elegant' solution to inherit from a class Global:

>>Create a class that contains only once functions (let's call the class GLOBAL).

>Using the once mechanism to obtain shared objects, depends on
>the knowledge how Eiffel is implemented. Eiffel creates 
>multiple instances of attributes, but only one
>(shared) instance of the methods.

This has nothing to do with the implementation, but everything with the
definition of Eiffel.
(Of course, the definition has to be implemented |-:) )

A once function is not just a method. If it was, the Result would
be created each time the method was called. This is not what is intended.
Gary is right, once functions are THE way to create shared objects.
See OOSC for more details.

>This confusion arises
>because of the 'natural' side effects of methods on the
>attributes of the object: you do not specify the attributes of
>an object as a parameter when you call a method.

>Isn't more logical to use the following syntax:
>	method(object.attribute)
>instead of
>	object.method

Why? A method is called on an object, not on an attribute of an object.

                                 Jos Warmer
				 jos@cs.vu.nl
				 ...uunet!mcvax!cs.vu.nl!jos
--
                                 Jos Warmer
				 jos@cs.vu.nl
				 ...uunet!mcvax!cs.vu.nl!jos