EIEIO provides an Object Oriented layer for Emacs Lisp. You can use EIEIO to create classes, methods for those classes, and instances of classes.
Here is a simple example of a class named person
, containing
three slots named name
, birthday
, and phone
:
(defclass person () ; No superclasses ((name :initarg :name :initform "" :type string :custom string :documentation "The name of a person.") (birthday :initarg :birthday :initform "Jan 1, 1970" :custom string :type string :documentation "The person's birthday.") (phone :initarg :phone :initform "" :documentation "Phone number.")) "A class for tracking people I know.")
Each class can have methods, which are defined like this:
(cl-defmethod call-person ((pers person) &optional scriptname) "Dial the phone for the person PERS. Execute the program SCRIPTNAME to dial the phone." (message "Dialing the phone for %s" (slot-value pers 'name)) (shell-command (concat (or scriptname "dialphone.sh") " " (slot-value pers 'phone))))
In this example, the first argument to call-person
is a list,
of the form (varname classname). varname is the
name of the variable used for the first argument; classname is
the name of the class that is expected as the first argument for this
method.
EIEIO dispatches methods based on the type of the first argument.
You can have multiple methods with the same name for different classes
of object. When the call-person
method is called, the first
argument is examined to determine the class of that argument, and the
method matching the input type is then executed.
Once the behavior of a class is defined, you can create a new
object of type person
. Objects are created by calling the
constructor. The constructor is a function with the same name as your
class which returns a new instance of that class. Here is an example:
(setq pers (person :name "Eric" :birthday "June" :phone "555-5555"))
For backward compatibility reasons, the first argument can be a string (a name given to this instance). Each instance used to be given a name, so different instances could be easily distinguished when debugging.
It can be a bit repetitive to also have a :name slot. To avoid doing
this, it is sometimes handy to use the base class eieio-named
.
See eieio-named
.
Calling methods on an object is a lot like calling any function. The first argument should be an object of a class which has had this method defined for it. In this example it would look like this:
(call-person pers)
or
(call-person pers "my-call-script")
In these examples, EIEIO automatically examines the class of
pers
, and ensures that the method defined above is called. If
pers
is some other class lacking a call-person
method, or
some other data type, Emacs signals a cl-no-applicable-method
error. Signals.