2012年11月30日金曜日

フライングセブンスポット

セブンスポットは12/1から全国展開とのことだったけれど、店舗検索で近くのセブンイレブンが引っ掛かったので、駄目元で帰宅途中に立ち寄ってみたらすんなり使えてしまった。

使用した端末は第4世代iPod touch。公式サイトの説明の通り、「7SPOT」というSSIDの無線LANに接続してWebブラウザを立ち上げ、あとは道なりにログインするだけ。ログイン画面には確か新規会員登録へのリンクがあったので、その場でも会員登録できそうな感じだった。touchのようなWi-Fiオンリーの端末だと、その場で確認メールを受信できなくて駄目かもしれないけど。

認証にこそWebブラウザを使うものの、Webブラウザを使用したネットサーフィンしかできないわけではない。YouTubeアプリも2chリーダーも普通に動いたし、メールも受信できた。

速度は真面目に測っていないけれど、体感速度には特に不満なし。自宅のADSLより速い? ノートPCを持って行けば、OSのでかいISOイメージなんかを速く落とせるかも。面倒だからやらないけど。

会員1人で複数端末の同時接続は可能なのだろうか? セブンイレブンで複数の端末を使うことはまずないとしても、デニーズならノートPCを開きながらスマートフォンを使いたくなっても不思議ではないし。

全然関係ないけど、横文字に「フライング」を付けると、何となく技の名前に見えるなぁ。フライングセブンスポットだと、空中で仕掛ける地獄の九所封じみたいな技だろうか?

2012年11月29日木曜日

やっぱりVirtualBox

VMware Fusionはやめて、結局VirtualBoxを使うことにした。

決め手はメモリ。CPUパワーには特に不満が無くても、物理メモリがどうにも心許ない。FreeRAM Boosterというアプリでモニタリングしてみると、メモリを1GBしか(?)アサインしていない仮想マシンを1台動かすだけで、結構ギリギリ。同程度の仮想マシンをもう1台動かしたら、スワップアウトは避けられまい。気軽にポコポコ仮想マシンを動かすには程遠い。8GB積んだときには、もうメモリで困ることなんてないだろうと思ってたんだけどなぁ。

そういうわけで、仮想化ソフトより物理メモリに金をかけた方が有意義だろうと思い、随分と安くなった8GBの2枚セットをポチっとやってしまった。さすがに16GBも積めば、当面メモリがネックになることはないだろう。

VMware Fusion 5を体験してみる

うじうじ悩んでいても仕方がないので、体験版を使ってみることにした。ここから新規アカウントを作成して、後は道なりにダウンロード&インストール。

とりあえずゲストOSとしてLinux Mint Debian Editionを入れてみた。シームレスにマウスカーソルを出入りさせたり、仮想マシンのディスプレイをリサイズしたりするには、仮想マシンにVMware Toolsを入れる必要がある。VirtualBoxで言うところのGuest Additionに相当するものだ。VMware Fusionの仮想マシンメニューからVMware Toolsのインストールを選べば、ディスクイメージがダウンロード&マウントされるので、あとはその中のtarballを展開して、vmware-install.plを実行すればOK。色々聞かれるが全部デフォルトにした。

もう少し使ってみて、良さそうなら購入しよう。

2012年11月28日水曜日

VMware Fusion 5がちょっと安い

おお、VMware Fusion 5が期間限定でディスカウントされている。通常版が20%、Professional版が40%割引で、それぞれ$39.9と$59.99。適当にググって見つかるレベルのプロモーションコードは併用できないみたい。

もうたまにしか起動しない物理Linuxマシンを仮想マシンにしてしまえば、スッキリして良さそうな気がするんだけれど、どうしてこんなときに円安が進むんだよ。何となく80円以上でドルを買うのが悔しい。冷静に考えれば、レートの変動より値引き額の方がずっと大きいんだけどね。

割引期間は今月いっぱいだそうなので、後2日間しっかり考えて、必要だと思ったら購入するとしよう。

2012年11月26日月曜日

SQLiteを使ってみる 第4回

これまではクエリ1つ投げるのに複数のAPIを用いてきたが、これはやはり面倒だ。そこで、一連のAPI呼び出しをまとめてやってくれるsqlite3_exec()の出番となるわけだが、ただ使ってみるだけでは芸がないので、今回は趣向を変えてその実装を見てみよう。以下、本家tarball内のsqlite.cより引用。

SQLITE_API int sqlite3_exec(
  sqlite3 *db,                /* The database on which the SQL executes */
  const char *zSql,           /* The SQL to be executed */
  sqlite3_callback xCallback, /* Invoke this callback routine */
  void *pArg,                 /* First argument to xCallback() */
  char **pzErrMsg             /* Write error messages here */
){
  int rc = SQLITE_OK;         /* Return code */
  const char *zLeftover;      /* Tail of unprocessed SQL */
  sqlite3_stmt *pStmt = 0;    /* The current SQL statement */
  char **azCols = 0;          /* Names of result columns */
  int nRetry = 0;             /* Number of retry attempts */
  int callbackIsInit;         /* True if callback data is initialized */
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
  if( zSql==0 ) zSql = "";
  sqlite3_mutex_enter(db->mutex);
  sqlite3Error(db, SQLITE_OK, 0);
  while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
    int nCol;
    char **azVals = 0;
    pStmt = 0;
    rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
    assert( rc==SQLITE_OK || pStmt==0 );
    if( rc!=SQLITE_OK ){
      continue;
    }
    if( !pStmt ){
      /* this happens for a comment or white-space */
      zSql = zLeftover;
      continue;
    }
    callbackIsInit = 0;
    nCol = sqlite3_column_count(pStmt);
    while( 1 ){
      int i;
      rc = sqlite3_step(pStmt);
      /* Invoke the callback function if required */
      if( xCallback && (SQLITE_ROW==rc ||
          (SQLITE_DONE==rc && !callbackIsInit
                           && db->flags&SQLITE_NullCallback)) ){
        if( !callbackIsInit ){
          azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
          if( azCols==0 ){
            goto exec_out;
          }
          for(i=0; i<nCol; i++){
            azCols[i] = (char *)sqlite3_column_name(pStmt, i);
            /* sqlite3VdbeSetColName() installs column names as UTF8
            ** strings so there is no way for sqlite3_column_name() to fail. */
            assert( azCols[i]!=0 );
          }
          callbackIsInit = 1;
        }
        if( rc==SQLITE_ROW ){
          azVals = &azCols[nCol];
          for(i=0; i<nCol; i++){
            azVals[i] = (char *)sqlite3_column_text(pStmt, i);
            if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
              db->mallocFailed = 1;
              goto exec_out;
            }
          }
        }
        if( xCallback(pArg, nCol, azVals, azCols) ){
          rc = SQLITE_ABORT;
          sqlite3VdbeFinalize((Vdbe *)pStmt);
          pStmt = 0;
          sqlite3Error(db, SQLITE_ABORT, 0);
          goto exec_out;
        }
      }
      if( rc!=SQLITE_ROW ){
        rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
        pStmt = 0;
        if( rc!=SQLITE_SCHEMA ){
          nRetry = 0;
          zSql = zLeftover;
          while( sqlite3Isspace(zSql[0]) ) zSql++;
        }
        break;
      }
    }
    sqlite3DbFree(db, azCols);
    azCols = 0;
  }
exec_out:
  if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
  sqlite3DbFree(db, azCols);
  rc = sqlite3ApiExit(db, rc);
  if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
    int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
    *pzErrMsg = sqlite3Malloc(nErrMsg);
    if( *pzErrMsg ){
      memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
    }else{
      rc = SQLITE_NOMEM;
      sqlite3Error(db, SQLITE_NOMEM, 0);
    }
  }else if( pzErrMsg ){
    *pzErrMsg = 0;
  }
  assert( (rc&db->errMask)==rc );
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

上から眺めると、まず目に付くのが排他処理。sqlite3_mutex_enter(), sqlite3_mutex_leave()を用いているのが分かる。次に、最も外側のループの中では、引数として与えられたSQL文を逐一実行する。セミコロンで区切った複数のSQL文も、エラーが検出されない限り最後まで実行されるわけだ。

コールバックも指定できる。…と言うか、クエリによってはこれを使わないとどうにもならない。何も返さないクエリは完了時に1回コールバックが呼ばれるだけなので、無理にコールバックを使わなくてもどうにかなるだろう。一方、表を返すクエリの場合、1行毎に取得した表の内容を引数にしてコールバックが呼び出されるので、基本的に所望の処理はコールバックの中で行う。メモリの解放は気にしなくても良い一方で、コールバックの外でも取得した表の内容を参照したければ、コールバックの中でどこかしら別の領域にコピーして取っておく必要がある。また、表を作成したときに指定した型に関わらず、カラムの内容はTEXT型として取得される。

エラーを検出した場合、エラーメッセージを返すことができるが、このエラーメッセージの領域はsqlite3Malloc()で確保したものである。したがって、エラーメッセージを使い終えたらsqlite3_free()で明示的に解放してやらなければならない。

SQLiteを使ってみる 第3回

結果を返すタイプのクエリを投げてみよう。今回は、以下のような簡単なテーブルを作って、それを丸ごと返してもらう。

日付品目価格
11/25りんご123
11/26ごりら456

まずはサンプルコード。

// vim: set fileencoding=utf-8:
#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
#define DEFAULT_FILENAME "test3.sqlite3"
sqlite3 *open_db(const char *filename) {
    sqlite3 *db;
    int rc;
    rc = sqlite3_open(filename, &db);
    printf("sqlite3_open() : %d\n", rc);
    if (rc != SQLITE_OK) {
        sqlite3_close(db);
        db = NULL;
    }
    return db;
}
int close_db(sqlite3 *db) {
    int rc;
    rc =  sqlite3_close(db);
    printf("sqlite3_close() : %d\n", rc);
    return rc;
}
sqlite3_stmt *exec_query(sqlite3 *db, const char *query) {
    sqlite3_stmt *stmt;
    int rc;
    rc = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
    printf("sqlite3_prepare_v2() : %d\n", rc);
    if (rc != SQLITE_OK) return NULL;
    rc = sqlite3_step(stmt);
    printf("sqlite3_step() : %d\n", rc);
    return stmt;
}
int fin_query(sqlite3_stmt *stmt) {
    int rc;
    rc = sqlite3_finalize(stmt);
    printf("sqlite3_finalize() : %d\n", rc);
    return rc;
}
int main(int argc, char **argv) {
    sqlite3 *db = NULL;
    int rc;
    char *filename = DEFAULT_FILENAME;
    // open
    if (argc >= 2) filename = argv[1];
    db = open_db(filename);
    if (db == NULL) return 1;
    sqlite3_stmt *stmt;
    rc = 2;
    // create table
    stmt = exec_query(db, "create table 家計簿(日付 text,品目 text,価格 int);");
    if (stmt == NULL) goto ensure;
    fin_query(stmt);
    // insert
    stmt = exec_query(db, "insert into 家計簿(日付,品目,価格) values('11/25','りんご',123);");
    if (stmt == NULL) goto ensure;
    fin_query(stmt);
    stmt = exec_query(db, "insert into 家計簿(日付,品目,価格) values('11/26','ごりら',456);");
    if (stmt == NULL) goto ensure;
    fin_query(stmt);
    // select
    const char *query = "select * from 家計簿";
    rc = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
    if (rc != SQLITE_OK) goto ensure;
    for (;;) {
        rc = sqlite3_step(stmt);
        printf("sqlite3_step() : %d\n", rc);
        if (rc != SQLITE_ROW) break;
        const unsigned char *text;
        int val;
        // 日付
        text = sqlite3_column_text(stmt, 0);
        if (text != NULL) printf("'%s', ", text);
        // 品目
        text = sqlite3_column_text(stmt, 1);
        if (text != NULL) printf("'%s', ", text);
        // 価格
        val = sqlite3_column_int(stmt, 2);
        printf("%d\n", val);
    }
    fin_query(stmt);
    rc = 0;
ensure:
    // close
    close_db(db);
    return rc;
}

結果は常に1行ずつ参照される。また、参照される行はsqlite3_step()が呼ばれる度に次へと進む。sqlite3_step()の戻り値は、参照する行が残っている場合はSQLITE_ROW、全ての行を返し終えた場合はSQLITE_DONEとなる。

sqlite3_column_text()が文字列へのポインタを返していることに注意。当然、メモリのどこかに文字列を確保しているわけだが、これはsqlite3_step()で次の行へ移ったときやsqlite3_finalize()で後始末するときに、自動的に解放される。このメモリの扱いは、ポインタを返す他のsqlite3_column_*()でも同様。

2012年11月24日土曜日

末は博士か大臣か

東映チャンネルでやっているサンバルカンの再放送で、孫娘が誘拐されて首相が脅迫される話を見て、そういえば総理大臣って偉かったんだよなぁ、ということを思い出した。丁度今日、買い物に行った駅前で野田首相が来るという看板を見て、何のありがたみも感じずに華麗にスルーしてきたところだったよ。

真面目な話、上手な大道芸や弾き語りをやってたら、そっちの方が間違いなく通行人の耳目を集めたんじゃないかな? かつて一番偉かった肩書きに、いつの間にか敬意も何もを感じなくなっていたことに気が付いて、少しだけ驚いた。

卓球の思ひ出

http://www.j-cast.com/2012/11/21154920.html?p=all

昔卓球部だったオッサンには、スーパーチャックの臭いが明らかにヤバかった記憶がある。大会とかは閉め切った体育館でやるから、余計に酷かった。確か、どこぞの阿呆がシンナー代わりにスーハーやって、完全に終了したんじゃなかったっけ?

さて、今現在問題になっているブースターとやらには、別に有機溶剤は含まれていないそうだ。だったら別に、トップレベルの試合では禁止することはないんじゃないかとは思う。それより中学生のローカル大会なんかで、消耗品に金をかけられる奴が有利になるというのが、なんだか微妙だ。ブースターなんて使わなくても、ラバー張りっぱなしで十分高性能な道具を開発してくれないかなぁ。

2012年11月23日金曜日

セブンスポット

サービス開始からもうすぐ1年。ようやく本気で全国展開するようなので、セブンスポットの会員登録をしてみた。

どうぶつの森かわら版によると、「セブンスポットのサービスを実施する全国10,000店舗以上のセブン・イレブン」でアイテム配信をするらしい。10月末時点で全国14,627店舗ある中の10,000店舗以上なら、大都会川崎の店舗がハブられることはまずあるまい。

もっとも、会社と家の往復の途中でインターネット接続サービスを利用するために、わざわざセブン・イレブンに立ち寄ることはまずあるまい。それならさっさと帰宅するか、会社に向かえばいいのだから。3G/4GのないiPod touchユーザーにとっては、たまに不慣れな土地に出かけたときに、セブン・イレブンさえ見つけられれば現在位置と地図を見られるとか、そんな感じの存在になりそう。このサービスが広く全国展開されれば、困ったときの駆け込み寺としての認知度がかなり上がりそうな気がする。

2012年11月21日水曜日

違憲状態のままの衆議院選挙に思う

違憲な選挙には行けん。…とは言わずに0.5票くらいを行使するつもりではあるが、なんだかなぁ。しかし司法もなめられたもんだ。一度ガツンとやり直し判決を下してやって欲しい。

議席配分はもちろん問題なんだけど、未だ選挙法をインターネットの時代に適応できていないのも、腐ってるよなぁ。いっそ任期を3ヶ月くらいにしてしまえば、ネットの活用も含めて死に物狂いで選挙方法を最適化するんじゃないか?

もっと突き詰めると、「ローコストでより民意を反映させる」ことを目的とするなら、定期的に全国から1000人くらい無作為に議員を選出すれば十分な気がする。政党は政策を提案する、言わば国民のシンクタンクになればいい。当然、議員の質は問題になるだろうけれど、それが平均的な国民の質なら仕方がないだろうよ。上手く回れば、全体的に質を底上げしようというインセンティブが働くかもしれない。

…そんな実現しようもない妄想は、誰も読んでないブログにでも吐き捨てよう。理想と現実の乖離を嘆いたって腹の足しにもなりゃしない。それより、現実をどう活用して腹の足しにするか、だ。

2012年11月20日火曜日

SQLiteを使ってみる 第2回

接続したDBにクエリを投げて、以下のような簡単なテーブルを作ってみよう。

日付品目価格

以下のサンプルではsqlite3_exec()を使わず、sqlite3_prepare_v2(), sqlite3_step(), sqlite3_finalize()を使ってクエリを投げている。

// vim: set fileencoding=utf-8:
#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
#define DEFAULT_FILENAME "test2.sqlite3"
int main(int argc, char **argv) {
    sqlite3 *db = NULL;
    int rc;
    char *filename = DEFAULT_FILENAME;
    // open
    if (argc >= 2) filename = argv[1];
    rc = sqlite3_open(filename, &db);
    if (rc == SQLITE_OK)
        printf("sqlite3_open() : OK, db = %p\n", db);
    else
        printf("sqlite3_open() : NG(%d), db = %p\n", rc, db);
    // create table
    const char *query = "create table 家計簿(日付 text, 品目 text, 価格 int);";
//  query = "creat table 家計簿(日付 text, 品目 text, 価格 int);";
    sqlite3_stmt *stmt = (sqlite3_stmt *) 0xdeadbeaf;
    rc = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
    if (rc == SQLITE_OK)
        printf("sqlite3_prepare_v2() : OK, stmt = %p\n", stmt);
    else
        printf("sqlite3_prepare_v2() : NG(%d), stmt = %p\n", rc, stmt);
    if (stmt != NULL) {
        rc = sqlite3_step(stmt);
        if (rc == SQLITE_DONE)
            printf("sqlite3_step() : DONE\n");
        else
            printf("sqlite3_step() : NG(%d)\n", rc);
    }
    rc = sqlite3_finalize(stmt);
    if (rc == SQLITE_OK)
        printf("sqlite3_finalize() : OK, stmt = %p\n", stmt);
    else
        printf("sqlite3_finalize() : NG(%d), stmt = %p\n", rc, stmt);
    // close
    rc = sqlite3_close(db);
    if (rc == SQLITE_OK)
        printf("sqlite3_close() : OK, db = %p\n", db);
    else
        printf("sqlite3_close() : NG(%d), db = %p\n", rc, db);
    return 0;
}

sqlite3_prepare_v2()は、UTF-8の文字列で表現されたクエリから内部形式であるsqlite3_stmt型のオブジェクトを生成するAPI。生成されたオブジェクトの場所は、第4引数で参照渡しするポインタ変数に返してもらう。sqlite3_open()とは異なり、失敗したら何もリソースは確保せず、NULLを返す。

sqlite3_prepare_v2()が生成したsqlite3_stmt型のオブジェクトを実行するのがsqlite3_step()。今回はテーブルを作成しているだけなので、クエリの実行結果としてテーブルが返ってきたりはしない。

使い終わったsqlite3_stmt型のオブジェクトは、sqlite3_finalize()で解放する。引数にNULLを渡しても実害はないようだ。

コメントアウトしているクエリは、わざとタイプミスをしたもの。これを実行するとsqlite3_prepare_v2()がエラーを返す。また、コンパイルした実行バイナリを2度3度実行すると、2回目以降はsqlite3_prepare_v2()がエラーを吐く。既存のテーブルと同じ名前のテーブルを作成しようとするので、失敗すること自体は想定していたが、sqlite3_step()でこけるものだと思っていた。sqlite3_open()かsqlite3_prepare_v2()で、DBに含まれているテーブル名くらいは見ているのかな?

2012年11月19日月曜日

(☆)??

今週のキン肉マン。

正義超人としての戦いを貫いたラーメンマンに対して、悪魔超人のスタイルに徹するブラックホール。今シリーズはとことん、イデオロギーの対立を描くつもりなのか。面白いんだけど、落とし所が不安でもある。綺麗に着地してくれるといいんだけど。

…何て思ってたら、白い羽根? ブラックホールに関係する白い羽根と言ったら、クロノスチェンジなあの人しか思い浮かばない。余りに脈絡がなさすぎるから、それはないだろうと思ったけれど、よくよく考えてみればこれはキン肉マンだ。超人墓場からペンタゴンを吸い寄せたとか言われたら、むしろアシュラマンのリアル御手を拝借より説得力があるくらいだ。

こんな気になる展開なのに今週分の閲覧期限が12/10ってことは、2週休載? 月曜日の貴重な楽しみが…。41巻発売の前兆だと思って待つしかないか。

2012年11月18日日曜日

SQLiteを使ってみる 第1.5回

さて、DBへ接続できるようになったら、いよいよクエリを投げるためのAPIだ。

文字列で表現されたクエリをsqlite3_prepare_v2()で内部形式に変換してから、sqlite3_step_v2()で変換後の式を評価し、使い終わった内部形式のオブジェクトをsqlite3_finalize()で破棄するのが基本のようだ。面倒ならば一連の操作をまとめてやってくれるsqlite3_exec()も使える。

…って、APIを押さえる前に、もう少しSQLをかじらないと投げるクエリが定まらない。コマンドラインでインタラクティブに使えるsqlite3コマンドで、色々いじりながら覚えよう。

2012年11月17日土曜日

CAST BOX購入、そして…

そういえばまだ入手していなかったので、ポチッと購入。

まだ買っただけで外しても戻してもいないのだけれど、立方体のパーツに継ぎ目が見当たらない。どうやって鋳造してるんだろう?

ついでに未購入の旧作も買ったのだけれど、どうも全体的に難易度が再設定されたようだ。それに合わせてか、赤黒金のパッケージも刷新されて、黒金+難易度に応じた色になった模様。こんがらかったままのVORTEXが★6つに格上げされていて、解けていない自分が少し肯定された気分w

HARMONYなる新作も出るのか。この手のビジュアル系パズルは好き。

SQLiteを使ってみる 第1回

まずはオープンとクローズ。

基本的にはsqlite3_open()でDBへの接続をオープンし、操作を終えたらsqlite3_close()でクローズすれば良い。以下は、オープン・クローズするだけのサンプル

#include <stdio.h>
#include <sqlite3.h>
#define DEFAULT_FILENAME "test1.sqlite3"
int main(int argc, char **argv) {
    sqlite3 *db = NULL;
    int rc;
    char *filename = DEFAULT_FILENAME;
    // open
    if (argc >= 2) filename = argv[1];
    rc = sqlite3_open(filename, &db);
    if (rc == SQLITE_OK)
        printf("sqlite3_open() : OK, db = %p\n", db);
    else
        printf("sqlite3_open() : NG(%d), db = %p\n", rc, db);
    // do something ...
    // close
    rc = sqlite3_close(db);
    if (rc == SQLITE_OK)
        printf("sqlite3_close() : OK, db = %p\n", db);
    else
        printf("sqlite3_close() : NG(%d), db = %p\n", rc, db);
    return 0;
}

まず、接続はsqlite3型のポインタで表現する。ユーザーは、APIが確保したsqlite3型のオブジェクトの場所を教えてもらうわけだ。sqlite3_open()は戻り値がint型のエラーコードなので、sqlite3型のオブジェクトのアドレスはポインタの参照を介して返してもらう。指定した名前のファイルが存在しなければ、新規ファイルの作成を試みる。なお、sqlite3_open()に限らず、基本的に引数の文字列はUTF-8。名前の末尾に16が付くAPIはUTF-16。

所望の操作を終えたらsqlite3_close()。sqlite3_open()で確保したリソースはこれで解放される。

注意すべきは、sqlite3_open()に失敗してもsqlite3_close()が必要な点。sqlite3型オブジェクトが表現するものは、あくまで「DBへの接続」。そして接続に失敗した場合でも、エラー情報を保持したsqlite3型のオブジェクトが確保される。失敗したからと言って放置せず、sqlite3_close()でこのオブジェクトを捨ててやらなければならない。fopen()に失敗したらfclose()しない普通のファイルとは、使い勝手が異なるところだ。

2012年11月15日木曜日

Wii Uの外付けストレージ

もうそろそろ舌の根は乾いたと思うので、昨日出てきたWII Uの公式情報に関する話。

USB外付けストレージのファイルシステムは独自ということか。そして、SDカードにWii U専用コンテンツを置けない理由もこれかな。技術的には出来ないことはないだろうけど、他の機器でも使用するSDカードを独自FSでフォーマットするなんて、どう考えても面倒なことになる。

結局2TiBの壁はあるのか。さすがに新たに作ったFSにそんな足かせは付けないだろうから、パーティションテーブルまでは独自じゃないのだろう。間違ってPCに差したときにMBRを作られてウギャーでは困るだろうし。しかし、当面需要は無いにしても、GPTくらい最初から対応しておいてもいいんじゃないか? まあ、とりあえず実機を購入したら、適当なUSBメモリをフォーマットさせてみてddで覗いてみよう。FS自体は暗号化されていて、ダンプを見ても何も分からないんだろうけど。

そう言えば、頻繁に書き換えるからUSBメモリは推奨しないそうだけど、だったら内蔵フラッシュはどうなのよ? とは思った。MLCだから安物TLCよりはましだというだけか、それとも内蔵フラッシュはハードand/orソフトで高度なウェアレべリングをやってるのか。こいつは覗き見できそうにないなぁ。

バーチャルコンソールは商売としてやる気があるようで、互換機能でとりあえず動くようにするだけではなく、きちんとWii Uネイティブ対応する予定とのこと。Wiiで購入済みのものは無料か、iTunes Plusのような差額アップグレード可能だといいなぁ。

2012年11月14日水曜日

Mountain LionのGCC

WII Uの公式新情報が出てきたのでその感想を書こうと思ったけれど、さすがに昨日の今日で前言撤回してゲーム時事ネタというのもアレなので、SQLiteの話を書こう。

…と思ったら、テストコードがコンパイルできない。調べてみたら、Mountain Lionは標準で(LLVM)GCCが入っていないそうな。こちらのページを参考にしてインストールしたら、無事使えるようになった。

今頃気付いたということは、家のマシンでは4ヶ月近くコマンドラインでコンパイルしてなかったってことか…。

2012年11月13日火曜日

SQLiteを使ってみる 第0回

最近、時事ネタやキン肉マンの感想ばかり書いていたので、初心に返って久々に技術ネタを書こう。…と言うわけで、ガチガチ低級な組み込み屋さんの苦手分野(?)であるDBを、SQLiteを通じて学んでみようと思う。

SQLiteを選んだのは、ネットワークを考える必要がなく、単なるローカルファイルの操作だけで完結するから。サンプルプログラムも作りやすいだろうし、ちょっとしたツールにもすぐ応用できそうだし。

2012年11月12日月曜日

完璧超人の格

今週のキン肉マン。

ギミック系のジャック・チーならブラックホールでも何とかならないかと思ったけれど、連戦&手札がバレバレで完璧超人を相手にするのは、さすがに無謀か。温泉を掘れるなら、水切れにも期待できなさそうだし。今シリーズの速さだと、温存していたフェイバリットでジャック・チーがあっさり勝利という展開も十分ありそうだ。何とか相打ちできないかと思わなくもないけど、それではあまりに完璧超人がやられ過ぎだしなぁ。爪痕の1つを残せれば上々と言ったところか。

最期にもう少し、バッファローマンやスプリングマンとの絡みに期待。

2012年11月11日日曜日

Wii on Wii U

http://www.nintendo.co.jp/wiiu/hardware/features/wiisoft/index.html

いつの間にか公式情報が結構上がっていた。Wii互換はWiiチャンネルを個別にWii U対応させるのではなく、Wiiそのものをエミュレートすることで一気に対応するってことかな? おそらくOSが全く別物というか、そもそもWiiには今時のOSが入っていたとは思えないので、まあ妥当な対応かな。クラック耐性も上がりそうだし。

Wii互換機能とGamePadの併用不可は残念だなぁ。Gamepadでバーチャルコンソールを遊びたかった。まあソフト的に解決可能な問題だろうから、本気でバーチャルコンソールの商売を続けるつもりなら、バーチャルコンソールのWii Uネイティブ対応もあるか? 覚えていたら、本体購入時のアンケートに要望を書こう。

エミュレートされた(?)Wii上ではWiiConnect24を使えないそうなので、実はまだ続いているどうぶつの森のアイテム配信はNGってことか。完全引っ越しはしばらく様子見かな。技術的には対応可能だとしても、商売としてはフェードアウトさせるだけのものだし、よほど人と金が余らない限り難しいだろうなぁ。

2012年11月10日土曜日

続・自作PCの廃棄

とうとう重い腰を上げて古いPCをどうにかしようとしたものの、やはりケースは難敵だった。

とりあえず、ねじ回しで外せるものは全て外し、プラスチックの部分もひっぺがしてやったのだが、それでも依然としてでかいこの鉄製の箱。

体重をかけたくらいではびくともしない。コーナーポストからフライングニードロップを食らわしてやろうかと思うも、おそらく膝がただでは済まない上に、そもそも家にはコーナーポストがない。そこで作戦変更して屋外に放置。そのうち腐食して脆くなったら壊してやるということにして、ひとまず問題は棚上げだ。

2012年11月9日金曜日

自作PCの廃棄

押し入れの肥やしとなっている自作PC。Palomino Athlon XPで組んで、修論のために夜通し唸ってくれていたマシンのうちの1台なのだが、さすがにもう使っていない。最後に動いていたのは6~7年前くらいだろうか。既に部品取り済みで、ケースとマザーボードとCPUのみの状態なのだが、もういい加減、捨てようかと思う。

さて、そうなると考えなければならないのが、その捨て方。CPUは小さいのでどうとでもなるし、マザーボードは米袋にでも入れて、キャメルクラッチなり地獄の断頭台なり、残虐ファイトで粉砕してやればいいだろう。問題はケースだ。

残念ながら今のところ、妙案は浮かんでいない。プラスチックの部分は叩き割り、大きな鉄板は折り曲げるしかないかと思っているのだが、バリだのなんだので流血沙汰になりそうな気がしてならない。…と言うか、だからこそ今日の今日まで、押し入れに放置したまま忘れた振りを決め込んできたのだ。

ああ、でも今日は遅いから、あと1日だけ先延ばしにしよう。

2012年11月8日木曜日

Appleの祝日カレンダーが直った

最近なぜか英語表記になっていたAppleが提供している日本の祝日カレンダーが、いつの間にか元に戻っていた。

表記だけならともかく、七五三とかバレンタインデーとか、別に休みでも何でもない日まで含まれている困ったちゃんだったので、まずは直って良かった。

誰かが更新ミスをして、誰かがクレームを入れて、誰かが修正をした。そんな経過が手元の端末に自動的に反映されるだなんて、色々と凄い時代になったもんだ。

2012年11月7日水曜日

さよなら どうぶつの森

7年続けた村の生活も、ついに最後の日を迎えた。

奇しくも、ずっと引き止め続けたレイニーちゃんも今日限りで村を去ると言う。いつもなら全力で考えを改めてもらうところだが、今日は黙って見送ることにした。そして、プログラム的には関係ないであろうことは知りつつも、しんみりしながら本気で感謝の手紙を書いて出してしまった。いい年こいたオッサンのくせに。

さて、明日からは新しい村だ。レイニーちゃんが来てくれるといいな~。

2012年11月6日火曜日

ARM in Mac?

http://www.itmedia.co.jp/news/articles/1211/06/news051.html

あくまで噂。しかも短期的には確認しようがない、言いっぱなし可能なもの。しかし、そう遠くない将来には、この選択肢もありかもしれないと思わせるだけの状況が整ってきているのは確かなことだ。

現時点でIntelは文句なしに強い。が、伸び悩んでもいる。単にAMDの脅威を背中で感じなくなったからだけではあるまい。半導体プロセスの伸び悩み(と言うか縮み悩み)は大きいだろう。このままブレイクスルーがなかったら…。一朝一夕に追いつかれるようなリードではないけれど、そう楽観もしていられないかもしれない。

ちと話はそれるけれど、CPUコアを開発しているわけではないAppleが「自社のプロセッサ」(元の記事ではits own designs)と表現することには、何となく違和感を覚えた。CPUが最も偉いと思うオッサンの感覚が古くなってるってことなのかなぁ。高度なIPそのもののより、買ってきたIPをいかに組み上げるか。まさにSoCの時代ってことか。

2012年11月5日月曜日

悪魔超人揃い踏み

今週のキン肉マン。

スプリングマン来たー、と思ったらいきなりフェイバリットを見せるなんて、そんなに慌てて死亡フラグ立てるなよ。しばらく1試合ずつ進めて行くのかと思ってたけど、悪魔超人の試合は3つ同時進行するのかな。3, 4, 5階に悪魔超人を集めたからには、何かしら絡みはありそうだ。

さて、これで第2ステージの組み合わせも全て決まった…、よな? さすがに万全の状態で登場したウォーズマンが、1試合もせずに迷路の中でウギャーってことはないよな? 6, 7階で超人師弟コンビを組めば、王位編で強くなりすぎたロビンマスクに土を付ける理由として丁度いいしw

2012年11月4日日曜日

引退の秋

今年のプロ野球も完全に(最も面白くない形で)終わり、ユニフォームを脱ぐ話がよく聞こえてくるようになった。しかも、かなりの割合で年下。おそらく、短い期間でも第一線で活躍したことを記憶されていれば幸せな方で、正直言って「誰だっけ?」と思う人も多い。夢破れて去ってゆく者の名前をググって、辛うじてWikipediaに残された爪痕を見ると、何だか無性に切ない気持ちになる。

しかしまあ、健全な人の入れ替わりがない組織が駄目なことは、今シーズンのタイガースが実に分かりやすく証明してみせたからなぁ。厳しいようだけれど仕方がない。球団職員として雇って再スタートをかけてやるのが、勝負の世界でかけられる精一杯の温情なのだろう。

それに比べれば遥かにヌルい世界にいる自分だが、何となく40歳が潮時なような気がしている。ギリギリ過放電しないで済むのが40歳くらいだろうという、大雑把な計算で。奇しくも世間では40歳定年案が議論されているが、それに合わせて何かいい制度ができやしないかと、ほんの少しだけ期待している。

2012年11月3日土曜日

王道を行く

王道という言葉を完全に勘違いしていた。これまで王道だと思っていたものは正道だった。

今まで、王道を行くなんて言う奴は眉唾で見てきたけれど、思い返してみると彼らも勘違いしているのではなかろうか。むしろ、勘違いせずに王道という言葉を使っていたのだとしたら、随分とおかしなことになる。王としての治め方の意味で王道と言っていたなら、何を根拠にそんなに上から目線なんだという話になるし、近道の意味で王道と言っていたのなら、俗に言うところの「ためになる話」ではなくなる。個人的には使える近道を使って悪いことはないと思うが。

正道の意味で発した王道という言葉が誤用とは、何たる皮肉か。面白いから誤用を見つけても正さずに泳がせておこうと思った自分は、きっと邪道を歩んでいる。

文化は死んだ?

死んだ子の年と土曜日に当たってしまった祝日は数えても仕方がない。…と思っていたら、Yahoo! Japan羨ましい! 羨ましすぎる!!

油断すると奴隷の鎖自慢をしてしまいそうなところだが、それだけはするまいと心に決めている。月並みながら潰れた休みの分まで、少しでもプライベートを充実させることを考えよう。

そういえば、子供の頃は日曜日だけは早起きしてたっけ。昔の日曜日を思い出したら、何だか無性にペットントンを見たくなった。YouTubeの東映チャンネルで再放送してくれないかなぁ。

2012年11月2日金曜日

パソコンの普及とコモディティ化

パソコンはコモディティ化した。だから安くなった。それはまあ確かなことだとは思うが、実はそれほど身近なものにはなっていないのではないか?

個人的にはプライベートでも仕事でもMacやPCを使わない日はないので、正直言ってパソコンの世を疑うことはなかった。しかし、そういえば発売されていたWindows8を冷やかしに見に行こうとして気が付いてしまったのだ。空気のように当たり前だと思っていたパソコンが、そもそも近所で売っていないということに。

決して辺鄙なところに住んでいるわけではない。いや、住宅価格を見るに、むしろ憧れられる側の地域なはずだ。にも関わらず、特急も止まる駅の周りでパソコンを売っていない。iPhone, iPad, iPod touchは買えても、パソコンは買えないのだ。

ネット通販で安く買える今、近所で売っていなくても特に困ったことはないのだが、それは自分が当たり前のようにMacやPCを使っているからのこと。もしパソコンを使い始めるきっかけに恵まれていなかったら…。

昔と比べると桁違いに安くも速くもなったけれど、敷居の高さはそれほど下がっていないのかもしれない。喉元を過ぎて久しいからすっかり忘れていたけれど、そういえば色々と気を使う機械だったっけ。

2012年11月1日木曜日

金は天下を回らぬもの?

10月分の家計簿を集計して驚いた。月の生活費の最低記録を2年半ぶりに更新していたのだ。それも、特別に節約をした感覚もなしに。

改めて内容を振り返ってみると、特別なことが何もなかったことが特別と言ったところ。たまたまめぼしいゲームソフトの発売もなく、本当に淡々と日々を過ごしていた結果が、家賃も光熱費も込みで6万円。割といい年こいた大人のはずなんだが。

身近な大人の例として昔の父親を思い返してみると、父親が今の自分と同じ年齢の頃は、丁度妹が生まれたところだった。専業主婦と2児を1人の稼ぎで支えていた家計は、さぞ厳しかっただろう。公務員にはバブルの恩恵なんてろくになかっただろうし。それでも今思えば、後に購入する住宅の頭金くらいは貯めていたのだろうか。

話が大分それたが、今の自分が金を回していなかったこと自体は、ちょっと驚きはしたものの、実は特に問題だとは思っていない。家も車も買えるなら買えよと無責任な商売人は言うかもしれないが、そんな他人の皮算用の帳尻合わせをしてやる道理なんてない。欲しければ買うし、欲しくなければ買わない。思いを素直に体現しやすくなった今の世の中は、まんざら悪くもないな。