新しい$titleでConfigクラスのadd(), put()を使う際の不良について

  • ページ: BugTrack2
  • 投稿者: token?
  • 優先順位: 重要
  • 状態: 却下
  • カテゴリー: 本体バグ
  • 投稿日: 2007-11-14 (水) 17:55:45
  • バージョン: 1.4.7_notb UTF-8

メッセージ

このバグが想定外かどうかで議論は分かれると思うので、まずは想定の範囲内かどうか判断してもらわないと。また、この問題自体が想定しているのは、:configのフォーマットが次のタイプです。

*title
|col|col|h
|val1|val2|
|val3|val4|

A.次の項目までが想定内ならバグではありません。

  • :configから、ヘッダ($title)と表($values)を元にオブジェクトを取得する
  • 取得したオブジェクトの行を書き換えるて:configに保存する
  • 取得したオブジェクトに行を追加して:configに保存する

理由

:configへの書き込みは、Config#write()を使います。Config#write()はConfigTableクラスとそのサブクラスが持つtoString()が返す値を該当ページへ書き出す役割となっています。Config#read()で得られたConfigTableとそのサブクラスは、読み込み対象が表(段組)なので、ConfigTable_Sequentialでしょう。Config#read()で作成したConfigTable_Sequentialは、:configへの書き込みに適したフォーマット(要所に改行文字を含む)を返してくれますので、問題ありません。

B.次の項目までが想定内ならバグでしょう。

  • :configへ、新しいヘッダ($title)と新しい表($values)を追加する。

理由

&get_object()がConfigTableをレベル1で生成する

例えば、新しいヘッダ($title)をConfig#&get_object($title)に渡して実行すると、新しくConfigTableオブジェクトを生成して返します。add(),put()に$titleを渡しても同様の動きを見せます。&get_object()が生成するConfigTableは、"*"+$titleなので、:configに書かれているデータは常にConfigTableを生成する条件に一致するものになります。

ConfigTable#toString()は$titleしか出力しない

そのまま、Config#write()をするとConfigTable#toString()は$titleしか返してくれません。その為、新しい表($values)は無視されてしまい、:configへの書き込みは$titleのみとなります。

Config#read()し直しても該当箇所はずっとConfigTable型になる

また、Config#read()は:configのフォーマットから格納するデータ型をConfigTable, ConfigTable_Sequential, ConfigTable_Directに振り分けて自インスタンスに保持します。しかし、対象はレベル1のConfigTable型なので、ConfigTableが返される条件と一致します。

ConfigTableのコンストラクタの使い方一つで出力フォーマットが変わる

$ab =& $this->config->get_object("test_titleXX");
$ab = new ConfigTable_Sequential("test_titleXX");
$ab->add_value(array('00000','11111'));

例えば、Config#objsにConfigTable_Sequentialオブジェクトを追加して、値を追加したとします。Config#write()の際に期待されるフォーマットは次の通りですが、

*test_titleXX
|00000|11111|

実際は次の通りです

*test_titleXX|00000|11111|

Config#read()経由で作られたConfigTable_Sequentialは、$beforeに$title+"\n"を追加して保存します。その理由は、

new ConfigTable_Sequential($title, $configtable_object)

の形で使っている為次の様に書けば改行が追加されます。

$ab =& $this->config->get_object("test_titleXX");
$ab = new ConfigTable_Sequential("test_titleXX", $ab);
$ab->add_value(array('00000','11111'));

条件を判断してるところは、ConfigTable_Sequential, ConfigTable_Directはコンストラクタを持たないのでConfigTableのコンストラクタが処理をしてます。

提案

&get_object()ではConfigTableを生成しない

この部分の書き換えは、既存の:configから読み込みには影響しないと思います。読み込みでは、:configに存在しない$titleを指定する理由がありません。事故で想定していた$titleが見付からなかった場合等は、Configクラスの誤りではなく:configの誤りでしょう。指定された$titleは無いと返す方が最善だと思います。

メソッド追加 : add_object($config_table)

ConfigTableとそのサブクラスを追加するメソッドを別途作成します。Configの中のオブジェクト配列への追加はこのメソッドに限定するべきです。引数の$config_tableはConfigTable型です。プリミティブな値を渡してメソッド内で判断するより、初めから型が決まったものを渡す方が後々面倒な事が起こらないでしょう。

但し、$title+"\n"が修正されなければ、期待しない文字が書き込まれる事になります。

$title+"\n"の形に修正

出力に関係する事なので、各toString()で対応すれば良いと思います。また、$beforeに格納する前に"\n" を除去しておくとか。他で"\n"を探さないのなら、この方が良さそうです。

ConfigTableをabstractに変更

:configへ書き込まれるフォーマットによってConfig#read()が型を決めている為、親クラスであるConfigTableの#toString()が特定フォーマットを出力するのは好ましくありません。それぞれの子クラスで$titleを含めた形でoverrideされているの為、ConfigTable#toString()は不要だと思われます。

また、一時データの受け皿として使うなら良さそうですが、フォーマットとデータ型が密接なので、最終的な受け皿としてConfigTableを使うべきじゃないと思います。


コメント

  • 関連: PukiWiki/1.4/プラグイン開発を便利に (pconfig.php をベースに、config.php が作られた) -- 2007-11-14 (水) 20:36:49
    • なるほど、pconfig.phpベースなら新規追加は想定されてませんね。 -- token? 2007-11-14 (水) 22:18:26
    • でも、存在しない$titleを渡した場合、書き戻しが出来ないオブジェクトが返されるのは、何をしようとしてたんでしょう? -- token? 2007-11-14 (水) 22:20:41
  • バグではない様なので、状態を却下に変えました。 -- token? 2007-11-27 (火) 23:40:45

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-11-27 (火) 23:40:45
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u8. HTML convert time: 0.455 sec.

OSDN