unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: David Engster <deng@randomsample.de>
To: help-gnu-emacs@gnu.org
Subject: Re: EIEIO built in methods -- question
Date: Wed, 12 Jun 2013 17:44:24 +0200	[thread overview]
Message-ID: <87wqpznxk7.fsf@arcor.de> (raw)
In-Reply-To: 87hah5jssd.fsf@ericabrahamsen.net

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	other threads:[~2013-06-12 15:44 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-09 10:22 EIEIO built in methods -- question Eric Abrahamsen
2013-06-09 10:49 ` Eric Abrahamsen
2013-06-09 11:54 ` Pascal J. Bourguignon
2013-06-09 15:22   ` Eric Abrahamsen
     [not found]   ` <mailman.1279.1370791373.22516.help-gnu-emacs@gnu.org>
2013-06-09 20:47     ` Pascal J. Bourguignon
2013-06-10 15:48       ` David Engster
2013-06-11  2:16         ` Eric Abrahamsen
2013-06-12 15:44           ` David Engster [this message]
2013-06-13  5:11             ` Eric Abrahamsen
2013-06-13  9:06               ` Eric Abrahamsen
2013-06-13 15:49               ` David Engster
2013-06-14  1:37                 ` Eric Abrahamsen
2013-06-14 15:14                   ` David Engster
2013-06-14 16:15                     ` Eric Abrahamsen
     [not found]                     ` <mailman.1680.1371226519.22516.help-gnu-emacs@gnu.org>
2013-06-14 18:29                       ` Pascal J. Bourguignon
     [not found]       ` <mailman.1356.1370879310.22516.help-gnu-emacs@gnu.org>
2013-06-10 19:18         ` Pascal J. Bourguignon
2013-06-11 15:43           ` David Engster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wqpznxk7.fsf@arcor.de \
    --to=deng@randomsample.de \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).