challenge メソッド名一覧の表示

リフレクション系のお題の続編です。

「ある与えられたオブジェクトtargetのメソッドのうち、 "test_"で始まるものをすべて呼びだす」というコードを書いてください。 引数に関しては都合のいいように仮定して構いません(全部0個、など)。

メソッドという概念がない言語の場合は、 「複数の関数への参照を持っているようなオブジェクト(たとえばパッケージとかモジュールとか)から"test_"で始まる関数をすべて呼び出す」と読み替えても構いません。

Posted feedbacks - Common Lisp

Common Lispのメソッドはクラス内の概念ではないので「複数の関数への参照を持っているようなオブジェクト(たとえばパッケージとかモジュールとか)から"test_"で始まる関数をすべて呼び出す」 関数名はLisp的にはtest-なんだけどね~
1
2
3
4
5
6
7
(require :cl-ppcre)
(defun test_1 () 1)
(defun test_2 () 2)
(defun test_3 () 3)

(loop for f in (ppcre:regex-apropos-list "^test_" *package*)
   collect (cons f (funcall f)))        ; => ((TEST_1 . 1) (TEST_3 . 3) (TEST_2 . 2))

変数の定義でもシンボルはインターンされるので fboundp を。ついでに大文字小文字を区別する別回答。 funcall は関数を探しにいきますので symbol-function は不要ですがなんとなく。
1
2
3
4
(defun call-test (pakcage)
  (do-symbols (symbol pakcage)
    (when (and (fboundp symbol) (ppcre:scan "^test_" (symbol-name symbol)))
      (format t "~A => ~A~%" symbol (funcall (symbol-function symbol))))))

ぎゃぁ、fboundpが抜けてたorzorzorz
1
2
3
4
5
6
7
8
9
(require :cl-ppcre)
(defun test_1 () 1)
(defun test_2 () 2)
(defun test_3 () 3)
(defparameter test_var 0)

(loop for f in (ppcre:regex-apropos-list "^test_" *package*)
   when (fboundp f)
   collect (cons f (funcall f)))        ; => ((TEST_1 . 1) (TEST_3 . 3) (TEST_2 . 2))

暇潰しにやってみた。

反則っちゃ反則なんだけどPCLベースのCLOS実装やってる処理系だと似たようなことできるんちゃうかな

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
(use-package :sb-mop)
(defclass c0 ()
  ((x :initarg :x :accessor x)
   (y :initarg :y :accessor y)))
(defgeneric magnitude (obj))
(defmethod magnitude ((obj c0))
  (sqrt (+ (expt (x obj) 2) (expt (y obj) 2))))
(mapcar #'(lambda (m)
        (slot-value (slot-value m 'SB-PCL::%GENERIC-FUNCTION)
            'SB-PCL::NAME))
    (car (slot-value (find-class 'c0) 'SB-PCL::DIRECT-METHODS)))

Index

Feed

Other

Link

Pathtraq

loading...