all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Michael Heerdegen <michael_heerdegen@web.de>
To: Emacs mailing list <help-gnu-emacs@gnu.org>
Subject: EIEIO: A question about interfaces
Date: Thu, 14 Jan 2021 16:21:21 +0100	[thread overview]
Message-ID: <877dofee8e.fsf@web.de> (raw)

Hello,

(One thing in advance: I'm still not really that familiar with using
EIEIO stuff in real code.)

My question: Say (general case) I have a given hierarchy of (EIEIO)
classes, and a set of methods implementing diverse generics for objects
of some of these classes.

Now I want to allow that some objects of some of these classes have/
support an additional feature.  Some of the methods might need be
slightly tuned for objects having this feature, e.g. by defining
according :around methods.

My question: how would I code that concretely?  When I define an
interface class, would I need to define a parallel version of the given
hierarchy of classes inheriting from the interface?  Can I avoid that?

Because, a thing "typically" only belongs to one class.  If I don't want
to mess around with `cl-generic-define-generalizer', the existing
specializers don't seem to allow to test whether a given object fulfills
a given arbitrary predicate (AFAIU &context allows to specify arbitrary
tests but seems there is no way to refer to the tested object from
within this test).

Too vague?  Here is some code I played with:

#+begin_src emacs-lisp
(defclass my-1 () ((contents :initarg :contents)))

(cl-defgeneric my-test (obj))

(cl-defmethod my-test ((obj my-1)) (format "Contents: %S" (oref obj contents)))

;;

(defclass my-foo-interface () ((additional :initarg :additional)))

(defclass my-1-foo (my-foo-interface my-1) ())

(cl-defmethod my-test ((obj my-foo-interface))
  (concat (format "Additional: %S\n" (oref obj additional))
          (cl-call-next-method)))

;; Test:

(my-test (my-1-foo :contents 'x :additional 17))
#+end_src

That "works" so far, but with that strategy I would have to define one
extra class per given class from the hierarchy to be even able to create
objects of the according kind.

To avoid that I could replace the interface class with a wrapper class
that has a field that can contain any instance of any class of the given
hierarchy.  But then the methods implementing generics for the class
hierarchy would not recognize this new kind of objects.  I would need to
implement each of these methods for the wrapper class individually.
Trivial but creating redundancy and maintenance burden.  And: other
existing code explicitly testing for the type of object could fail to
recognize the altered classes as well, code I might not be able to
extent as easily as by adding (wrapper) method implementations.

Any hints of how to do this more intelligently?

TIA,

Michael.



             reply	other threads:[~2021-01-14 15:21 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-14 15:21 Michael Heerdegen [this message]
2021-01-14 17:47 ` EIEIO: A question about interfaces Stefan Monnier
2021-01-15 11:30   ` Michael Heerdegen
2021-01-15 16:21     ` Stefan Monnier
2021-01-15 22:34       ` Michael Heerdegen
2021-01-15 22:56         ` Eric Abrahamsen
2021-01-15 23:38         ` Stefan Monnier

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

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

  git send-email \
    --in-reply-to=877dofee8e.fsf@web.de \
    --to=michael_heerdegen@web.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.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.