2011-02-14 2 views
3

다음 코드를 두 번 평가하면 결과가 달라집니다. 아무도 무슨 일이 일어나고 있는지 설명 할 수 있습니까?우연한 섀도 잉과`제거 된 [심볼] '

findHull[points_] := Module[{}, 
    Needs["ComputationalGeometry`"]; 
    ConvexHull[points] 
    ]; 
findHull[RandomReal[1, {10, 2}]]; 
Remove["Global`ConvexHull"]; 
findHull[RandomReal[1, {10, 2}]] 

답변

6

문제는 당신이 정의 할 때 findHull 전화 전까지 모듈이 평가되지 않더라도, 기호가 해결 될 것입니다 findHull (즉 : findHull의 새로운 downvalue은 문자, 텍스트가 아닌 측면에 저장됩니다). 즉, Needs이 평가되지 않기 때문에 첫 번째 라운드에서 ConvexHullGlobal`ConvexHull으로 해결됩니다. 두 번째 라운드에서 ComputationalGeometry$ContextPath이고 따라서 ConvexHull은 의도 한대로 해결됩니다.

실제로 미리 ComputationalGeometry을로드 할 수 없다면 ConvexHull의 전체 이름 : ComputationalGeometry`ConvexHull을 참조하십시오. this related answer을 참조하십시오.

HTH

+0

감사합니다. 필자가 발견 한 또 다른 상황은 패키지 MyPackage 내부의 함수 내에서 정의 된 함수가 MyPackage 'Private이 아닌 Private'에 넣어 졌다는 것입니다. –

+0

@Yaroslav. 그 중 하나를 재현 할 수 없다 - Begin [ "Private'"] 대신 Begin [ "` Private `"]을 사용했는지 기억해 봤습니까? – Janus

+0

다시 인용구를 사용하여 다시 시도해 보겠습니다. Begin [ "\'Private \'"]을 사용해야합니다. – Janus

2

아니 직접 질문에 대답하지만, 주석에 대한 조금 너무 큽니다. 또 다른 대안으로, 런타임까지 심볼 파싱을 지연시키는 일반적인 방법은 Symbol["your-symbol-name"]을 사용하는 것입니다. 귀하의 경우, r.h.s.s의 ConvexHull을 대체 할 수 있습니다. Symbol["ConvexHull"]하여 정의의 : Symbol["ConvexHull"]가 새롭게마다 실행되기 때문에

findHull[points_] := 
Module[{}, 
    Needs["ComputationalGeometry`"]; 
    Symbol["ConvexHull"][points]]; 

이 솔루션은, 그러나 매우 우아하지 않습니다. $ContextPath으로 간단한 조작을 수행하면 다소 오류가 발생할 수 있습니다. 여기에 자체 재정으로 일반적으로 유용한 트릭과 함께 수정 된 버전은, 내가 비슷한 경우에 사용하는 것이있다 :

findHull[RandomReal[1, {10, 2}]] 

{4, 10, 9, 1, 6, 2, 5} 

무엇 일어나는 것은, 예를 들어

Clear[findHull]; 
findHull[points_] := 
Module[{}, 
    Needs["ComputationalGeometry`"]; 
    With[{ch = Symbol["ConvexHull"]}, 
    findHull[pts_] := ch[pts]; 
    findHull[points]]]; 

처음으로 기능이 원래 정의가 Module으로 바뀌면 내부 패키지로 바뀌고 필요한 패키지가로드되고 해당 컨텍스트가 $ContextPath에 배치 된 후에 이미 발생합니다. 여기서 우리는 매쓰 매 티카가 패턴이 동일하다는 것을 결정할 수 있다면 (Mathematica가 이전 정의를 새로운 것으로 대체한다는 사실을 악용합니다.

예를 들어, 함수 호출이 값 비싼 계산을 초래할 수있는 경우가 있습니다 만, 캐시하기를 원하지만 함수가 전혀 호출되지 않을지는 확실하지 않은 경우가 있습니다 . 그런 구조체는 함수에 대한 첫 번째 호출시 계산 된 (말하자면, 상징적 인) 결과를 자동으로 캐시 할 수 있습니다.

+0

멋진 트릭! 그리고 문자 계산을위한 몇 가지 추가 단어 :) – Janus

+0

@Janus 그 자리에 있었고, 자세한 내용은 내 죄의 하나입니다 :) –

+0

비밀스러운 댓글 사과 : "여분의 단어"는 "좋은 트릭!"SO 주석으로 자격을 부여하기에 충분하지 않습니다. 귀하의 대답은 자세한 정보 수준에 달려 있다고 생각합니다. :) – Janus