all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* EIEIO: A question about interfaces
@ 2021-01-14 15:21 Michael Heerdegen
  2021-01-14 17:47 ` Stefan Monnier
  0 siblings, 1 reply; 7+ messages in thread
From: Michael Heerdegen @ 2021-01-14 15:21 UTC (permalink / raw)
  To: Emacs mailing list

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.



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-01-15 23:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-01-14 15:21 EIEIO: A question about interfaces Michael Heerdegen
2021-01-14 17:47 ` 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

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.