2009-11-04 5 views
2

클래스 내의 파일 액세스를 처리하는 CLOS 방식을 이해하는 데 문제가 있습니다. C++에서 나는이 작업을 수행 할 수있을 것입니다 : 내가 지적하고 싶은 것은 PraseData()를 여러 번 호출 할 것입니다, 매번 새로운 데이터 블록은 파일에서 구문 분석됩니다클래스의 lisp 파일 포인터

class Foo { 
    Foo (string filename); // opens the file (my_file) requested by the filename 
    ~Foo(); // close the file 

    FILE * my_file; // a persistent file-handle 
    DataStruct my_data; // some data 

    void ParseData(); // will perform some function on the file and populate my_data 
    DataStruct * GetData() { return &my_data; } // accessor to the data 
}; 

my_data가 변경됩니다.

내가 CLOS에서 같은 트릭을 수행하려고 해요 - 나는 등이 헤더 등뿐만 아니라 클래스 정의를 읽고, 파일을로드, 데이터를 분석하는 모든 일반적인 방법을 만듭니다

(defclass data-file() 
    ((filename :initarg :filename :accessor filename) 
    (file :accessor file) 
    (frame :accessor frame))) 

"생성자"(즉 initialize-instance)에서 파일을 내 C++ 관용어로 엽니 다. 그런 다음 데이터에 액세스 할 수 있으며 이전과 같이 데이터를 구문 분석 할 수 있습니다. 그러나 "destructor"또는 (finalize) 메서드를 사용하여 파일을 닫는 것이 파일을 필요로하는 이런 유형의 상황을 처리하는 관용 CLOS가 아니므로 데이터 파일 외부에서 액세스 할 수 있다고 들었습니다. 행동 양식.

데이터 파일을로드하고 데이터를 사용하여 일련의 분석을 수행 한 다음 잘하면 닫는 함수를 정의 할 것입니다. 이 일을 처리하는 방법은 무엇입니까? (매크로 나 어떤 유형의 클로저가 여기에서 작동한다고 가정하고 있지만, 필요한 부분이나 구현 방법을 결정하는 데 익숙하지 않습니다.)

(with-open-file (stream file) 
    (let ((foo (make-instance 'foo :stream stream))) 
    (frob foo) 
    (...other processing of foo...))) 

그런 다음 스트림이 자동으로 종료됩니다

답변

6

하나의 옵션은 WITH-OPEN-FILE과 슬롯 대신에 파일 이름, 그리고 범위 그것으로 스트림을하는 것입니다.

+0

초기 새가 대답을 얻습니다. –

3

나는 완전한 권위있는 데이터 (당신이 DataStruct라고 부르는 것)를 저장하기 위해서만 클래스를 만드는 것에 의지한다고 생각한다.

"다른 클래스의로드 + 저장"을 위해 특별한 클래스가 실제로 필요하지 않습니다. 게다가, 그런 식으로 말해서, my_data가 my_file의 데이터를 현재 탐색 위치까지 보유하고있는 무언의 불변성이 있습니다. 이것은 내 눈에 이상하게 보입니다.

다른 말로 표현하면 Foo는 무엇을하나요? 파일 이름을 주면 데이터를로드하고 DataStruct를 제공합니다. 그것은 나에게 기능처럼 들린다. 스레드에서 실행하거나 레코드를로드하는 사이에 이벤트를 발생시킬 수 있어야하는 경우 클래스는 C++에서 자연스럽게 수행하는 방법이지만 Lisp에서는 그러한 클래스를 필요로하지 않습니다.

또한 CLOS에서 일반 메소드를 사용하려면 DEFCLASS를 사용할 필요가 없습니다.

데이터 구조가 무엇인지 모르겠지만 유사한 상황에서 스트림을 취하여 하나의 레코드를 반환하는 구문 분석 one-chunk 함수를 만든 다음 with-open-file에서 반복하십시오. 스트림이 열린 파일 확장 범위 밖에서 절대로 필요하지 않은 경우 스트림을 닫을 때 걱정할 필요가 없습니다.

+0

나는이 문제를 파싱하는 데 어려움을 겪고 있지만, 통찰력에 감사드립니다. 사실 Foo는 파일을로드하고 DataStruct를 돌려 주지만 파일 포인터도 보유합니다. 파일이 일부 데이터에서 읽히지 않으면 새로운 위치로 이동해야합니다. 파일 포인터를 각각의 새로운 데이터 프레임으로 업데이트해야합니다. 귀하의 의견에서 수집 한 것은 파일 스트림을 조작하고 데이터를 구문 분석하기 위해 단일 개체를 사용하는 것이 아니라 데이터 구문 분석을 위해 주어진 파일 스트림을 사용할 수있는 개체를 만드는 것이 더 좋을 것입니다. 파일 및 다른 곳에 스트림. 정확하니? – Shamster

+0

그리고 나는 당신의 의견으로 유사하게 혼란 스럽다고 생각합니다. "데이터 파싱을 위해 주어진 파일 스트림을 취할 수있는 개체 만들기"-> 물론이 "개체"는 "함수"라고 부릅니다. :-) 나는 "class Foo"뒤에있는 목적을 여기 실제로 보지 못했다. 계속되는 상속은 없습니다. 그것은 입력, 출력, 임시 및 시작, 중간 및 끝에서 실행할 수있는 코드가 있습니다. 내 세계에서 이것은 클래스가 아니라 함수를 설명합니다. 그러나 나는 문맥을 완전히 이해하지 못한다. – Ken

+0

켄 : 잘 넣어. 나는 함수/클래스를 형성하는 것을 배워서 특별한 틀에 박혀 있었기 때문에 통찰력에 감사드립니다. 이 경우, "신뢰할 수있는 데이터"를 보유 할 DataStruct 이외의 객체를 만들고 그 주위에서 스트림 조작을 수행하는 함수를 작성할 이유가 없습니다. – Shamster

관련 문제