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

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

EIEIO: A question about interfaces


From: Michael Heerdegen
Subject: EIEIO: A question about interfaces
Date: Thu, 14 Jan 2021 16:21:21 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

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 via email to

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