またまた、謎が生まれちゃいました。
RecordSetにデータを追加などするときは、RecordDataクラスのオブジェクトなのに、取得するときはBasicRecordなのはなんでですか??
ややこしいので、同じにすればいいと思うんですが。。。
Code:
def rs =
{RecordSet
{RecordFields
{RecordField "id"}, {RecordField "name"}
},
{RecordData id = "01", name = "hoge"},
{RecordData id = "02", name = "foo"}
}
{for r in rs do
{dump {type-of r}} || BasicRecordがでちゃった。
}
よろしくです。
- B
(08-17-2011, 10:30 AM)nasuB Wrote: [ -> ]またまた、謎が生まれちゃいました。
RecordSetにデータを追加などするときは、RecordDataクラスのオブジェクトなのに、取得するときはBasicRecordなのはなんでですか??
ややこしいので、同じにすればいいと思うんですが。。。
はじめて書き込みます。
nmyzkと申します。
簡単に言うと、RecordDataがあるのは
「プログラムを簡単に書くため」です。
もしRecordDataが無かったら、
nasuBさんの書いたプログラムは
↓このような書き方をしなければなりません。
Code:
def rs = {RecordSet
{RecordFields
{RecordField "id"},
{RecordField "name"}
}
}
let r:Record = {rs.new-record}
set r["id"] = "01"
set r["name"] = "hoge"
{rs.append r}
set r = {rs.new-record}
set r["id"] = "02"
set r["name"] = "foo"
{rs.append r}
{rs.commit}
{for r in rs do {dump {type-of r}}
かなり冗長な感じがしませんか?
ちなみにこのサンプルはフィールドが2つですし、
取り扱うRecordSetのオブジェクトも1つなので
まだいいですが、
これが何十フィールド、何オブジェクトもを
同時に扱うとなると、いきなりややこしくなります。
でも、RecordDataなら1行でまとめることもできるのです。
あと、RecordDataが内部でRecord(BasicRecord)に変換されるのは、
RecordDataの柔軟性を持ったまま、RecordSetが実現する
高速処理を行うのが難しいからだと思われます。
この先は挙動に基づく推測も含まれますので
次の返信で掲載します。
お暇な方はお読みください。
上記返信に補足します。
RecordSetはデータを管理するために、オブジェクト生成時に
RecordFieldsオブジェクトでフィールド構造を定義します。
この処理を行うことで入力されるデータの厳格化を行いつつ、
高速にアクセスしやすい構造を内部的に作っているのだと理解しています。
RecordSetに紐付くRecordオブジェクトは全て
リンクされているRecordSetを参照しており、
RecordSetを経由してフィールド情報を確認しています。
このRecordSetとRecordFields、Recordの絶妙な関係で
RecordSetのデータの安全性と高速性が保たれています。
しかし、この構造にはコーディング上の大きな問題があります。
C#のDataTableなど同じようなデータ構造を保持できるものは
どれでも似たような問題を抱えているのですが、
「RecordSetが参照しているフィールドの名前を記憶していないと、
データ入力のコーディングを行う際にエラーになる。
しかし、そのエラーは実行するまで検出されない。」
というものです。
これはプログラマにとっては非常に厄介で、
スペルミスがあってもコードが通ってしまうため
デバッグのときに苦労する羽目に陥りがちです。
これに対してC#では、RecordSetに相当するDataTableクラスのサブクラスを
データの種類ごとに設けて、カラムの値をフィールド変数にすることで
問題の解決を図りました。
これはVisual Studioの入力補完機能と合わせることで
デバッグ能力を飛躍的に向上させた反面、
サブクラスの増加に伴う使用メモリ増大の問題を起こしています。
CurlでもC#と同じ実装方法をとることは出来ますが、
「クライアントの環境に捉われず、高速な処理を実現する」
という言語の基本命題を考えると同じ轍を踏むのは避けたいところです。
そこで、CurlとしてはRecordDataのようなデータ書き込み用のクラスを用意して、
コーディングの可読性を上げることで
デバッグの効率を上げることを目指したのではないのでしょうか?
もっとも、RecordDataを用いた方法だと
エラーの発生箇所が変わってしまうため、
どちらが良いのかは好みによると思います。
すいません、補足の補足です。
書いた後から気づいたのですが、
Recordオブジェクトに値をsetすると
RecordSetEventがRecordSet側で働いてしまうので、
データを追加する際の処理効率が落ちるかもしれないですね。
そういった意味では、
RecordとRecordDataの関係が判りにくくても、
RecordDataを使うことが推奨されます。
nmyzkさん
ずらずら長文返信、ありがとうございます!!
最終的な結論がわかりずらかったですが、
結局は、Recordで本来は良かったところをもっと簡易にコードを書くために
RecordDataが用意されているということですか??
質問多くてすいませんずら。
- B
(08-18-2011, 05:35 PM)nasuB Wrote: [ -> ]結局は、Recordで本来は良かったところをもっと簡易にコードを書くために
RecordDataが用意されているということですか??
冒頭に書いたとおりで、端的に言うとそうです。
コードを判りやすく簡単に書けることは開発効率向上につながりますからね。
それを実現するために調整した仕様だというのが考えです。
nmyzkさん
回答、ありがとうございます!!
非常に参考になりました。
開発生産性は、学習に関するコストも影響しますので、
こういった悩ませる要素を排除してもらえると助かりますよね。。
Curl RTEの開発チームの人がこのメッセージを見て、改善を検討してもらえるとありがたいですね。
-B