リフレクション? 関数分割?

Flex+Java(SpringFramework+iBatis)のPRJ異動から3ヶ月、気づいたらVB2008のコーディングをするようになっていました。
オブジェクト指向が分かれば何のことはない…とタカを括りながらも、VBではコンストラクタを継承できないなどいろんな驚き、気づきを貰いながらここまで何とかやってこれてます。

そんな私の今日の悩み。
下記のような事があり、リフレクションにするか関数分割するか迷ってます。
.NET Frameworkのリフレクションが遅いのであれば関数分割かなと。


ComboBoxとDataGridComboBoxColumnという2つの型があります。
この2つの型は、同じ名前のプロパティ(DataSource,ValueMember,DisplayMemberなどなど)を持ちながらも継承関係ではなく、インターフェースを持っていませんでした。
こんな2つの型に共通の設定を行いたいという要望が現場で上がりました。

そこでまず、現場の方々はこう考えました。

遅延バインディングに任せろ!(バリバリ

Sub foo(ByRef cmbBox As Object, ByVal dataSource As IList)
    cmbBox.DataSource = dataSource
    cmbBox.ValueMember = VM_XXXX
    ' ...
End Sub

しかし、Option Strict Onを書いた途端にコンパイルエラー。浅はかな野望は脆くも崩れ去りました。

ここはコンパイルエラーをなくすことが先決。
現場の方々にすがりつかれましたので、リフレクションの出番ですよ! ということで以下のように書き換えました。

Sub foo(ByRef cmbBox As Object, ByVal dataSource As IList)
    Dim type As System.Type = cmbBox.GetType
    type.GetProperty("DataSource").SetValue(cmbBox, dataSource, Nothing)
    type.GetProperty("ValueMember").SetValue(cmbBox, VM_XXXX, Nothing)
    ' ...
End Sub

…急いで直したのでNullチェックとか色々抜けてるのは後々直すとして。
思ったのは、「ホントにこれでいいのか?」ということです。パフォーマンス的に問題が出ることはないのだろうか。

素直に、別々の引数ComboBox、DataGridComboBoxColumnを持つ別々の関数にしておいた方が確実な気がしました。
もう少し考えてみます。

[WordPress] WordPress + PDO (SQLite) For Wordpress 投稿時のエラー

投稿時やページ編集時に以下のエラーが発生していた。

Warning: implode() [function.implode]: Invalid arguments passed in .../wordpress/wp-includes/post.php  on line 1980

エラー名でググったら早速解決法発見。

wp-includes/post.php の1980行目あたりを変更

$hierarchical_post_types_string = implode("', '", $hierarchical_post_types);
$hierarchical_post_types_string = addslashes($hierarchical_post_types_string);
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( '" . $hierarchical_post_types_string . "' ) AND ID != %d AND post_parent = %d LIMIT 1";

WordPress PDO (SQLite) For WordPress でエラー | MEMO-LOG

解決法がすぐ出てくるあたり、WordPressSQLiteで動かしてる人多いんだなーと驚き。

UbuntuでPDOを使おうとしてエラー

Ubuntu9上のapache2+php5で WordPress + PDO (SQLite) For Wordpress をお試しで動かそうと思い立ち、着手。
http://example.com/WordPress/wp-admin/install.php にアクセスしたところ、以下のエラーが出た。

Invalid or missing PDO Driver
Your PHP installation appears not to have the right PDO drivers loaded. These are required for this version of Wordpress and the type of database you have specified.

そういや、PDO入ってないよな…と思い、入れようとすると以下のエラー。

sudo pecl install pdo
[sudo] password for tmftake: 
downloading PDO-1.0.3.tgz ...
Starting to download PDO-1.0.3.tgz (52,613 bytes)
.............done: 52,613 bytes
12 source files, building
running: phpize
sh: phpize: not found
ERROR: `phpize' failed

原因について調べたらあっさり見つかりました。

この記事で本当にいいたいのは、表題の通り、「UbuntuでPDOを使うときには、php5-devパッケージが必要」だ、ということです。

[Ubuntu][PHP][PDO] UbuntuでPDOを使うときには、php5-devパッケージが必要。 - SumiTomohikoの日記

というわけで早速入れてみました。

[Ubuntu][php] 続続・WordPress + PDO (SQLite) For Wordpress インストール時のエラー

WordPress > インストールのボタン押下で以下のエラーが発生。
SQLiteSQL構文分からん…。

Error installing the database
Query was ; CREATE TABLE IF NOT EXISTS wp_terms ( term_id integer NOT NULL PRIMARY KEY AUTOINCREMENT , name text NOT NULL default '', slug text NOT NULL default '', term_group integer NOT NULL default 0); CREATE UNIQUE INDEX IF NOT EXISTS slug_1 on wp_terms (slug); CREATE INDEX IF NOT EXISTS name_30 on wp_terms (name).
Error message was: Array ( [0] => HY000 [1] => 1 [2] => near "NOT": syntax error ) 

どうやら、CREATE TABLEにIF NOT EXISTSがついてるのがダメみたい。
wp-content/pdo/driver_sqlite/schema.php の35行目あたりに以下のコードを追加してみた。

                $_q = $q->rewriteQuery($query);
                $_q = str_replace("IF NOT EXISTS ", "", $_q); // <-追加
                $q = NULL;

そしたら無事、WordPressのログイン画面が出ました。

[Ubuntu][php] 続・WordPress + PDO (SQLite) For Wordpress インストール時のエラー

上記の問題を解決したものの、install.phpを実行すると以下のエラーが発生。

Fatal error: Call to a member function bail() on a non-object in /var/www/wordpress/wp-content/pdo/PDOEngine.php on line 82

で、該当行を確認。

$wpdb->bail('<h1>Permissions Problem</h1><p>PDO For WordPress needs to be able to write to the folder ' .FQDBDIR ."</p>");

$wpdbがnull、というのもあるけど、そもそも権限の問題か。
$ chmod -R 777 wordpress/

Cシェル使ってきました。

一週間の期限つきトラブル対応支援が終わりました。

リーダー「シェル作ったことある?」私「bashなら何度か…」 →ふたを開けてみればcsh\(^o^)/

Twitter / tmftake: リーダー「シェル作ったことある?」私「bashなら何度か…」 ...

そんなわけで久々にシェル触りました。cshでもまぁ何とかなるもんですね。
…と言うわけで備忘録。

変数に値が設定されているか確認する

phpでいうとissetでしょうか。空文字列との比較だとエラーになるから焦った。

if (${?hoge}) then
  #...
endif

ファイル存在チェック

条件分岐で-f,-d,-eなどでチェック。
foreach file (./hoge /etc/fuga)
  if (! -f ${file}) then
    echo ${file} not found.
    exit -1
  endif

  source $file
end

対象ファイルが複数の場合、lsのリターンコードでチェック。

ls -1t hoge/* >& /dev/null
if (${status} != 0) then
  echo ${file} not found.
  exit -1
endif

あとはcut,sed,grepなどを駆使して何とかしてきました。

Cライクを謳ってるのにif-then-endifとかどういうこと!(笑
あとはfor文がないのに驚き。foreachとwhileで何とかなるので気にならなかった。

        • -

支援に行く前に自分の担当作業についてどうするかリーダーと話をして、残りのメンバーでなんとかすると言ってくれてたんですがが…

元の職場に帰ってきてみると、支援で抜けてた5日丸々遅れてる件!

…もうトラブルはいやぽ。

ソースレビューで見つけたおもしろいコード

Flex+Java開発のプロジェクトが3月末で無事終了し、VB.NET開発のプロジェクトにアサインされたのも束の間、急遽C++開発のプロジェクト支援(いわゆるトラブル対応)に回されました。
与えられた作業はソースレビューとちょっとした実装。今日はソースレビューをしてきました。
少し見た限りでは設計書も細かく書かれていて、それに沿ってソースも書かれているのですが、トラブってるのもあってかちょっとしたケアレスミスが原因でバグを作り込んでいて残念な限り。


実際に見つけたバグを以下に書いてみます。

ループ変数がインクリメントされてない

最初見たとき、思わず「えっ」と言ってしまいました。

for (i = 0; i < 10; i) {
   //...
}

条件が逆

一部あってて一部間違ってるからたち悪い。

// nFlg1 <> 0 かつ nFlg2 = 0 かつ nFlg3 = 0の場合
if (nFlg1 != 0 && nFlg2 != 0 && nFlg3 != 0) {
   //...
}

絶対に入らないループ

残念な感じ。

int i = 0;
int nRet = 255;

for (i = 0; ((i < 10000) && (nRet == 0)); i++) {
   nRet = func();
   //
}

ループの中でカウンタ初期化

とっても残念な感じ。

void hoge() {
    // ...
    for (i = 0; i < 10000; i++) {
       fuga();
    }
}

void fuga() {
    int nCnt = 0;

    if (...) {
        nCnt++;
    }
    if (nCnt >= 1000) {
        //カウンタが1000以上になったときの処理
    }
}