Hi all.
Can somebody point where to look for ways to get all accessors of a class?
As I read accessors are generally faster than slot access thru slot-value.
And I want some to write some kind of macro with-all-accessors that uses
with-accessors.
--
With best regards,
Anton Kazennikov. mailto:kazennikov[at]mirea.ru ICQ# 98965967
Anton Kazennikov <···············@gmail.com> writes:
> Can somebody point where to look for ways to get all accessors of a class?
You'll have to use MOP.
For example:
(defun class-direct-accessors (class-designator)
"
RETURN: all the accessors of all the slots for the designated class.
"
#+allegro (ignore-errors (make-instance class-designator)) ; needed to finalize the class.
(mapcan (lambda (slot)
(append (mop:slot-definition-readers slot)
(copy-list (mop:slot-definition-writers slot))))
(mop:class-direct-slots
(if (typep class-designator 'class)
class-designator
(find-class class-designator)))))
C/USER[120]> (defclass a ()
(s1
(s2 :reader s2r :writer s2w :accessor s2a)
(s3 :reader s3r :writer s3w :accessor s3a)))
#1=#<STANDARD-CLASS A>
C/USER[121]> (class-direct-accessors 'a)
(S2R S2A S2W (SETF S2A) S3R S3A S3W (SETF S3A))
;; More work will be needed if you want the accessors of the inherited
;; slots too.
> As I read accessors are generally faster than slot access thru slot-value.
I doubt it.
> And I want some to write some kind of macro with-all-accessors that uses
> with-accessors.
--
__Pascal Bourguignon__ http://www.informatimago.com/
NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
Anton Kazennikov wrote:
> Hi all.
>
> Can somebody point where to look for ways to get all accessors of a class?
>
> As I read accessors are generally faster than slot access thru slot-value.
> And I want some to write some kind of macro with-all-accessors that uses
> with-accessors.
In the general case, that is not possible. A macro is processed at
compile time [1], but a defclass form doesn't generate a representation
of a class at compile time - at least not in a standardized portable way
(not even with the CLOS MOP present). A defclass form actually only
generates the code that will eventually produce a class at runtime. What
is even more important is that you can change the definition of a class
at runtime at any time - so especially, the set of slots that a class
defines can change dynamically. So even if it were possible to
statically determine all slots of a class as it is defined at compile
time, it is not completely unlikely that the local variables introduced
by a hypothetical 'with-all-accessors form goes out of sync and doesn't
actually correspond to the given class anymore.
In other words, I would strongly advice against going that route.
Also your premise that accessors are in general faster than slot-value
is not true. Accessors are easier to optimize, but that doesn't mean
that slot-value cannot be optimized either. Especially, if you provide
the slot name as a constant (like in (slot-value object 'foo)) then most
advanced CL implementations can produce very efficient code which is
actually on par with accessors.
However, what is more important is that slot-value is a very low-level
approach to access slots, which should probably in most cases only be
performed by the class designer. Client code is most probably better off
using the accessors for semantical reasons: For example, if the class
designer doesn't provide a writer, then you should get the idea that she
doesn't want you to write to the corresponding slot. Also, accessors can
have before/after/around methods, and it is most probably semantically
important to trigger them if someone defined them. You don't trigger
them when you call slot-value.
The bottom line here is: Don't worry about efficiency here, especially
not prematurely, but rather focus on good programming practices,
especially by honoring abstraction boundaries.
Pascal
[1] Actually, at macroexpansion time, but since most CL implementations
provide an compiler and since you typically deploy compiled code, it's
an acceptable assumption that macroexpansion coincides with compilation.
--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/