I wanted to trace all functions in a package and ended up with the
unusually thorny code..
(loop for sym being each present-symbol in :pat-match if (fboundp sym) do
(eval `(trace ,sym)))
Is there a better way to do this?
--------------
John Thingstad
"John Thingstad" <·······@online.no> writes:
> I wanted to trace all functions in a package and ended up with the
> unusually thorny code..
>
> (loop for sym being each present-symbol in :pat-match if (fboundp sym)
> do (eval `(trace ,sym)))
>
> Is there a better way to do this?
(eval `(trace ,@(loop :for sym :being :each present-symbol :in :pat-match
:when (fboundp sym) :collect sym)))
Since EVAL is frowned upon, the less you call it the better. ;-)
--
__Pascal Bourguignon__ http://www.informatimago.com/
Litter box not here.
You must have moved it again.
I'll poop in the sink.
On 2008-08-29, Pascal J. Bourguignon <···@informatimago.com> wrote:
> "John Thingstad" <·······@online.no> writes:
>
>> I wanted to trace all functions in a package and ended up with the
>> unusually thorny code..
>>
>> (loop for sym being each present-symbol in :pat-match if (fboundp sym)
>> do (eval `(trace ,sym)))
>>
>> Is there a better way to do this?
>
> (eval `(trace ,@(loop :for sym :being :each present-symbol :in :pat-match
> :when (fboundp sym) :collect sym)))
>
> Since EVAL is frowned upon, the less you call it the better. ;-)
I.e. no eval is even better:
(defmacro trace-helper (trace-untrace package)
`(,trace-untrace ,@(loop :for sym :being :each present-symbol :in package
:when (fboundp sym) :collect sym)))
(defmacro trace-package (package)
`(trace-helper trace ,package))
(defmacro untrace-package (package)
`(trace-helper untrace ,package))
In article <··············@hubble.informatimago.com>,
···@informatimago.com (Pascal J. Bourguignon) wrote:
> "John Thingstad" <·······@online.no> writes:
>
> > I wanted to trace all functions in a package and ended up with the
> > unusually thorny code..
> >
> > (loop for sym being each present-symbol in :pat-match if (fboundp sym)
> > do (eval `(trace ,sym)))
> >
> > Is there a better way to do this?
>
> (eval `(trace ,@(loop :for sym :being :each present-symbol :in :pat-match
> :when (fboundp sym) :collect sym)))
>
> Since EVAL is frowned upon, the less you call it the better. ;-)
Macros and Special Operators are also FBOUND.
* (defmacro foobarbaz () )
FOOBARBAZ
* (fboundp *)
T
(defmacro traceall (package)
(flet ((all-function-symbols-in-package (package &aux (result nil))
(do-symbols (symbol package result)
(when (and (fboundp symbol)
(not (macro-function symbol))
(not (special-operator-p symbol)))
(push symbol result)))))
`(trace ,@(all-function-symbols-in-package package))))
--
http://lispm.dyndns.org/
P� Fri, 29 Aug 2008 23:00:09 +0200, skrev Rainer Joswig <······@lisp.de>:
>
> Macros and Special Operators are also FBOUND.
>
> * (defmacro foobarbaz () )
>
> FOOBARBAZ
> * (fboundp *)
>
> T
>
>
> (defmacro traceall (package)
> (flet ((all-function-symbols-in-package (package &aux (result nil))
> (do-symbols (symbol package result)
> (when (and (fboundp symbol)
> (not (macro-function symbol))
> (not (special-operator-p symbol)))
> (push symbol result)))))
> `(trace ,@(all-function-symbols-in-package package))))
>
Thanks! As it stands it is a bit too generous as do-symbols includes all
symbols it sees in the package and that includes the ones you :use.
Tracing all function symbols in the common-lisp package as well might not
be what you intended..
After messing with it a bit I came up with the following:
(defun all-function-symbols-in-package (&optional (package *package*))
"Return a list of all functions is a package.
A symbol is a function symbol if it is fboundp and not a macro or spesial
operator."
(let (result
(current-package (if (symbolp package) (find-package package)
package)))
(do-symbols (symbol current-package result)
(when (and (eq (symbol-package symbol) current-package)
(fboundp symbol)
(not (macro-function symbol))
(not (special-operator-p symbol)))
(push symbol result)))
(nreverse result)))
(defmacro traceall (&optional (package *package*))
`(trace ,@(all-function-symbols-in-package package)))
(defmacro untraceall (&optional (package *package*))
`(untrace ,@(all-function-symbols-in-package package)))
--------------
John Thingstad
P� Fri, 29 Aug 2008 22:35:48 +0200, skrev John Thingstad
<·······@online.no>:
> I wanted to trace all functions in a package and ended up with the
> unusually thorny code..
>
> (loop for sym being each present-symbol in :pat-match if (fboundp sym)
> do (eval `(trace ,sym)))
>
> Is there a better way to do this?
Thanks to all that replied. I eventually ended up with the following code.
(Just another utillity in my /Lisp Programs/misc directory.)
Note that 'package can be a a package structure, a package symbol or nick
and defaults to current *package*.
use:
(load "../misc/traceall")
(tu:trace-all)
...
(tu:untrace-all)
code:
(defpackage :trace-utilleties
(:nicknames :tu)
(:use :cl)
(:export package-function-symbols trace-all untrace-all))
(in-package :trace-utilleties)
(defun package-function-symbols (&optional (package *package*))
"Return a list of all functions is a package.
A symbol is a function symbol if it is fboundp and not a macro or spesial
operator."
(let (result
(current-package (if (packagep package) package (find-package
package))))
(assert (not (eq current-package nil)) (package) "package ~S not
found." package)
(do-symbols (symbol current-package result)
(when (and (eq (symbol-package symbol) current-package)
(fboundp symbol)
(not (macro-function symbol))
(not (special-operator-p symbol)))
(push symbol result)))
(nreverse result)))
(defmacro trace-all (&optional (package *package*))
"Trace all functions in package. Defaults to the current package."
`(trace ,@(package-function-symbols package)))
(defmacro untrace-all (&optional (package *package*))
"Untrace all the functins in the current package. Defaults to the
current package."
`(untrace ,@(package-function-symbols package)))
--------------
John Thingstad
"John Thingstad" <·······@online.no> writes:
> Thanks to all that replied. I eventually ended up with the following code.
Thank you for posting this. I had a similar need today, and found
your code before wasting too much time reinventing it. However, I
wanted to be able to just trace the external functions of a package.
My version ended up like this:
(defun package-function-symbols (&optional (package *package*) external-only)
"Return a list of all (or all external) functions is a package.
A symbol is a function symbol if it is fboundp and not a macro or spesial
operator."
(let (result
symbols
(current-package (if (packagep package) package (find-package package))))
(assert (not (eq current-package nil)) (package) "package ~S not found." package)
(if external-only
(do-external-symbols (symbol current-package)
(push symbol symbols))
(do-symbols (symbol current-package)
(push symbol symbols)))
(dolist (symbol symbols result)
(when (and (eq (symbol-package symbol) current-package)
(fboundp symbol)
(not (macro-function symbol))
(not (special-operator-p symbol)))
(push symbol result)))))
(defmacro trace-all (&optional (package *package*) external-only)
"Trace all (or all external) functions in package. Defaults to the
current package."
`(trace ,@(package-function-symbols package external-only)))
(defmacro untrace-all (&optional (package *package*) external-only)
"Untrace all (or all external) functions in package. Defaults to the
current package."
`(untrace ,@(package-function-symbols package external-only)))
Share and enjoy.
...Peder...
--
I wish a new life awaited _me_ in some off-world colony.