[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: EIEIO built in methods -- question
From: |
Eric Abrahamsen |
Subject: |
Re: EIEIO built in methods -- question |
Date: |
Thu, 13 Jun 2013 13:11:55 +0800 |
User-agent: |
Gnus/5.130008 (Ma Gnus v0.8) Emacs/24.3 (gnu/linux) |
David Engster <deng@randomsample.de> writes:
> 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.
Oh dear, something is very confused here! My understanding of the
CLOS/EIEIO model of generic methods and inheritance is that you're
basically just creating a glorified hook that gets called as one of a
chain of hooks, and that you continue the chain with call-next-method.
It's call-next-method that calls a method that produces a return value,
not my actual implementation of initialize-instance. The whole thing in
a nutshell:
(defvar bad-file-name "/home/eric/bad.txt")
(defclass persisty (eieio-persistent)
())
(defmethod initialize-instance ((obj persisty) slots)
(let ((file-name (plist-get slots :file)))
(if (equal file-name bad-file-name)
(error "You can't use that file")
(message "You made %s" file-name))
(call-next-method obj slots)))
ELISP> (setq g (make-instance 'persisty "good" :file "/home/eric/good.txt"))
[object persisty "good" "/home/eric/good.txt"] <--- produces success message
ELISP> (setq b (make-instance 'persisty "bad" :file "/home/eric/bad.txt"))
*** Eval error *** You can't use that file
ELISP> b
*** Eval error *** Symbol's value as variable is void: b
Unless there's some potential fatal flaw with this that I'm not seeing,
this is precisely the behavior I wanted.
>> 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'.
Ha, though what you say here is basically a restatement of what I could
see for myself in the code, it only just made sense, thank you. I think
you're right -- I'm not used to seeing the initialization process broken
into several steps, that was the only problem.
I'm a little curious as to why overloading the constructor only seems to
work with the :static specification (it doesn't appear to get called at
all, otherwise).
I'll do some more experimentation with class-allocated slots, that's
still a bit opaque to me.
[...]
>> 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.
That was interesting, thanks. For persistent objects, in particular, it
does seem to make sense to use the save file as the name.
>> 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:
I think I've got a handle on that now. I first read those chapters two
or three years ago and was *totally* baffled -- I couldn't grok that
methods could be separated from objects. I revisited it recently,
though, and it made quite a bit of sense (and made me wish, once again,
that my emacs ran on SBCL...).
I don't think I'm necessarily stuck in Python/C++ etc, but I do think
it's helpful to tell people "what it looks like over here".
Thanks for your help,
Eric
- EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/09
- Re: EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/09
- Re: EIEIO built in methods -- question, Pascal J. Bourguignon, 2013/06/09
- Re: EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/09
- Message not available
- Re: EIEIO built in methods -- question, Pascal J. Bourguignon, 2013/06/09
- Re: EIEIO built in methods -- question, David Engster, 2013/06/10
- Re: EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/10
- Re: EIEIO built in methods -- question, David Engster, 2013/06/12
- Re: EIEIO built in methods -- question,
Eric Abrahamsen <=
- Re: EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/13
- Re: EIEIO built in methods -- question, David Engster, 2013/06/13
- Re: EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/13
- Re: EIEIO built in methods -- question, David Engster, 2013/06/14
- Re: EIEIO built in methods -- question, Eric Abrahamsen, 2013/06/14
- Message not available
- Re: EIEIO built in methods -- question, Pascal J. Bourguignon, 2013/06/14
- Message not available
- Re: EIEIO built in methods -- question, Pascal J. Bourguignon, 2013/06/10
- Re: EIEIO built in methods -- question, David Engster, 2013/06/11