Bagaimana cara membuat: kata kunci?

16

T: Bagaimana cara membuat dan menggunakan :keywords?

Pertimbangkan upaya (naif, tampaknya) untuk mengakses daftar mainan berikut:

(setf alist '((:key-1 "Key no. 1")
              (:key-2 "Key no. 2")))

(assq :key-1 alist)                 ; => (:key-1 "Key no. 1")
(assq (make-symbol ":key-1") alist) ; => nil

Kunci pertama berfungsi seperti yang diharapkan, tetapi kunci kedua tidak. Sejauh tidak ada make-keywordfungsi yang jelas , bagaimana cara membuat dan menggunakan kata kunci?

Motivasi orisinal: Saya perlu mengubah string menjadi kunci pencarian yang merupakan simbol yang saya dapat putproperti.

Dalam proses merumuskan pertanyaan ini, saya mendapatkan setidaknya sebagian dari jawaban, yang saya posting secara terpisah. Saya berharap pikiran yang lebih cerah daripada yang bisa saya perbaiki.

Dan
sumber
1
(eq :foo (read ":foo"))
abo-abo

Jawaban:

9

Anda benar yang make-symbolakan membuat kata kunci yang bukan equntuk kata kunci yang ada, dan internmungkin mencemari obarray global dengan simbol baru. Di antara itu, Anda memiliki intern-soft, yang mengembalikan simbol jika sudah dibuat, atau niljika belum:

ELISP> (intern-soft ":key-1")
nil
ELISP> :key-1
:key-1
ELISP> (intern-soft ":key-1")
:key-1

Ini harus sesuai untuk tujuan Anda: jika kata kunci tidak ada, kata kunci itu tidak ada di daftar, jadi tidak perlu membuatnya hanya untuk memeriksa apakah ada di sana. Sesuatu seperti:

(let ((maybe-keyword (intern-soft ":key-1")))
  (and maybe-keyword (assq maybe-keyword alist)))
legoscia
sumber
Pintar - saya pernah melihat intern-softtetapi tidak berpikir untuk menggunakannya dengan cara ini.
Dan
6

Mungkin saya tidak memahami pertanyaan dengan benar. Tetapi jika Anda ingin kata kunci (yaitu, Anda ingin memuaskan keywordp) maka Anda ingin simbol yang akan magang di obarray global yang , obarray.

Itu harus diinternir di sana untuk memuaskan keywordp, AFAICT, dan C-h f keywordpmengatakan demikian.

Jadi jawaban untuk pertanyaan Anda, AFAICT, hanya digunakanintern .

Saya merasa Anda mungkin tidak menanyakan pertanyaan Anda yang sebenarnya - sepertinya pertanyaan XY. Apa yang sebenarnya ingin Anda lakukan? (Mungkin mengajukan itu sebagai pertanyaan terpisah.)

[Sebagai jawaban atas komentar Anda bahwa pemagangan " tidak :keywordspesifik, karena berlaku untuk semua simbol ": Benar, pemagangan tidak spesifik untuk kata kunci. Tetapi magang ( obarraymenggunakan) dan menggunakan symbol-nameyang dimulai :khusus untuk kata kunci.]

Drew
sumber
Ini tentu saja merupakan pertanyaan XY dalam arti bahwa saya mencoba untuk Y, tetapi benar-benar tertarik pada X dalam upaya saya untuk sampai ke Y. Biarkan saya memikirkan bagaimana mengajukan pertanyaan tentang Y sedemikian rupa sehingga itu bermanfaat bagi orang lain juga.
Dan
Bagus. Itu akan sangat membantu. Terima kasih.
Drew
2

Ini jawaban parsial untuk pertanyaan ini. Versi singkat dan tidak sepenuhnya memuaskan tampaknya: digunakan intern.

:key-1 memenuhi keduanya:

(symbolp :key-1)                    ; => t
(keywordp :key-1)                   ; => t

Meskipun (make-symbol ":key-1")memuaskan yang pertama tetapi tidak yang kedua:

(symbolp (make-symbol ":key-1"))    ; => t
(keywordp (make-symbol ":key-1"))   ; => nil

Sekarang, dokumen untuk make-symbolmengatakan bahwa itu akan:

Kembalikan simbol yang tidak diinginkan yang baru dialokasikan dan namanya NAME.

Mmmkay, dan dokumen untuk keywordpmengatakan bahwa itu akan:

Kembali tjika OBJECT adalah kata kunci. Ini berarti bahwa itu adalah simbol dengan nama cetak yang dimulai dengan : diinternir dalam obarray awal.

Jadi tampaknya itu internakan berfungsi:

(assq (intern ":key-1") alist)      ; => (:key-1 "Key no. 1")

Karena internakan:

Kembalikan simbol kanonik yang namanya STRING. Jika tidak ada, satu dibuat oleh fungsi ini dan dikembalikan. Argumen opsional kedua menentukan obarray untuk digunakan; standarnya adalah nilai obarray.

Tapi ini sepertinya tidak :keywordspesifik, karena ini berlaku untuk semua simbol. Secara default, tampaknya juga mencemari global obarray, yang mungkin atau mungkin bukan A Big Deal.

Dan
sumber