リンク化けたったー

®ってなんぞ?

追記: &を&ampに;してあげるだけでいいよ!!

年末くらいからものすごい体調不良続きでしたたが、ボクは元気です。
今日も風邪気味だったけど、早退せずに乗り切ったよ。
で、タイトルの®ですが今日の作業中に何だかおかしなエラーメッセージが出ていることに気付いたのでした。
1ページ戻っても出てる。。

で、更に遡ること10ページほど、漸くエラーメッセージの出ていないページに戻った(∩´∀`)∩ワーイ
(´Д')bどんだけ気付くの遅かったんだっていう。
で、そのページで入力した内容とか見てみる。
特におかしくない。(・3・)あるぇ〜?

仕方ないので、エラーの出ているページと出ていないページのURLをEmacsに貼付ける。
すると、エラーの出ているページに®ちゃんがいるじゃないですか!!
でもって、エラーの出ていない方のURLと照らし合わせてみると、&reghogeってとこが®hogeとなっていた。
文字参照かよΣ(゚∀゚*)
文字参照ってどうやったら防げるんだっけ(´∀`)
そういや、知らなかったので検索してみても1ページ目にそれっぽいのがない。。。
もしかして:HTMLでやるからダメなんじゃね?
ということで、jsに喰わせてみることに。

で、↓みたいなのを作って遷移させてみた。んだけども、うまくいかない��(゚□゚;)
何でだろ?と思ったけど、htmlがパースされた時点で®になってるんじゃないの?
ということで、↓みたいのを作ってみてポチ。今度はうまくいった(∩´∀`)∩ワーイ
何か検索しても回避策は引っかからなかったけど、
クエリストリングにregとか突っ込むとかあまりしないのかな?
ちゃんとした解決方法あるよってご存知の方は教えて下さい。
それでわヾ(。・ω・。)

2011年を振り返ったったー

今年は自分にとって変化の大きな年となりました。

1つ目

引越した。といっても池袋から池袋、歩いていける距離、
大阪->東京だったり、千葉->東京だったりの引越しと比べると
短距離引越しになったけど、ちょっとだけ部屋も広くなった。

2つ目

Macデビューした。まだまだコンソールでゴニョってるくらいだけど、
来年はもう少し遊べるようになりたいな。

3つ目

YAPCのRejectConfで話した。反省点でいっぱいだけど、
来年以降も継続してアウトプット出来るように頑張りたい。

4つ目

退職した。1年ほど前から決まっていた規定事項。
以前から興味のあった仕事をすることが出来るようになったので、
こちらも継続できるように頑張っていきたいところ。

来年は

今年以上にクライアントサイドの技術が重要になってくると思うので、
引き続き、Perl+JSの連携をいかに行うかの検証を進めたり、
ネイティブアプリの学習を進めていこうと思います。
あと、台湾に行きたいw

undefined valueのwarningsに疑問を感じったー

先日、コードの書き直しが必要になった際に文字列結合演算子を消し忘れ、

my $foo .= 'bar';

みたいなコードになっていたのですが、いつものwarningsが出ないので
いろいろと試してみましたよっと

#!/usr/bin/perl

use strict;
use warnings;
use lib q{.};

use Hoge;

print "Case:1$/";
my $foo;
$foo++;
print $/;

print "Case:2$/";
my $foo;
++$foo;
print $/;

print "Case:3$/";
my $foo .= 'bar';
print $/;

print "Case:4$/";
my $bar;
my $foo .= $bar;
print $/;

print "Case:5$/";
my $bar;
my $foo . $bar;
print $/;

print "Case:6$/";
my $foo .= Hoge->new();
print $/;

print "Case:7$/";
scalar(my $foo);
print $/;

print "Case:8$/";
length(my $foo);
print $/;

print "Case:9$/";
int(my $foo);
print $/;

print "Case:10$/";
ref(my $foo);
print $/;

print "Case:11$/";
lc(my $foo);
print $/;

print "Case:12$/";
uc(my $foo);
print $/;

print "Case:13$/";
select(my $foo);
select STDOUT;
print $/;

print "Case:14$/";
my $foo eq my $bar;
print $/;

print "Case:15$/";
my $foo == my $bar;
print $/;

print "Case:16$/";
my $foo ne my $bar;
print $/;

print "Case:17$/";
my $foo != my $bar;
print $/;

print "Case:18$/";
my $foo > 1;
print $/;

print "Case:19$/";
my $foo < 1;
print $/;

print "Case:20$/";
my $foo && my $bar;
print $/;

print "Case:21$/";
my $foo and 1;
print $/;

print "Case:20$/";
my $foo || my $bar;
print $/;

print "Case:21$/";
my $foo or 1;
print $/;

print "Case:22$/";
my $foo xor 1;
print $/;

print "Case:23$/";
my $foo >> 1;
print $/;

print "Case:24$/";
my $foo << 1;
print $/;

__END__

これの出力結果が

Case:1

Case:2

Case:3

Case:4
Use of uninitialized value in concatenation (.) or string at test.pl line 28.

Case:5
Use of uninitialized value in concatenation (.) or string at test.pl line 33.
Use of uninitialized value in concatenation (.) or string at test.pl line 33.

Case:6

Case:7

Case:8
Use of uninitialized value in length at test.pl line 45.

Case:9
Use of uninitialized value in int at test.pl line 49.

Case:10

Case:11

Case:12

Case:13

Case:14
Use of uninitialized value in string eq at test.pl line 70.
Use of uninitialized value in string eq at test.pl line 70.

Case:15
Use of uninitialized value in numeric eq (==) at test.pl line 74.
Use of uninitialized value in numeric eq (==) at test.pl line 74.

Case:16
Use of uninitialized value in string ne at test.pl line 78.
Use of uninitialized value in string ne at test.pl line 78.

Case:17
Use of uninitialized value in numeric ne (!=) at test.pl line 82.
Use of uninitialized value in numeric ne (!=) at test.pl line 82.

Case:18
Use of uninitialized value in numeric gt (>) at test.pl line 86.

Case:19
Use of uninitialized value in numeric lt (<) at test.pl line 90.

Case:20

Case:21

Case:20

Case:21

Case:22

Case:23
Use of uninitialized value in right bitshift (>>) at test.pl line 114.

Case:24
Use of uninitialized value in left bitshift (<<) at test.pl line 118.

warningsプラグマ謎い。。。

Hachioji.pmに初参加してきたったー

はい
ということで行ってきましたよHachioji.pm #11
メモとかとってなかったので簡単に

今回のテーマは○○道ということで
自分は退職した道(どー)というお話をしてきました。
途中で銅鑼なったけどね><

(まさかの?)北海道もネタかぶりでした。
YAPCに続いてのLISPの侵略も!?
後で少しだけお話させて頂きましたが、vi使いでいらっしゃるとのこと。

今回は参加者25人(かな?)中、まさかの退職ネタが3件!
きっと冬眠に入るんだ。そうに違いない。

あと、YAPCの時に買えてなかったACME大全をGET!


勝手に前夜祭やったったー

年の瀬ですね。明日明後日からは12月ですね。12月と言えばAdvent Calendarですね!
今年も数多くの技術系Advent Calendarが立ち上がっています。
自分も来年こそはAdvent Calendarデビューしたいと思います。
12月からガラリと環境が変わるので余裕がない><

ということで、MySQL Casual Advent Calendar勝手に前夜祭とかやっちゃうよ!
公式はコチラ => MySQL Casual Advent Calendar
などと勢いで書き始めてみましたが、ベンチがまだとれてない(′・ω・`)
ぐ、ぐぬぬ。。。
正直、レコード数だったり、テーブル設計なんかも迷ってる状態だったりします。
と言い訳をしつつ、ベンチは追記させて頂きます。

実力がないなりに敷居を下げてみよう大作戦!
まぁ、こっちの方が何かカジュアルに書けるんじゃないか説()
という名目で書いてみようと思います。

みなさん、SQL書いてますか?ORMとか使ってたりしませんよね?
今回のお題ですが、以前に次のSQLでSLOW QUERYが出てしまったというお話です。

UPDATE tbl SET col = col + ? [COND]

初めて真っ当にRDBMSを触ったのがOracleだったんですが、かなり使ってたSQL
加算するだけだよね?ちなみにSLOW QUERY吐いた環境はPerlRedhat系です。

SLOW QUERYの内容を見るとプレースホルダが文字列に!
ここであー、アレだな!と思い出した記事がありました。
@kazuhoさんのサイボウズラボ時代に書かれていた記事です。
MySQL の高速化プチBK

とはいえ、環境的にDBIをそのまま使う習慣がなく、某ORMを使う他もなく
3点のベンチをとってみることにしました(※後述、下記のベンチにバグがあった)

  1. SQL_INTEGERを付けない
  2. SQL_INTEGERを付ける
  3. 加算せずにプレースホルダだけにする

結果は2は1よりも高速だったが、3は両者の30倍程度に高速(バグのせい)
という結果となりました。はて、どうしてこんなことになるのだろうか?
考えてみましたが、プレースホルダの置換/加算にMySQLが時間がかかっている?
そんな結果にちょっと納得もいかないまま月日が流れていました(1年以上。。。)

そして、今回こそはその原因を探るべく、再度、調査を行おう!
思いを胸に過去のベンチを見たわけですが、
ベンチをとったコードを見直してみてアレ?と思ってしまいました。

『加算せずにプレースホルダだけにする』
やはり、この条件に大きなミスがあったのです。
はわわ。。。SELECTしただけで、fetchせずに定数を突っ込んでいた><
ついったで相談させて頂いた@kitayama_tさん、@riywoさんに申し訳が><
とはいえ、MySQLに定数を突っ込むだけならそれだけ高速という意味でもある?

この辺がベンチを取り切れないというか、公開に慎重になった理由でもあります。
現在、とれているベンチでは以下の順で高速かな?

  1. 定数を突っ込む(SELECTなし == 評価外)
  2. SQL_INTEGERを付ける
  3. SQL_INTEGERを付けない
  4. SELECTしてプログラム側で加算した値をプレースホルダに突っ込む
正規表現で数値であることを担保した上で

の順となっています(仕事データなので外に出せない><)
ちなみにSQLite@同一マシン(Win機)ではそこまでの差は出ませんでした。
というよりもMySQLと比べてパフォーマンスが出なかったというところですね。

特にオチも根拠もない感じになってしまいましたが、
大抵のプロジェクトではサーバ台数と言う点で
AP > DB かと思います。
であれば、DBにかける負荷をAPで吸収するのは当然ですね。

コードを書く人間からすればSQL一発で出来るのが最適化でしょうが、
局所最適化に過ぎず、(機械も含めた)全体最適化でないとダメだなと実感しました。
インフラチームに余計な負荷かけるのもアレですしね!

こんな単純だと思っていたSQLでもSLOW QUERYを吐いてくれたことで
更新系の処理はできる限りシンプルに、不精せずにAPの数を活かす。
という教訓を得ることが出来ました。

ベンチにバグがあったおかげ?で思った以上にカジュアルな内容になりましたが、
勝手に前夜祭というタイトルとしてはちょうどよかったのかな?とも思います。
それでは皆様、よいAdvent Calendarライフを!

追記:
何だか、0時過ぎて書いたけど、11/29になってた。
(゚ー゚ ).。oO(誰か0日目とか書いてくれないかな)

ふと思ったったー

仕事で先日書いたコードにコメント書き足していてふと思ったんですが、
A|Bな真偽値と1|2な真偽値の組み合わせの条件文ってどう書きますか?

// case.1
if (A && 1) {
    BLOCK1
} else if (A && 2) {
    BLOCK2
} else if (B && 1) {
    BLOCK3
} else if (B && 2) {
    BLOCK4
}

シンプルに書くとこうなりますね。でも、elseがないのが残念です

// case.2
if (A && 1) {
    BLOCK1
} else if (A && 2) {
    BLOCK2
} else if (B && 1) {
    BLOCK3
} else {
    BLOCK4
}

elseにしてみました。でも、このelseは何者?って感じですね

// case.3
if (A && 1) {
    BLOCK1
} else if (A && 2) {
    BLOCK2
} else if (B && 1) {
    BLOCK3
} else if (B && 2) {
    BLOCK4
} else {
    // oops...something wrong
}

elseを追加してみました、でも、elseに入ってくる時点でおかしいですね

// case.4
if (A) {
    if (1) {
        BLOCK1
    } else {
        BLOCK2
    }
} else {
    } if (1) {
        BLOCK3
    } else {
        BLOCK4
    }
}

Bと2が条件に明記されてない上にレキシカルスコープとか考えちゃいますね

// case.5
if (A && 1) {
    BLOCK1
} else if (A) {
    BLOCK2
} else if (1) {
    BLOCK3
} else {
    BLOCK4
}

最初に書いてた条件文がコレ
コメント書いてる途中で、新卒の人間が保守ったりって考えると不親切?
とか思って、何人かに聞いてみたわけですが、仕事コードだと
どれが最適なんでしょう?
20111112追記: case.n、s/EXPR/BLOCK/