スキップしてメイン コンテンツに移動

投稿

7月, 2014の投稿を表示しています

JSON のオブジェクトを ID でリンクする(5)

JSON のオブジェクトを ID でリンクする(4) - SakuraCrowd’s blog  の続きです。 jsonId を利用しようとしていた仕様が変わってしまい、必要なくなったのでいったん保留します。 とはいっても、 {"$ref":"id1"} などの ID から、その ID を持つオブジェクトの参照への変換、逆変換の簡単なテストをクリアする実装もできたので、記念として gist にしました。長いので最後にはっときます。   jsonId の実装について gist のコメントに書いてありますが、循環参照は jsonId の置換では問題にならないのでエラー検出はしないことにしました。 JSONPath でルートの "$" のときに jsonPath.eval の第一引数を対象にしたかったのですが、空の配列が返されてしまっていたので、その部分だけ条件文で特別に処理しました。 "$[0]" などはルート配列の1番目の要素の参照を取得できるので、 jsonPath.eval(...)[0]を使っています。 反省点 jsonId を使わない仕様をなぜ最初に気づけなかったか。 それは、なるべく作成する機能に汎用性を持たせたいという悪いくせがでたためだと思います。 tmx のプロパティの編集がやりづらいので、他の json ファイルに細かい設定を書いてそれを参照させようというのがきっかけでした。 しかし、実際に自分が必要とする設定は tmx のプロパティに CSV などで4つくらいのパラメータを書くだけですむものでした。 それがなぜか、もっと複雑なものも簡単に設定したいというあいまいな仕様になってしまいました。 実際に使うデータを処理できるだけで十分だということを念頭において仕様を考えるようにしたいです。   cocos2d-js-3.0-rc0  が使えるようになりました(∩´∀`)∩ワーイ setup.py をいちいち管理者権限で呼び出すのが面倒なのでバッチファイルを作りました。 2.2 のころと違って html を起動するだけというわけではなく、 cocos コマンドで実行するのが微妙に面倒ですが、ノードの親子関係に依存しないで奥行きを設定できたりするのが便利です。 project

JSON のオブジェクトを ID でリンクする(4)

gistb28ba8146f829f3f3254 JSON のオブジェクトを ID でリンクする(3) - SakuraCrowd’s blog  の続きです。前回まではテストケースをクリアする実装までいけていたのですが、今回はテストケースを書いたまでで、それを満たす実装は勉強中です。 いつもどおり、仕様の説明は gist のコメントに書いてあります。 簡単に言うと、 複数 のオブジェクトが集まっている構造の中で一部だけを処理できるようにしました。 それだけならば、その一部のオブジェクトを引数にくわせりゃいいじゃんと思うんですが、 ID からデータに置換するには JSONPath の 絶対パス を利用しています。 そのためルートが変わってしまうと ID からデータに置換できなくなってしまうのです。   JSONPath とか XPath とかパスもいろいろあるね(`・ω・´) そんなかんなで jsonPath を使って処理を開始するノード要素を取得する処理を追加しました。 最初にはまったのはルートは "$" だから jsonPath.eval(target, "$") とすれば target の値が返されると思ったところでした。 実際は空の配列が返って来ます。 XPath の仕様などの説明を読んだところ、どうやらルートノードとルート要素というものは別物らしいです。 そして JSONPath でルート要素を表す場合は "$.*" とします。 これで target の値が取得できました。   eval だからって、えばる(eval)な!←いってみたかっただけです>< しかし、今度は ret = jsonPath.eval(target, "$.*") が ret == target ですが ret !== target になっています! これでは、共通のオブジェクトへリンクする処理ではなく、同じ値を持つ別のオブジェクトへのリンクとなってしまいます。 どうすればいいのかなー。 現状はそんなところです。  

JSON のオブジェクトを ID でリンクする(3)

gist8e9a924f3090183b6a41 JSON のオブジェクトを ID でリンクする(2) - SakuraCrowd’s blog  の続きです。 詳しくは上記の gist のコメントに書きました。 前回は参照→オブジェクトへの変換だけでしたが、逆の変換の機能も追加しました。 参照とオブジェクトが混ざった状態から、オブジェクトだけに置換してしまうので、その後、どれがもともとオブジェクトだったのかわかりません。 そのため、変換の結果でそれを記録しておき、逆変換のときに利用します。 ない場合は、最初にみつけたオブジェクトの位置以外を参照に置き換えます。   git 苦手だったけどちゃんとできたよ(`・ω・´) subversion も使いこなしてたってわけではありません。 しかし git はもっとわからなかったしやってませんでした。 そんなでしたが、いい機会だしとやってみると以外に簡単にやれました。 tortoiseGIT っていう コンテキストメニュー 拡張のソフトを使いました。 バージョン管理したいファイルの置いてあるフォルダを選んで、「Git ここに リポジトリ を作成」を選ぶ。 管理したいファイルを選択して Git > 追加 メニューで追加する。 あとはコミットすればOK。 ついテンパったりめんどくなるとコピーして日付つけて 「どきっ!コピーだらけの開発フォルダ///」 になってしまうのですが、なるべく git とかで管理しようといつも思っています。   jasmine-node が動かないヽ(`Д´)ノウワァァァン!! 以前に、 npm install -g jasmine-node でちゃちゃちゃっとインストールしておいて、以前はたしか コマンドプロンプト から jasmine-node でいけたはずなのに、「cannot find module」とか「ファイルとして認識されません」とかでちゃった(∀`*ゞ)テヘッ なんか、いじっちゃったかなー、って 環境変数 とか確認してたけど、よくわからないまま3時間経過ヽ(`Д´)ノウワァァァン!! 自分の中ではこういう問題を 「環境系バグ('∀`)」 と呼び恐れています。 環境様を怒らせたらもう何がなんだかわからないバグがいっぱいでて(゚∀゚)アヒャ ヒャ ヒャ ヒャ ヒャ ヒャとなって

JSON のオブジェクトを ID でリンクする(2)

gistcf43df70ff1d946640af   JSON のオブジェクトを ID でリンクする - SakuraCrowd’s blog  の関数のテストケースの作成と実装を行いました。 関数の説明は gist のコメントに書きました。   JSONPath でいいんじゃね?->やっぱり ID もいるよね! リンクを展開していく際に、循環参照を検知したらエラーにして、発生した場所をメッセージで伝える仕様にしました。 その場所の表し方を検討していたところ、 JSONPath という XPath の JSON 版がみつかりました。 「あれ? ID とか独自仕様作らないで JsonPath でリンクすればいいんじゃね?(`・ω´・)」と思い始めました。 実際、それですんだら独自仕様なんて面倒なものから解放されるのでよいと思ったのですが、 ぐぬぬ と思う残念なところがあって、先日の提案どおり ID によるリンクにしました。 残念なところとは、上位へのアクセスを指示する .. が使えないことです。 .. 自体はあるのですが、 再帰 の指示で使われていて意味が異なりました。 これがないと、同じ階層にある他のオブジェクトを指すために 絶対パス が必要になると思います。 ID はプロパティを割り振る手間や重複などのデメリットがありますが、ユーザが簡単にオブジェクトを指すことができます。 もともと、この機能は TMX の中のオブジェクトの設定を簡単にするために作っています。 TMX 自体は XML で表されていて、それを tmx-parser で JavaScript のオブジェクトに変換します。 TMX の編集中に JSONPath を意識するのは難しいので、 ID によるリンクでよいと思いました。   開発環境とかコーディングルールとか 実際のところ、関数の作成よりも開発環境や基本的な書き方の勉強に時間がかかりました。 しかも、まだふわふわしています。   JavaScript のライブラリの書き方 (まだふわふわ) JavaScript によるライブラリの書き方は underscore.js を参考にしました。 無名関数の中で、ライブラリ用のプロパティを グローバル変数 に追加します。 同じ名前の変数がすでにある場合は直前まで割り当てられていた値に戻せる

JavaScript のテストフレームワーク Jasmine の勉強

Jasmine というテスト フレームワーク を勉強中です。 Jasmine を選んだ理由 クライアントサイドだけでなくサーバサイドもサポートしている クライアントサイドは jasmine standalone 、サーバサイドは jasmine-node が提供されている。 わりと人気がありそう 主観ですが、検索すると結構使われていそうでした。よらば大樹の陰。 Jasmine standalone を使ってみる バージョン 1.3 と 2.0 系があったので 2.0 系をダウンロードしてみました。 SpecRunner.html というそれっぽいのを起動すると、同梱しているサンプルのテストの実行結果が表示されました。 SpecRunner.html 内で、 フレームワーク の .js とテスト対象の .js とテストコードの .js を指定して利用します。 jasmine-node を使ってみる jasmine-node のバージョンは 1.14.3 となっていて、standalone と足並みそろってないのかなと思いました。 こちらは実行対象をファイル単位で指定せず、ディレクトリ単位です。 クライアントサイドのテストコードとの大きな違い クライアントサイドでは script タグで読み込むファイルを require で読み込む。 テスト対象の関数の代入先が違う。 クライアントサイドでは単純に関数を定義するだけでした。 var func1 = function(){...} jasmine-node では、 exports.func1 = func1; としたりして、 exports のプロパティに設定する必要がある。 これは Jasmine というよりクライアントサイドと node.js の違いかもしれません。 できたらクライアントサイドもサーバサイドもコードを共用したい クライアントサイドとサーバサイドでそれぞれネットで見つけた FizzBuzz のテストケースを実行できました。 できましたが、まだ不満があります。前述した違いを除くと、テストコードが同じであることです。 同じようなコードをクライアントサイドとサーバサイドの両方で書くことは、DRY のポリシーに反するような気がします。 そこで、同じファイルで実行できないか模索中です。 これは、 Jasm

JSON のオブジェクトを ID でリンクする

複数 のプロパティに同じ値のオブジェクトを設定するのは面倒だし同じであることがわかりにくい。 {"prop1":{"value":12345},  "prop2":{"value":12345},  "prop3":{"value":12345}}   いちいち同じ値のオブジェクトを記述しないで、共通のオブジェクトを参照したくなりました。 あれ={"value":12345} {"prop1":あれ, "prop2":あれ, "prop3":あれ}    そこで、 ID というプロパティを持たせて、オブジェクトを ID で表せないか考えました。 共通のオブジェクトを指定したい場合は、そのプロパティにオブジェクトの ID を指定します。 {"id":" hoge ", "value":12345} {"prop1":" hoge ", "prop2":" hoge ", "prop3":" hoge "}   ID といってもただの文字列なので、読み込み側でオブジェクトが指定されるはずのプロパティで文字列があったら、その文字列を ID とするオブジェクトを割り当てる処理が必要です。  「オブジェクトが指定されるはずのプロパティ」かどうかを判別する手段として、あらかじめ読み込み側に教えておくか、プロパティ名にプレフィックスなどをつけて表すことが考えられます。 さらに何かないかと調べていると、 JSON のハイパー スキーマ 仕様には参照型というものがある事を知りました。 JSONだってハイパーメディア -- JSONハイパースキーマ仕様をなんとかしたい - 檜山正幸のキマイラ飼育記 URL をただの文字列ではなく "$ref" というプロパティの値として指定することで、その文字列が参照であることを表します。   これを先ほどの例に適用すると、さきほどよりも参照であることが明確