키워드를 만드는 방법?


16

Q : 어떻게 만들고 사용 :keywords합니까?

다음 장난감 목록에 액세스하려는 (순진하고 명백한) 시도를 고려하십시오.

(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

첫 번째 키는 예상대로 작동하지만 두 번째 키는 작동하지 않습니다. 명백한 make-keyword기능 이없는 한 키워드는 어떻게 만들고 사용합니까?

독창적 인 동기 부여 : 문자열을 put속성을 지정할 수있는 기호 인 조회 키로 변환해야 합니다.

이 질문을 공식화하는 과정에서 나는 적어도 부분적으로 답변을 얻었습니다. 나는 내 마음이 향상 될 수있는 것보다 더 밝은 마음을 바라고있다.


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

답변:


9

당신이 바로 점이다 make-symbol없는 키워드 생성합니다 eq기존의 키워드, 그리고 intern새로운 기호 글로벌 obarray을 오염 수 있습니다. 그 사이 intern-soft에 기호가 이미 생성되었거나 nil그렇지 않은 경우 기호를 반환합니다 .

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

키워드가 존재하지 않으면 키워드가 목록에 없을 수 있으므로 키워드가 있는지 확인하기 위해 키워드를 만들 필요가 없습니다. 다음과 같은 것 :

(let ((maybe-keyword (intern-soft ":key-1")))
  (and maybe-keyword (assq maybe-keyword alist)))

영리한-나는 보았지만 intern-soft이런 식으로 사용하지는 않았다.
Dan

6

아마도 질문을 올바르게 이해하지 못했을 것입니다. 하지만이 경우 키워드를 원하는 (즉, 당신이 만족하려는 keywordp) 당신은 기호가 글로벌 obarray에 구금되고 싶지 , obarray.

그것은 해야한다 충족시키기 위해이 억류 될 keywordp, AFAICT, 그리고 C-h f keywordp이렇게 말한다.

귀하의 질문에, AFAICT에 대한 대답 그래서, 단지이다 사용intern .

나는 당신이 아마도 당신의 실제 질문을하지 않는 것처럼 느낍니다. XY 질문처럼 보입니다. 당신은 정말로 무엇을하려고합니까? (아마도 별도의 질문으로 포즈를 취하십시오.)

[귀하의 의견에 "interning" :keyword모든 기호에 적용되므로 " 특정 하지 않습니다 ": 맞습니다. interning은 키워드에만 국한되지 않습니다. 그러나 인턴으로 시작하고 로 시작 obarray하는 symbol-name을 사용하는 것은 :키워드에 따라 다릅니다.]


내가 Y를 시도하고 있다는 점에서 XY 질문이 가장 확실하지만 Y에 도달하려는 시도에서 X에 정말로 관심이 있습니다. 다른 사람에게도 유용합니다.
Dan

큰. 도움이 될 것입니다. 고마워.
Drew

2

이 질문에 대한 부분 답변이 있습니다. 짧고 완전히 만족스럽지 않은 버전은 다음과 같습니다. use intern.

:key-1 둘 다 만족합니다 :

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

반면 (make-symbol ":key-1")만족 처음하지만 두 번째되지를 :

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

이제 docstring은 다음과 make-symbol같이 말합니다.

이름이 NAME 인 새로 할당 된 언 인턴 심볼을 반환합니다.

음, 그리고 docstring은 다음과 같이 keywordp말합니다 :

tOBJECT가 키워드 인 경우 반환 합니다. 이것은 : 최초의 obarray에서 interned으로 시작하는 인쇄 이름을 가진 기호임을 의미합니다 .

따라서 intern작동 하는 것처럼 보입니다 .

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

때문에 intern의지 :

이름이 STRING 인 정식 기호를 반환합니다. 없는 경우이 함수에 의해 생성되어 반환됩니다. 두 번째 선택적 인수는 사용할 obarray를 지정합니다. 기본값은 obarray입니다.

그러나 이것은 :keyword모든 기호에 적용 되므로 구체적으로 보이지는 않습니다 . 기본적으로 전역을 오염시키는 것으로 보이며 obarray이는 큰 거래일 수도 있고 아닐 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.