Unknown::Programmingスマートフォン用の表示で見るUnknown::Programmingこの広告は、90日以上更新していないブログに表示しています。errorao(foo())->aaa;というのを思いついた。あ、そうだ、あけましておめでとうございます。22:54ArrayObjectを如何にして有効活用するかTweet広告を非表示にするもっと読むコメントを書く2009-12-18PHPのhtmltemplate.incでオブジェクトやらフィルターやらphpひょんなことからhtmltemplate.incというHTMLテンプレートエンジンを触ることになった。どんな感じのテンプレートなのかはhttp://hokori.net/2008/03/01/thmltemplate_for_php/http://d.hatena.ne.jp/atyks/20090830/1251641112あたりで詳しく書かれている。Smartyに慣れている人間からすると非常に使いにくい。オブジェクトが渡せなかったり、テンプレート内でHTMLエスケープ等のフィルター処理ができなかったりする。機能追加をしたいわけなのですが、これがなかなかhtmltemplate.incというやつは短いコードながら設計が優れていてとても機能拡張がしやすい。いうわけでやっちゃいました。tag_fil);これで機能追加完了。filというタグを追加しました。A&lt;hr&gt;Bとなります。実際にそれぞれの動きを見てみよう。150うまく動いてます。古いクラスなので需要があるのかさっぱりわからないけど何かの参考になれば幸いです。20:00PHPのhtmltemplate.incでオブジェクトやらフィルターやらTweet広告を非表示にするもっと読むコメントを書く2009-11-27ArrayObjectは便利だけと扱いづらいねPHP配列のように振舞えるArrayObjectなんだけど、あくまでもオブジェクトなので結局のところ配列を期待する標準関数との相性が悪すぎて微妙。is_arrayは偽になっちゃうし、array_shiftはうまく動かないし。array_flipとかarray_uniqueとかには一応渡せるけど戻り値は配列になってるのでこれまた微妙。配列っぽく扱えるのに標準関数に渡せないので、非常に使いどころが難しくなる上に後々の混乱の元となりそうだ。文字列評価された時の振る舞いを定義できる__toStringみたいな感じで、配列評価された時の振る舞いを定義できる__toArrayみたいな構文を用意してくれればちょっとはマシになりそうなんだけどねー。is_arrayだけでも真になって欲しいなぁ・・・。仕方ないので今はこんな関数用意してやってます。13:25ArrayObjectは便利だけと扱いづらいねTweet広告を非表示にするもっと読むコメントを書く2009-11-19List::MoreUtilsのuniq関数の実装が変わってた件perl大分昔に書いたHashを使って配列をユニークにしようという記事のブコメにてList::MoreUtilsのuniq関数の実装が変わったというコメントを頂きました。2009年11月17日さっそくどう変わったのか確認したところ、なんともアンビリーバボーな実装になってました。@_;}新uniq関数では、なにやら「1」のリファレンスを取ってmap中にdefinedでチェックしたり色々処理が増えてます。何がしたいのかというと旧uniq関数ではハッシュの特性上、未定義値が空文字と同義と見なされてしまい、別々の値としてユニークにすることが出来なかったのでそれに対応するために新uniq関数ではごにょごにょやっているわけなんですね。実際に挙動を見てみましょう。];旧uniq関数の場合、ユニーク結果が空文字だけになってしまってます。新uniq関数だと空文字と未定義値がちゃんと別々のものとしてユニークになってますね。この新uniq関数なんですが、少し実装に問題があります。1のリファレンスを持っておき、配列中に未定義値があった場合その1のリファレンスの値を使用してユニーク処理を行ってるわけですが、この時たまたま配列に1のリファレンスの値とまったく同じ文字列が入っていた場合、誤認識してしまいます。配列にリファレンスの値っぽい普通の文字列が入ってる。これがもしuniq関数中の\1のリファレンスの文字列と被ってたら誤認識する。];と、このように「'SCALAR(0x1bc77e0)'」という文字列が消えてしまいます。この文字列はたまたま被った場合の話なので環境によっては値が異なります。これに対応するとなるとこんな感じになりますかね。何でも汎用的に作ろうとするとどんどん実装が重くなっていきますよね。このuniq関数にしたって空文字と未定義値を区別したいなんてニーズが果たしてどれくらいあるのかわからないのに汎用的であるが故に実装しなければならないという。18:32List::MoreUtilsのuniq関数の実装が変わってた件Tweet広告を非表示にするもっと読むコメントを書く2009-11-12配列か連想配列かを判別するphpPHPにおいて、ある配列が連想配列として使われているのかどうかを判別したい場合どうすればいいのか。調べてたらこんな記事を発見しました。判定関数(is_hash)なるほど。array_keysで配列のキー一覧を取得し、そのキー一覧が0からの連番になっているかどうかを比較すれば、対象の配列が配列なのか連想配列なのかを判別できるという理屈ですね。確かにこれで判別ができそうです。ひとつだけ気になる部分があって、array_keysやrangeを使って一時的な配列を確保しているのは無駄が多いのではないかと。対象となる配列が大きければ大きいほどメモリ効率が悪くなりそうな気がします。要件としては、対象の配列のキーが0からの連番になってるかどうかを調べたいだけなのでforeachでループしながら比較する方が効率良いのではないかと思い、実装してみました。false;}こんな感じですね。次にベンチマークをとってみます。"\n");要素が1001個ある配列を1000回繰り返し実行した場合のベンチマークです。0.106162071228foreachで処理する方が2.6倍ほど早くなりました。他にも色々な条件でやってみます。0.169075965881要素が少ない場合でもforeachの方が早いですね。0.038535118103要素が多い場合は速度の差が顕著にでます。bytes)というエラーがでました。array_keysやrangeで確保するメモリの量が多すぎてプログラムが落ちるようです・・・。foreachなら100万個でも難なく処理できます。次に連想配列を渡したときのベンチマークですが、foreachの場合、キーが連番じゃなかったり数字じゃなかった時点で処理が終了するのでめちゃめちゃ早くなりました。試しに文字列のキーを持つ10万要素の連想配列でベンチマークを取ってみます。1.59740447998E-5比較にならないぐらい桁違いに早いですね。数万倍くらい?結論としては配列の大きさに関わらずforeachの方が早い配列が大きければ大きいほどforeachの方が更に早い対象の配列が連想配列だった場合、foreachの方が桁違いに早い。foreach万歳ですね。ひとつだけデメリットをあげるならば、ワンライナーじゃないというところになりますか^^;さてこれでカンペキ!と言いたいところですが、実は実際のところ、連想配列として利用する配列のキー名に0という数字は使わないという前提条件がある場合、その対象配列の最初のキーが0かどうかだけをチェックすればそれだけでOKだったりするんですよね。速度的にはピカ一で早いです。厳密にチェックしたい場合はforeachを使い、前提条件がある場合は最初のキーだけをチェックする感じで良いんじゃないでしょうか。14:12配列か連想配列かを判別するTweet広告を非表示にするもっと読むコメントを書く2009-08-19ArrayObjectによる配列演算子のオーバーロード風PHPPHP5やり始めたばっかでまだ右も左もわからずに右往左往してます。Library)ってのが導入されたということを知った。そのSPLの中にArrayObjectという物がありまして、オブジェクトを配列っぽく扱えるようにしたものなのですよ。今日はコレを取り上げてみたいと思います。200)おお、面白い。オブジェクトなのに配列のように扱えています。面白いのがオブジェクトのプロパティに設定した値と同期させることもできるところです。以下の例を見てください。200)これは凄いですね。ある変数に対して、プロパティ呼び出しでも配列形式でもどちらの方法でもアクセスできるというのはかなり便利です。記号等を含まないデータ名の場合はプロパティ呼び出しで値を設定し、含んでしまうようなデータ名の場合は配列形式で値を設定するという感じでしょうか。300;僕の場合、オブジェクトのプロパティを連想配列代わりとして使うことがちょくちょくあったりするんですよね。括弧やシングルクォートすら書くのが面倒臭いので->だけでアクセスできると凄い楽なんです。記号が必要になりそうなケースでは初めから連想配列を使いますが。このArrayObjectはPerlのCatalystのstashの様な使い方に向いてるんじゃないかなぁと思います。個人的に非の打ち所が無いArrayObjectですが、こうなるとやっぱり気になるのは速度面でどうなのか?ってことですよね。いうわけでArrayObjectとstdClassと配列でベンチマークをとってみました。0.031132え、ちょ、ま。殆ど同じじゃないっすか!あれれ、ベンチの書き方間違ってるのかな・・・。PHPでベンチ書かないからよくわからない。本当にこれだけ早いのならコレマジで使わない手は無いですね。19:22ArrayObjectによる配列演算子のオーバーロード風Tweet広告を非表示にするもっと読むコメントを書く2009-07-20PHPでnewと同時にメソッドチェーンする方法PHP最近ようやくPHP5をちょこちょこと触ってるわけなんですが、折角メソッドチェーンサポートされたのに何故かnewと同時にできない罠。これなんか動いても良さそうなのになぁ。Foo)->bar();嘆いてもしょうがない。動かないものは動かないので、ちょこちょこと調べてたらこんなのがそこで以下のような関数を定義する。$obj;}この関数はみたとおり渡された値をそのまま返す関数だが、これを使うことで以下のようにメソッドチェーンできるようになる。Hoge)->doSomething();というバッドノウハウっぽい話。id:anatooのブログやっぱこれくらいしかないよねー。標準関数だけでやりたいのが人情というもの。あれこれ試してみたところ、やっとこさ実現できた。ことで僕が出した結論はコレ。Foo))->bar();これがホントのバッドノウハウ。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。