help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: EIEIO built in methods -- question


From: David Engster
Subject: Re: EIEIO built in methods -- question
Date: Wed, 12 Jun 2013 17:44:24 +0200
User-agent: Gnus/5.130008 (Ma Gnus v0.8) Emacs/24.3 (gnu/linux)

Eric Abrahamsen writes:
> This discussion went over my head pretty fast! In my case I don't think
> I need to worry about the behavior of `class-of', I was just looking to
> tie some code into the creation of an object instance. 

Since you want to meddle with the actual creation of objects, I'm afraid
the issues Pascal mentions are at the core of the problems you're
currently experiencing.

I'll try to answer your question as best as I can, but my EIEIO&CLOS-fu
is pretty rusty (and was never particularly good to start with), so
please take the following with a grain of salt and prepend an 'AFAIK' in
your mind.

> Testing indicates
> that this works perfectly well:
>
> (defclass persisty (eieio-persistent)
>   ())
>
> (defmethod initialize-instance ((obj persisty) slots)
>   (message "slots: %s" slots)
>   (call-next-method obj slots))
>
> I have access to `slots', can short-circuit initialization, and the
> object is created as expected. Surely that's enough?

But, as the name says, `initialize-instance' only initializes the newly
created instance; it does not return it. So there's no way for you to
return the existing singleton. The only thing you could do is throw an
error.

> I like the idea of keeping the full list of files in a class-allocated
> slot. If it's a problem that the slot only exists after the first
> instance has been created, that seems like something that can be
> accounted for in `initialize-instance' as well...

In initialize-instance, the instance is already created.

> One thing I'm still confused about (and if I'm going to provide a doc
> patch, this is exactly what I'd like to address) is the relationship
> between `constructor', `initialize-instance' and `shared-initialize'.
> Obviously I can see that they call each other in that order, but I don't
> understand when you'd want to override one vs the other.

In a nutshell: The 'constructor' actually creates a new instance and
returns it, and it uses `initialize-instance' to initialize it, which
again calls `shared-initialize'.

This is confusing especially for people which come from a C++/Java
background, because here these steps are inseparable and the details are
fixed and defined by the language standard. For instance, in C++, you
cannot change the order in which members are initialized from the
initialization list. Also, what you call a 'constructor' in C++ is
actually an initializer, because the object is already constructed when
it is called. So the actual equivalent to what a constructor in C++ does
is an 'initialize-instance :after' method.

Since you want to meddle with actual object creation, you need to work
on 'constructor'. As I've written, you can use class allocated slots to
keep track of the already existing objects. However, as Pascal correctly
mentions, you don't necessarily have an existing instance. This is why
my initial statement that :allocate :class is pretty much equivalent to
'static' is wrong.

However, there's `oset-default' and `oref-default', which also work on
classes and not only on instances. All this is an EIEIO thing: the
'constructor' generic as well as `oset/oref-default'; this does not
exist in CLOS (AFAIK, etc.).

So how do you do this in CLOS? Here you have more powerful features:
metaclasses (which Python has, too) and EQL-specialization. Both are not
supported by EIEIO.

> As far as I can tell the only difference is that `constructor' has
> access to the string object name (the point of which I've never
> understood), and `initialize-instance' doesn't.

The object name is also an EIEIO thing. It's mainly there to ease
debugging. For instance, we create lot of databases in Semantic (which
are objects) to store symbols from source files in certain
directories. The name of these databases is equal to the directory
name. This makes inspection in the object browser much easier, since you
directly see the directory instead of some cryptic code. However, you
don't have to care about it, and `make-instance' will just use the class
name by default.

> Thanks for the offer! It would be something simple, just about using
> `initialize-instance', `constructor' if I ever understand exactly what
> that does, `object-print', and a few other methods in that neighborhood.
> As I mentioned I'm coming at this from Python experience, and wanted to
> write a basic how-to that would make sense to people with OO experience
> in other languages.

IMHO you best learn CLOS by forgetting OOP idioms from other
languages. You'll just get confused. I recommend reading the two
chapters on OOP from the Seibel-Book, which you can read online here:

http://gigamonkeys.com/book/

-David




reply via email to

[Prev in Thread] Current Thread [Next in Thread]