2016-08-22 5 views
0

私は、1つの変数を格納し、その変数に特定の関数を持たせる方法を知りたいと思います。私はクラスを作成するための選択肢があるのだろうかと思っています。クラスを使うためのCommon Lispの代替方法

具体的には、基本時間から経過した秒数を表す時間値を格納するアプリケーションを作成しています(たとえば、Jan 1、2000、00:00:00)。私は秒から特定の時刻または日付に、または日付を特定の秒に変換するなど、この値の操作を実行したいと思います。

私はこれをクラスを使って行っていますが、無駄に思えます。具体的には、保存された値に秒単位でアクセスするたびに、(time-time time)と似たようになります。ここで、は、時間インスタンスtimeのアクセサーです(time-time)。

おそらくクラスを使わないでこれを設計するより良い方法はありますか?

+2

整数として保存するだけではどうですか? – jkiiski

+2

標準の一部である[universal time functions](http://www.lispworks.com/documentation/HyperSpec/Body/f_get_un.htm)を使用したくないということを明確にするには? –

+0

頻度順に何をしていますか?それは特定の時間ですか、あるいはあなたのオフセットからの経過時間がありますか? – Sylwester

答えて

3

クラスが1つのオブジェクトをラッピングするだけで、そのオブジェクトが既知の型を持つ場合は、代わりにそのオブジェクトのクラスのメソッドを書くことができます。

(defmethod time-as-unix-time ((tm integer)) 
    (- tm (load-time-value (encode-universal-time 0 0 0 1 1 1970 0)))) 

たとえば、次のようになります。

もちろん、オブジェクト指向の熱狂者たちは、あなたがこのようなことをしてくれるならば、スパイクでいっぱいのピットにあなたを投げるでしょう。疑いなくカプセル化やカルトの他のルールに違反することは間違いありません。

+1

メソッドをクラスを使用せずにタイプ別に制限することはできますか? – audrow

+0

@audrowまあ、あなたはクラスを使っているだけです。[組み込み型](http://www.lispworks.com/documentation/HyperSpec/Body/t_built_.htm#built-in-class)です。あなたは他のどのクラスに対してもできる 'built-in-class'のためのどんな種類のメソッドも定義することができます:あなたがすることができないものはそれをサブクラス化するものであり、標準以外のスロットまたは他の属性を持ちませんそれを定義します。 – tfb

+0

私は参照してください。ありがとうございました。 – audrow

2

あなたは、このようなレキシカルスコープ上の閉鎖を試みることができる:

(let ((time (get-universal-time))) 
    (defun set-time(tm) 
    (setf time tm)) 

    (defun get-time() 
    time) 

    (defun get-time-in-some-other-format() 
    ;; calculate return value based on 'time' 
    ) 
) 
+0

これは 'let((time(get-universal-time))))')にしたいと思ったでしょうか?これは代替方法ですが、時間構造のインスタンスを1つしか持てないようにしています。それは不便かもしれません... –

+0

オススメのために申し訳ありません、今修正されました。 –

+0

これは美しいです。私は、この例の前にレキシカルスコープでクロージャーを使用する方法を理解していませんでした。ありがとうございました。 – audrow

5

アクセサ名

あなたはCLOSでアクセサあなたが好きなように名前を付けることができます。アクセサ関数は、secondsと呼ばれることができる:一般的なLispは、フォームWITH-ACCESSORSを有する

アクセサ関数を介してスロットに

CL-USER 23 > (defclass mytime() 
       ((seconds :accessor seconds :initarg :seconds))) 
#<STANDARD-CLASS MYTIME 422015CDD3> 

CL-USER 24 > (let ((mt (make-instance 'mytime :seconds 100))) 
       (values (seconds mt) 
         (truncate (seconds mt) 60))) 
100 
1 

短いアクセス。これにより、特定のCLOSオブジェクトに対して、コード内のアクセサフォームの代わりにシンボルを使用することができます。次の例ではsecsを使用できますが、コード内の変数のように見えますが、Common Lispは実際にアクセッサーsecondsを呼び出していることを確認します。 (seconds mt)の代わりにsecsと書くことができます。したがって、囲まれたコードを短くすることができます。上記のコードと次の例を比較してください。

CL-USER 25 > (let ((mt (make-instance 'mytime :seconds 200))) 
       (with-accessors ((secs seconds)) 
        mt 
       (values secs (truncate secs 60)))) 
200 
3 

SLOT-VALUE

CLOSを介してスロットに短いアクセスもここmytimeインスタンスのseconds命名スロット名secsを介してアクセスすることができ、スロット名を介して、スロットアクセス用WITH-SLOTSを有する:

CL-USER 26 > (let ((mt (make-instance 'mytime :seconds 200))) 
       (with-slots ((secs seconds)) 
        mt 
       (values secs (truncate secs 60)))) 
200 
3 
関連する問題