[comp.lang.eiffel] Global object question

greg@ee.tamu.edu (Greg Economides) (12/01/90)

I am unable to get mail to go to "rick@tetrauk.uucp" -- it bounces back.  So
I am posting this question for Rick Jones regarding his recent posting.  If anyone
else can answer my question, feel free to do so.


Rick,

Addressing the subject of global objects in Eiffel, you posted a message to the net
a while back.  The topic is of interest to me, so I hope you can take a moment
to clarify the idea that you presented for me.

You gave the following example of a "global" class:

class DEFS

feature

        Const1: INTEGER is 1 ;
        Const2: INTEGER is 2 ;
        Const3: INTEGER is 3 ;

        -- etc ...

        foo: FOO is    -- I assume you meant "foo: DEFS is" here (greg)
        once
                Result.Create ;
        end ;

        -- etc ...
end


And then wrote:

Hence any class which inherits from DEFS can refer to foo as an attribute of
the Current object, and all classes will share only one instance.  In a large
system it may be appropriate to have multiple definition classes, each
concerned with a particular group of cooperating classes which can be treated
as a subsystem.

====================
My question is, do you imply here that (since foo returns type DEFS) 
in the classes that inherit from DEFS there should be a statement of the form:

globals: DEFS;

...

globals := foo;

And then when we want to access the global objects, we do a call such as:

globals.Const1

(which would imply that Const? and other globals would have to be exported)?

Or is this scenario supposed to be used in another fashion?

Peace,

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Greg Economides             Internet:  greg@zadok.tamu.edu
Texas A&M University                   greg@eemips.tamu.edu

"This sentence is false"

--
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Greg Economides             Internet:  greg@zadok.tamu.edu
Texas A&M University                   greg@eemips.tamu.edu

rick@tetrauk.UUCP (Rick Jones) (12/03/90)

In article <10538@helios.TAMU.EDU> greg@ee.tamu.edu (Greg Economides) writes:
>
>Addressing the subject of global objects in Eiffel, you posted a message to the net
>a while back.  The topic is of interest to me, so I hope you can take a moment
>to clarify the idea that you presented for me.

I'll answer this publicly since it may well be of interest to others.

>You gave the following example of a "global" class:
>
>class DEFS
>
>feature
>
>        Const1: INTEGER is 1 ;
>        Const2: INTEGER is 2 ;
>        Const3: INTEGER is 3 ;
>
>        -- etc ...
>
>        foo: FOO is    -- I assume you meant "foo: DEFS is" here (greg)
						    ^^^^
	No I didn't, I meant what I wrote!

>        once
>                Result.Create ;
>        end ;
>
>        -- etc ...
>end

The rest of your confusion results from your incorrect assumption above.  The
purpose of the DEFS class is to be inherited from, NOT to be instantiated.  FOO
is a completely different class with no direct connection with DEFS at all.
What we want, system-wide, is one single instance of a FOO object accessible by
potentially any class in the system.  The DEFS class provides the mechanism for
doing this.

If all classes which need access to the global FOO _inherit_ from DEFS, then
they can all refer to "foo" (the instance of FOO) as a local attribute.  Since
"foo" is the result of a once function, it has the same value in every instance
of every class which inherits from DEFS;  in other words, in all instances the
reference to "foo" is a reference to the same object.  The code will simply be
of the form:

	foo.some_feature  ;

In my example, the values Const1, etc have no direct connection with FOO, they
are just examples of global constants, while FOO is an example of a global
object.

Part of the difficulty is, I think, getting used to the fact that inheritance
in Eiffel can be used for a variety of different puposes, and with multiple
inheritance it can be used for different reasons within the same class.  The
two "classic" reasons for inheritance are to inherit either abstraction or
implementation (or both), but here its use is more akin to the C concept
"#include", or equivalent mechanisms in other languages.  I sometimes feel
uneasy that the notion of inheritance is being misused, but I can't see any
practical reason for having a separate mechanism when the present one actually
works - quite elegantly as well!

If you have now grasped the above idea, you are licensed to read on :-)

This example of a global reference does not allow the actual object to be
changed.  Its contents or state may be changed if the class FOO provides the
necessary features, but sometimes it is useful to be able to have a single
global reference to a single object, but where the actual object can be
replaced by a new instance by any of the classes which refer to it.  This can
in fact be achieved very easily by using the Eiffel library class CELL.  A CELL
object is effectively a "pointer" to some other object - CELL is a generic
class having two features, "put" & "item".  Its use for this purpose in a class
such as DEFS would be:

	foo_ref: CELL [FOO] is
	local
		foo: FOO ;
	once
		foo.Create ;
		Result.Create ;
		Result.put (foo) ;
	end ;

The first active reference to foo_ref creates the cell and fills it with a FOO
object.  Any inheriting class can get at the global FOO by using:

	foo_ref.item ;		-- function returning a FOO object

If a class wishes to change the global object it will have to do something
like:

	local
		noo_foo: FOO ;
	do
		noo_foo.Create ;
		foo_ref.put (noo_foo) ;
		...

This technique can also solve the problem of a global value of a basic type,
where the value can only be determined at run-time.  A CELL [INTEGER] for
example can be used.

I hope this helps,
Regards -
-- 
Rick Jones
Tetra Ltd.  Maidenhead, 	Was it something important?  Maybe not
Berks, UK			What was it you wanted?  Tell me again I forgot
rick@tetrauk.uucp					-- Bob Dylan