Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-10-31

SLIMEとElispを連携させたい その2

| 16:35 | SLIMEとElispを連携させたい その2 - わだばLisperになる を含むブックマーク はてなブックマーク - SLIMEとElispを連携させたい その2 - わだばLisperになる

コメント覧にて、佐野さんから値を取得する場合には、slime-evalを使う、と教えてもらったので早速試してみました。

slime-evalの仕様がいまいち分かっておらず、シンボルのパッケージの指定は強制的に文字列で置換した後にSLIMEに送ることにしてみました。

;; Emacs Lisp
(require 'cl)

(defun has-package-name-p (symbol)
  (and (position ?: (symbol-name symbol)) 'T))

(defun put-package-name (tree &optional pkg)
  (let ((pkg (symbol-name (or pkg 'cl-user))))
    (*put-package-name tree pkg)))

(defun *put-package-name (tree pkg)
  (cond ((null tree) () )
        ((consp (car tree))
         (cons (*put-package-name (car tree) pkg)
               (*put-package-name (cdr tree) pkg)))
        ((and (symbolp (car tree))
              (not (has-package-name-p (car tree))))
         (cons (intern (concat pkg "::" (symbol-name (car tree))))
               (*put-package-name (cdr tree) pkg)))
        ('T (cons (car tree)
                  (*put-package-name (cdr tree) pkg)))))

(defmacro cl-funcall (fn &rest expr)
  `(slime-eval 
    ',(put-package-name `(funcall ,fn ,@expr))))

;; 動作
(+ (cl-funcall #'+ 30 40) 30)
100

(cl-funcall #'ppcre:scan "良し" "これで良し")
3

効率は悪そうですが、まずこれで良しとします。cl-evalとかも欲しいかも。

SLIMEとElispを連携させたい

| 13:41 | SLIMEとElispを連携させたい - わだばLisperになる を含むブックマーク はてなブックマーク - SLIMEとElispを連携させたい - わだばLisperになる

先日はSLIME経由で、CLの関数を呼んでみたりしました(→LINK)

しかし、これだけだとつまらないので、もう一歩進んで、CLの関数をELispと混ぜて使えたら便利だなということで、適当に試してみました。

希望としては、Elisp上で

(+ 33 (cl-funcall #'fib 10))
;=> 88

みたいな事ができれば最高です。

とりあえずElisp上でCLの関数が定義できるようにしてみました。

先日定義した、slime-eval-mesgを使用します。

(defmacro define-cl-function (name arg &rest body)
  (slime-eval-mesg
   (format "(defun %s %s %s)"
           name arg (mapconcat (lambda (x) (format "%s" x)) body " "))))

(defun eval-cl (expr)
  (slime-eval-mesg (format "%s" expr)))

;; 関数を定義してみる
(define-cl-function fib (n)
  (if (< n 2)
      n
      (+ (fib (1- n))
         (fib (- n 2)))))

(eval-cl '(fib 20))
;>>> 6765

とりあえずですが、関数は定義できました。ちなみにパッケージの連携については謎です。

それで、その値を取得したい訳なのですが、

(defun cl-funcall (fn &rest args)
  (slime-eval-async
   `(swank:eval-and-grab-output 
     ,(format "(funcall #'%s %s)" 
              fn (mapconcat (lambda (x) (format "%S" x)) args " ")))
   (lambda (result)
     (setq *ans* (cadr result))))
  *ans*) ;; 大域変数に逃すという苦肉の策。しかし*ans*の値がリアルタイムに取得できない。

みたいなものを定義しても、どうやら駄目なようです。

SLIMEの値の受渡しについてもう少し探ってみる必要があるようですが、自分は、根性無しなので知っている方がいらっしゃったら是非教えて欲しいです(笑)

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20081031