SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

知っておきたいCurl文法の要点(AD)

ここがポイント!Curlプログラミング
null値の取り扱い(キャスト・マクロの利用)

第2回

  • このエントリーをはてなブックマークに追加

uninitialized-value-for-typeマクロ

 クラスを定義した場合、フィールドの型にnull値を許すか否かについては、結構悩むところです。null値を許さないフィールドの方が利用する場合に便利なのですが、初期値としてなんらかの値を与えておく必要があります。

 変数に初期値は設定できない(しにくい)けれど、非null値の変数を定義したい場合、uninitialized-value-for-typeマクロを使うことで、null値を許さない変数に対して一時的にインスタンスが未設定の状態を作り出すことができます。実際にクラスを作成し、フィールドで利用している例を示します。

コード7
{curl 7.0 applet}
{curl-file-attributes character-encoding = "shift-jis"}

|| クラス
{define-class public Child

  field public name:String = {uninitialized-value-for-type String}

  {getter public {pet-name}:String
    {return self.name & "ちゃん"}
  }  
}

{value
    let a:Child = {Child}
    let b:Child = {Child}
    
    set a.name = "さり"
    set b.name = "まい"
    
    a.pet-name & "と" & b.pet-name & "はお友達"
}

 実行した結果(図2)です。

図2
図2

 uninitialized-value-for-typeマクロを使った変数には、どのような値が入っているのでしょうか? デバッガで変数aのインスタンスを生成した所で止めて、nameフィールドの値を見ます(図3)。

図3
図3

 uninitialized-value-for-typeマクロを使ったnameフィールドの値は「null」でした。このマクロは、コンパイラを一時的にだましていることになります。フィールドを読み出す前に値が設定されることが確実な時だけ利用しましょう。値が設定されていないのに値を読み出せば、当然Exceptionが発生することになります。

まとめ

 最後に今まで説明してきたマクロを実際に利用するサンプルを見ていきましょう。1人の子供をあらわすChildクラスを定義しています。コンストラクタで名前を指定し、set-friendメソッドでお友達の名前を追加していきます。

コード8
{curl 7.0 applet}
{curl-file-attributes character-encoding = "shift-jis"}

|| こどもクラス
{define-class public Child

  || 名前フィールド
  field public name:String = {uninitialized-value-for-type String}
  
  || コンストラクタ
  {constructor public {default name:String}
    set self.name = name
  }
  
  || 友達リスト
  field private _friend-list:#{Array-of String} = null

  || ゲッターでインスタンスを生成
  {getter public {friend-list}:{Array-of String}
    {if self._friend-list == null then
        set self._friend-list = {{Array-of String}}
    }
    {return {non-null self._friend-list}}
  }
  
  || 友達を設定する
  {method public {set-friend name:String}:void
    {self.friend-list.append name}
  }

  || 友達全員の文字列を返す
  {getter public {size}:int
    {return
        {if-non-null friend-list = self._friend-list then
            friend-list.size
         else
            0
        }
    }
  }
}

{value
    let mai:Child = {Child "まいちゃん"}
    {mai.set-friend "まなちゃん"}
    {mai.set-friend "としくん"}
    {mai.set-friend "かっちゃん"}
    {mai.set-friend "みーちゃん"}
    {format "%sの友達は%d人です。", mai.name, mai.size}
}

 実行結果です(図4)。

図4
図4

 Childクラスのnameフィールドは、{uninitialized-value-for-type String}により定義されており、コンストラクタで値が入ります。よって、#Stringにする必要がありません。

 友達のリストを表す _friend-list フィールドは、#{Array-of String}となっており、友達リストが使われた時に初めてインスタンスを生成しています。インスタンスを遅延生成することで、Childクラスの生成を高速化できます。ここでは、フィールドは、#{Array-of String}ですが、ゲッターを {Array-of Stirng}にすることで、利用する時にnull値判定が不要になり使い勝手が良くなります。

最後に

 Curl言語の特徴的な機能である、null値の取り扱いについて見てきました。曖昧なnull値の利用を排除することで質の高いプログラムを書くことが可能です。マクロを利用することで、他の言語と比べても遜色なく効率よくコードを書くことができます。マクロの1つ1つはとても簡単な内容ですので、ぜひ利用してみてください。

修正履歴

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
知っておきたいCurl文法の要点連載記事一覧

もっと読む

この記事の著者

久保田 一郎(クボタ イチロウ)

財団法人日本自動車研究所電算システムGr所属。Macintosh HyperCardとOracleを使った業務システムの開発から始まって、4D、Java、AIRを経由してCurl に到達。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4333 2009/09/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング