vieweditattachhistoryswikistopchangessearchhelp

YASOS で bank-account

Gauche で SLIB の YASOS を使って、bank-account を書いてみました。--sumim
(use slib)
(require 'oop)
(define print (with-module gauche print))

(define-predicate bank-account?)
(define-operation (dollars obj))
(define-operation (dollars! obj new-dollars))
(define-operation (deposit! obj delta-dollars))
(define-operation (withdraw! obj delta-dollars))

(define (bank-account the-dollars)
  (object
    ((bank-account? self) #t)
    ((dollars self) the-dollars)
    ((dollars! self val) (set! the-dollars val) self)
    ((deposit! self val) (dollars! self (+ (dollars self) val)) self)
    ((withdraw! self val) (dollars! self (max (- (dollars self) val) 0)) self)))

(define my-account (bank-account 200))
(dollars my-account)
=> 200

(dollars (deposit! my-account 50))
=> 250

(dollars (withdraw! my-account 100))
=> 150

(dollars (withdraw! my-account 200))
=> 0

(define-predicate stock-account?)
(define-operation (num-shares obj))
(define-operation (num-shares! obj new-num-shares))
(define-operation (price-per-share obj))
(define-operation (price-per-share! obj new-price-per-share))

(define (stock-account the-num-shares the-price-per-share)
  (object-with-ancestors ((a-bank-account (bank-account 0)))
    ((stock-account? self) #t)
    ((num-shares self) the-num-shares)
    ((num-shares! self val) (set! the-num-shares val) self)
    ((price-per-share self) the-price-per-share)
    ((price-per-share! self val) (set! the-price-per-share val) self)
    ((dollars self) (* (num-shares self)) (price-per-share self)))
    ((dollars! self val) (num-shares! self (/ val (price-per-share self))) self)))

(define my-stock (stock-account 10 30))
(dollars my-stock)
=> 300

(dollars (dollars! my-stock 600))
=> 600

(dollars (deposit! my-stock 60))
=> 660

(num-shares my-stock)
=> 22

(dollars (withdraw! my-stock 120))
=> 540

(num-shares my-stock)
=> 18



プロトタイプベースっぽい bank-account も書いてみました。--sumim
(use slib)
(require 'oop)
(define print (with-module gauche print))

(define-predicate bank-account?)
(define-operation (dollars obj))
(define-operation (dollars! obj new-dollars))
(define-operation (deposit! obj delta-dollars))
(define-operation (withdraw! obj delta-dollars))

(define bank-account
  (let ((the-dollars 200))
    (define me
      (object
        ((bank-account? self) #t)
        ((dollars self) the-dollars)
        ((dollars! self val) (set! the-dollars val) self)
        ((deposit! self val) (dollars! self (+ (dollars self) val)) self)
        ((withdraw! self val) (dollars! self (max (- (dollars self) val) 0)) self)))
    me))

(dollars bank-account)
=> 200

(dollars (deposit! bank-account 50))
=> 250

(dollars (withdraw! bank-account 100))
=> 150

(dollars (withdraw! bank-account 200))
=> 0

(define my-account
  (let ((the-dollars 0))
    (define me
      (object-with-ancestors ((proto bank-account))
        ((dollars self) the-dollars)
        ((dollars! self val) (set! the-dollars val) self)))
    me))

(dollars (dollars! my-account 500))
=> 500

(dollars bank-account) ;; プロトタイプのスロットには影響が及ばない
=> 0

(dollars (deposit! my-account 50)) ;; プロトタイプのメソッドを起動
=> 550

(dollars (withdraw! my-account 80)) ;; プロトタイプのメソッドを起動
=> 470

(define-predicate stock-account?)
(define-operation (num-shares obj))
(define-operation (num-shares! obj new-num-shares))
(define-operation (price-per-share obj))
(define-operation (price-per-share! obj new-price-per-share))

(define stock-account
  (let ((the-num-shares 10) (the-price-per-share 30))
    (define me
      (object-with-ancestors ((proto bank-account))
        ((stock-account? self) #t)
        ((num-shares self) the-num-shares)
        ((num-shares! self val) (set! the-num-shares val) self)
        ((price-per-share self) the-price-per-share)
        ((price-per-share! self val) (set! the-price-per-share val) self)
        ((dollars self) (* (num-shares self) (price-per-share self)))
        ((dollars! self val) (num-shares! self (/ val (price-per-share self))) self)))
    me))

(dollars stock-account) ;; オーバーライドした dollars を起動
=> 300

(dollars (dollars! stock-account 600)) ;; オーバーライドした dollars! を起動
=> 600

(dollars (deposit! stock-account 60)) ;; プロトタイプの deposit! を起動し、dollars、dollars! で多態
=> 660

(num-shares stock-account)
=> 22

(dollars (withdraw! stock-account 120)) ;; プロトタイプの withdraw! を起動し、dollars、dollars! で多態
=> 540

(num-shares stock-account)
=> 18

(define my-stock
  (let ((the-num-shares 0) (the-price-per-share 30))
    (define me
      (object-with-ancestors ((proto stock-account))
        ((num-shares self) the-num-shares)
        ((num-shares! self val) (set! the-num-shares val) self)
        ((price-per-share self) the-price-per-share)
        ((price-per-share! self val) (set! the-price-per-share val) self)))
    me))

(dollars (dollars! my-stock 150))
=> 150

(num-shares my-stock)
=> 5

(num-shares stock-account) ;; プロトタイプのスロットには影響が及ばない。
=> 18



多重継承ができることを利用して、スロット保持とアクセッサはさらに別オブジェクトに委譲してよりシンプルに。--sumim
(use slib)
(require 'oop)
(define print (with-module gauche print))

(define-predicate bank-account?)
(define-operation (dollars obj))
(define-operation (dollars! obj new-dollars))
(define-operation (deposit! obj delta-dollars))
(define-operation (withdraw! obj delta-dollars))

(define (make-dollars the-dollars)
  (object
    ((dollars self) the-dollars)
    ((dollars! self val) (set! the-dollars val) self)))

(define bank-account
  (object-with-ancestors ((slots (make-dollars 200)))
    ((bank-account? self) #t)
    ((deposit! self val) (dollars! self (+ (dollars self) val)) self)
    ((withdraw! self val) (dollars! self (max (- (dollars self) val) 0)) self)))

(dollars bank-account)
=> 200

(dollars (deposit! bank-account 50))
=> 250

(dollars (withdraw! bank-account 100))
=> 150

(dollars (withdraw! bank-account 200))
=> 0

(define my-account
  (object-with-ancestors ((slots (make-dollars 0)) (proto bank-account))))

(dollars (dollars! my-account 500))
=> 500

(dollars bank-account) ;; プロトタイプのスロットには影響が及ばない
=> 0

(dollars (deposit! my-account 50)) ;; プロトタイプのメソッドを起動
=> 550

(dollars (withdraw! my-account 80)) ;; プロトタイプのメソッドを起動
=> 470

(define-predicate stock-account?)
(define-operation (num-shares obj))
(define-operation (num-shares! obj new-num-shares))
(define-operation (price-per-share obj))
(define-operation (price-per-share! obj new-price-per-share))

(define (make-shares the-num-shares the-price-per-share)
  (object
    ((num-shares self) the-num-shares)
    ((num-shares! self val) (set! the-num-shares val) self)
    ((price-per-share self) the-price-per-share)
    ((price-per-share! self val) (set! the-price-per-share val) self)))

(define stock-account
  (object-with-ancestors ((slots (make-shares 10 30)) (proto bank-account))
    ((stock-account? self) #t)
    ((dollars self) (* (num-shares self) (price-per-share self)))
    ((dollars! self val) (num-shares! self (/ val (price-per-share self))) self)))

(dollars stock-account) ;; オーバーライドした dollars を起動
=> 300

(dollars (dollars! stock-account 600)) ;; オーバーライドした dollars! を起動
=> 600

(dollars (deposit! stock-account 60)) ;; プロトタイプの deposit! を起動し、dollars、dollars! で多態
=> 660

(num-shares stock-account)
=> 22

(dollars (withdraw! stock-account 120)) ;; プロトタイプの withdraw! を起動し、dollars、dollars! で多態
=> 540

(num-shares stock-account)
=> 18

(define my-stock
      (object-with-ancestors ((slots (make-shares 0 30)) (proto stock-account))))

(dollars (dollars! my-stock 150))
=> 150

(num-shares my-stock)
=> 5

(num-shares stock-account) ;; プロトタイプのスロットには影響が及ばない。
=> 18

このページを編集 (7930 bytes)


Congratulations! 以下の 3 ページから参照されています。

This page has been visited 3509 times.