[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

10.6 srfi-9 - レコード型

Module: srfi-9

このモジュールはレコード型を使うマクロを含んでいます。レコード型は Gauche のオブジェクトシステム上で実装されています。

SRFI-9 のレコード型はオブジェクトシステムほどには強力ではありませんが、 ポータブルなプログラムを書くときには役に立ちます。

ちなみに、レコード型に対するSCMコンパチブルな 手続き的APIを提供するutil.record - SLIB-互換のレコード型モジュールもあります。

Macro: define-record-type name (constructor init-tag …) predicate (field accessor [modifier]) …

レコード型を作成し、それを name に束縛します。Gauche では、 レコード型は <record> のサブクラスです。

constructor はそのレコード型のインスタンスを作成する手続きに 束縛されており、init-tag … として多くの引数をとります。 それぞれの init-tag はフィールド名に対応しており、作成された レコード型のインスタンスのフィールドはそれぞれの init-tag にしたがって、初期化されます。init-tag には全てのフィールドが ある必要なはく、初期化されないフィールドは、未束縛のままになります。

predicate は、一つの引数をとり、もしその引数が、定義された レコード型のインスタンスであれば、#t を返し、さもなければ、 #f を返すような手続きに束縛されます。

そのあとは、フィールドの仕様です。レコードはフィールド field … をもち、それぞれのフィールドはメソッド accessor によってアクセス可能です。そのフィールドに対して modifier が与えられていれば、それは、そのフィールドの 値をセットするメソッドに束縛されます。

例:

 
(define-record-type pare
  (kons x y) pare?
  (x kar set-kar!)
  (y kdr))
 ⇒ #<class pare>

(pare? (kons 2 3)) ⇒ #t
(pare? (cons 2 3)) ⇒ #f

(kar (kons 2 3)) ⇒ 2
(kdr (kons 2 3)) ⇒ 3

(let ((x (kons 2 3)))
  (set-kar! x -1)
  (kar x)) ⇒ -1

概念的には、上の例は以下の形式のならびに展開されます。

 
(define-class pare (<record>) (x y))
(define (kons x y)
  (let ((obj (make pare)))
    (slot-set! obj 'x x) 
    (slot-set! obj 'y y)
    obj))
(define (pare? obj) (is-a? obj pare))
(define-method kar ((obj pare))
  (slot-ref obj 'x))
(define-method set-kar! ((obj pare) value)
  (slot-set! obj 'x value))
(define-method kdr ((obj pare))
  (slot-ref obj 'y))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by Shiro Kawai on November, 22 2009 using texi2html 1.78.