Personal tools
You are here: Home ブログ 井上
« January 2008 »
Su Mo Tu We Th Fr Sa
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Categories
カテゴリなし
 
Document Actions

DTIから値上げの連絡

一ヶ月遅れの反応は、郵便を一ヶ月に一度ぐらいしかチェックしないためです。 サービス内容変更、という表題ですが、単なる値上げです。突然です。納得できません。

引用

1)高トラフィック規制対象からの解除 ひかりone Tタイプ各プランでの利用においては、2007年10月 より開始しました 15GB/日以上の高トラフィック規制対象外となります。

この付加価値を欲しがる人に別途料金でサービスする、という話なら文句はありません。しかし、このサービスを受けないという選択肢はありません。値上げを受け入れる以外の選択肢がありません。

9月ごろから嫌な予感がありました。突然、次の文面のメールが届きました。

石田氏のメールから引用

 などなど、さまざまな魅力的なサービスを、今お支払いいただいている料金を変えることなく投入していきます。(一部オプションは有料になる予定です)

今すぐプロバイダを変更するのは面倒なので、次に変える時は、DTIを選択肢から外そうと思います。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/hate-dti/tbping

Google Documentのプレゼンツール

Google Documentのプレゼンツール(PowerPointキラー?)を初めて使ってみました。 元々、プレゼンで字しか使わない(使えない)ので、機能的には充分です。 まあ、使い方はemacsで書いた文をコピーペーストしていくだけですが。 こういう使い方(文を貼り付けていくだけ)なら使いモノになります。 現状、PowerPoint大好きな人にはまったく役に立たない気がします。

文を貼り付けていくだけでも、実は重くてイライラです。 勉強会の資料をこれで作る気はありません。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/google-ppt-killer/tbping

Yahoo Pipesの勉強会資料

浜辺さんによるYahoo Pipesの勉強会資料を公開しました。

以前、(いわゆる)Web APIの(いわゆる)APIキーの秘匿性が良く分からない、と書いたことがあります。

原理的にAPIキーは完全に秘密にはなりえません。だからと言って、APIキーをWebサイトに晒すのはいいのか、サービス提供者との紳士協定違反では無いのか、という疑問でした。 結論から言うと、Yahoo Pipesの中では、普通にAPIキーが晒されています。例えば、Amazon Webサービスを使っているPipesを検索すれば、AWSAccessKeyIdの値が簡単に得られます(Amazon WebサービスではAPIキーではなくアクセスキーと呼んでいます)。"Private String"というパイプもあるので、Yahoo Pipesの意向はこれを使ってほしいのかもしれません。

初めてのYahoo Pipes

Amazonから、これから発売予定の書籍一覧をタイトルのキーワードでフィルタして表示するアプリを作ってみました。

でも、実は動作が変です。Yahoo Pipesの問題ではなく、Amazonの問題です。Power=pubdate:afterがまともに動いていません。次のURLで、発売日が2008/1/1以降、かつタイトルにP2Pを含む書籍が得られるはずですが、古い書籍もひっかかります。

詳細サーチ(http://www.amazon.co.jp/b/ref=sv_b_0?ie=UTF8&node=124284011)で、日付指定をしてもきちんと動作していないようです。謎です。

浜辺さん作のクールなアプリ。

サーバサイドのプログラミングゼロで実現しています。これを聞いて驚かない人がいたら、よほど進んでいるかよほど遅れているかのどちらかでしょう。 サーバでXMLをちょこまかパースするコードを書いている世界とは別次元です。

del.icio.usのデータのビューワにdirec.tor(http://www.johnvey.com/features/deliciousdirector/)というのがあって、そのビューワに合う形にdiggのデータをYahoo Pipesで加工してから流しています。世間でマッシュアップと言われるものが、ほとんどアグリゲーションの域をでていない(複数サイトの情報を一緒に見せるだけ)という中、このやすやすと境界を越える身軽さに脱帽しました。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/yahoo-pipes/tbping

ifconfigの出力をsedでパース

GNU/LinuxでローカルのIPアドレス、ブロードキャストアドレス、ネットマスクを取得するコード例は以下のようになります。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <arpa/inet.h> /* for inet_ntoa() */

int main(int argc, char **argv)
{
    struct ifreq ifr;
    const char *ifname = "eth0";

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    strcpy(ifr.ifr_name, ifname);
    ifr.ifr_addr.sa_family = AF_INET;
    if (ioctl(sock, SIOCGIFADDR, &ifr) == 0) {
      struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
        printf("%s\n", inet_ntoa(sin->sin_addr));
    }
    if (ioctl(sock, SIOCGIFBRDADDR, &ifr) == 0) {
      struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_broadaddr;
        printf("%s\n", inet_ntoa(sin->sin_addr));
    }
    if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
      struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_netmask;
        printf("%s\n", inet_ntoa(sin->sin_addr));
    }
    close(sock);
    return 0;
} 

コード例を見てわかるように"eth0"というネットワークインターフェース名に依存したコードになっています。 ifconfigコマンドは、/proc/net/devファイルを開いてインターフェース名を取得しています。

AirOneでローカルIPアドレスを取得する必要があります。上のようなコードを書くのが面倒なので、ifconfig(1)の出力をパースしています。次のようなシェルスクリプトです。

LANG=C /sbin/ifconfig -a | sed -n '/.*inet addr:\([0-9.]*\).*Mask:\([0-9.]*\)/{s//\1 \2/;p;q}'

これは少し問題がありました。lo(loopback)インターフェースが先に現れると、そのアドレスを拾ってしまいます。loインターフェースは読み飛ばす必要があります。grepを挟むか、あるいはsedをperlで書き換えるかと迷いましたが、次のように簡単にsedで書けました。perl使ったら負けだと思っていました。

LANG=C /sbin/ifconfig -a | sed -n '/^lo/,/^$/d; /.*inet addr:\([0-9.]*\).*Mask:\([0-9.]*\)/{s//\1 \2/;p;q}'

動作を簡単に説明します。-nオプションで暗黙の出力を抑制しています。この例のようにマッチしたパターンだけを表示したい場合には有効なオプションです。/^lo/,/^$/d でひとかたまりです。dの部分がコマンドです。カッコをつけて /^lo/,/^$/{d} と書くこともできます。// の中はそれぞれ正規表現です。loで始まる行と空行です。カンマでつなぐと、それぞれの正規表現にマッチする間コマンドを実行、という意味になります。dコマンドはパターンスペース(入力行)を削除して、次の行を読み込みます。-nオプションを指定している場合、単に入力行を無視して次の行を読む、と見なして構いません。後続する部分は // で囲まれた正規表現がマッチ条件で、{}で囲まれた部分がコマンドです。sは置換、pは出力、qは終了です。実に直感的な命名です。

PerlやEmacsのようななんでもできるツールは勝って当然、sedで勝つところが醍醐味です。例えて言えば、激ペナでボールになる変化球ばかり使って打ち取るのがPerlやEmacsで、ストレート一本、ストライク勝負で打ち取るのがsedの世界です。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/we-love-sed/tbping

WEB+DB PRESS vol35の原稿を公開

WEB+DB PRESS vol35 (2006年10月) 特別企画[Webプログラマのための]速習コードリーディングの原稿を公開しました。 1年以上前の原稿ですが、公開するのを忘れていました。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/webdb-vol35/tbping

MS-WindowsのローカルIPアドレス、ブロードキャストアドレス、ネットマスクを取得するコード例

先日、GNU/LinuxのIPアドレス、ブロードキャストアドレス、ネットマスクを取得するコード例を書きました。

対称性のためにMS-Windowsのコード例も書きました。コードばかりで見栄えが悪いので、以下に書きました。

ちなみに、MS-Windowsでipconfigの出力をパースするコードを書こうとは思いません。MS-Windowsで、子プロセスを作って出力をパイプで読み取る処理が、信用できないからです。偏見かもしれませんが。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/windows-ipconfig/tbping

シェルのイディオム

シェルは対話的なコマンドラインツールであると同時にプログラミング言語でもあります。 しかし、対話的なツールの利便性を優先しているので、プログラミング言語として見ると変態的です。 何物にも似ていません。なのですぐに忘れます。ぼくは相当、シェルスクリプトを書いてきた自負がありますが、それでも10回まわるループのコードすらすぐに忘れます。

最もポータブルなループのコードは次のようになるでしょう。ここでのポータブルの意味は、古いシェルでも動くという意味です。シェルはすべてbourneシェル系を前提にしています。1行で書いていますが、;(セミコロン)の部分を改行にして、複数行に書いても構いません。

i=0;while [ $i -lt 10 ]; do echo $i; i=`expr $i + 1`; done

この、意味が分かりそうに見えるコードにも、他の言語からすれば信じられない落し穴が隠れています。

最初の i=0 は、シェルを知らなくても変数iに値0を代入していると予想できるでしょう。なんとなく詰まって見づらいと思って次のように空白を入れると無情にもエラーになります。

i = 0
bash: i: command not found

エラーメッセージを見れば何が起きたか予想がつくと思います。変数への代入の時は = の前後に空白をいれてはいけないのです。

変数の左辺値が欲しい時は i とそのまま書いて、右辺値が欲しい時は $i と $ をつけるあたりも、そんなもの構文で判断してくれ、と文句を言いたくなりますが、そういうものです。ちなみに ${i} と中括弧をつけることもできます。中括弧は ${foo}bar のような場合、必要になります(変数fooの値と文字列barの連接になります)。

while の後ろの [ は有名なので知っている人が多いと思います。コマンドとしても存在しますが(手元のDebian etchでは/usr/bin/[)、いまどきのシェルでは組込みコマンドになっています。man [ すれば分かるように test コマンドの別名です。ちなみにtestコマンドはCプログラマには有名です。test.c(たいていprintfが書かれている)をコンパイルしたtestという実行ファイルを実行したのですが何も出ません、という泣ける話です。Unix Cの最初の洗礼です。

[ ] の中の意味は man test で調べてください。perlにもあるので lt は less than の略だと、初めて見ても気づく人はいるかもしれません。

doからdoneの間が、whileのループでまわる部分です。doとdoneはかわいいものですが、ifの場合、終わりがfiです。昔からあるから誰も文句を言いませんが、いまどきの言語がfiなんてキーワードを使ったら、ふざけているのかと問い詰められそうです。

バッククォートはコマンド実行結果の展開の意味です。exprは各種計算ができます。興味があれば man expr してください。expr は数値演算以外に文字列演算もできます。正規表現を使ったsedみたいなことまでできてしまいます。

/sbin/ifconfig -a| while read x; do echo `expr "$x" : '.*inet addr:\([0-9.]*\)'`; done

簡単に説明すると、expr A : B と書いた時、文字列Aに対して正規表現Bでマッチングして、正規表現の部分パターン(=丸カッコで囲ったマッチ部分)が返ります。上のコードを実行すると空行がたくさんでます。気になるなら、次のように空行を削ってください。

/sbin/ifconfig -a| while read x; do echo `expr "$x" : '.*inet addr:\([0-9.]*\)'`; done | tr -s '\n'

最初の例に戻ると、bashなら、`expr $i + 1`の代わりに次のようにも書けます。この方が短くて良いのですが覚えられません。

i=0;while [ $i -lt 10 ]; do echo $i; i=$((i+1)); done

${} の中で、思ったより色々なことができます。

まず、一番良く使うイディオムから。

: ${foo=bar}

変数がfooが未定義なら代入を行い、定義済みなら代入をしません。elispで (defvar foo "bar") と書くような感じです。 fooの部分に環境変数を使うコードは良く書きます。ユーザが環境変数を設定済みならそれを尊重し、未設定ならデフォルト値を使いたい場合に書くコードです。

以下はあまりポータブルでは無いので覚えられません。

文字列から部分文字列を取得するには次のようにします。

# 書き方:  ${value:offset:length}
foo='foobar'; echo ${foo:2:3}
=> oba

部分文字列の置換もできます(正規表現ではありません)。

# 置換の書き方:    ${value/pattern/replace}
# グローバル置換の書き方(いわゆる /g):    ${value//pattern/replace}
foo='inet addr:192.168.80.11'; echo ${foo/inet addr:/address=}
=> address=192.168.80.11

最後にシェルスクリプトのデバッグについて書きます。たいていは sh -x で実行すれば分かります。ファイル名がfoo.shなら sh -x foo.sh と実行します。

それでもダメならechoデバッグです。今はprintf(1)コマンドもありますが、echoデバッグです。なぜならechoは悲恋の精霊だからです(例: http://www.arakihp.jp/koramu/koramu34.html)。想いが届かず嘆きのあまりやせ細りついに身体が消え去るecho。でも声だけは残ったecho。printfのような無機質なコマンドとは一線を画す叙情的なコマンドです。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/shell-idioms/tbping

別解 (Re:シェルのイディオム)

Posted by inoue at 2008-01-25 10:25
for i in `seq 0 9`; do echo $i; done

プログラマと失われた時

良いプログラマを見分ける指標はいくつもあります。ひとつの指標で測れるほど単純なものではないからです。更にややこしいことに、作っているソフトウェアの分野や他のメンバーとの関係(スキルの得意不得意。文化的なこと)でも、プログラマの評価が変わります。

もし、ひとつしか指標を選べないとしたら、ぼくは「可読性の良いコードを書けるか」という指標を選びます。可読性が高くても、コードを書くのがとても遅いかもしれません。可読性が高くても、アルゴリズムやデータ構造の知識が無くて実行性能の低いコードしか書けないかもしれません。可読性が高くても、100行以下の短いコードしか書けないかもしれません、あるいは、入門書に載っている簡単な例題以上のことはできないかもしれません。まったく相関が無そうな指標もあります(*1)。様々な可能性はありますが、可読性の高いコードを書ける人は、他の指標で良い基準に達している可能性が高い、という経験則です。作業速度や規模の大きな開発(設計)の力は、経験を積んで成長する可能性に賭けられますし、実行性能の低いコードの改善は、頭の中がマシン語でできているような人に任せることも可能です。

可読性の高いコードを書く動機づけとして、自分が以前書いたコードが読みづらくて困ったから、という理由を挙げれば、より高く評価します。

自分で書いたコードは、コンテキストを覚えている限り、自分で理解するのは簡単です。誰でもできます。しかし、他人が自分のコードを読んだ時、どう感じるかを想像することは容易ではありません。他人から、自分のコードを理解できないと言われた経験をしても、それを自分の問題として受け入れることはなかなかできません。自分が、他人の書いたコードを読んで理解できない経験をしても、自分の能力不足に帰着しがちです。

ある日、昔自分自身が書いたコードを読んで理解できない、という経験をすると、ショックを受けます。なんと言っても、かつては完璧に理解していた(*2)コードが分からなくなっているのです。ここから、可読性の高いコードを書くための強い動機づけが生まれます。

コードを書いている最中は、そのことで頭が一杯なので、当たり前に思っていることがたくさんあります。これを(コードの外の)コンテキストと呼びたいと思います。コードを書いている人にとって、コンテキストは当たり前すぎて、それは誰でも知っているはずだ、と錯覚しがちです。コンテキストを理解できない他人が現れると、なんでそんなことも知らないのか、と憤ったりします。問題に集中している当人には重要でも、他の人から見れば、そんなこと知ったことか、ということも多々あります。そして、いつか未来の自分も、そんなこと知ったことか、という人のひとりになるかもしれません。

可読性の高いコードを書くということは、そこに想像が及ぶかです。

ぼくの理想のコードは、ソースコード*だけ*で完結しているコードです。余計なコンテキストに依存していなければ誰がいつ読んでも理解できるからです(*3)。もちろん、これはありえません。なので、未来の自分が様々なことを忘れていても理解できる仕掛けをほどこします。それは名前のつけ方だったり、コメントでのメッセージだったりします。しかし、すべてをくどくどと説明はできません。時間もありませんし、そもそも情報量が増えると重要な情報が埋もれるという事実があります(*4)。この辺の取捨選択のバランスは経験です。キーワードひとつでも未来の自分への気づきのメッセージとして充分な場合もあります。最も極端な例は、XXX コメントだけをつける場合です。「なにか思い出すべきコンテキストがあった」ことを、未来の自分に気づかせるサインだけで充分と判断した場合です。

さて、言うほど、これは簡単な話ではありません。例えば、HTTPを知らない人がコードを読むことまで想定してWebアプリを書くことに意味はあるでしょうか。意味があるとは思えません。プログラマなら当然知っているべき標準技術やアルゴリズムを知らない人まで想定する気はありません。これらの当然知っておくべき(と自分が思う)コンテキストと、上で挙げたコンテキストの区分は、非常に難しい話です。このバランスも、経験からとしか言いようが無いのかもしれません。

後者のコンテキストをドメインコンテキストと呼ぶとして、ドメインコンテキストをまったく知らない人を想定して、それぞれのコードを書くのはやりすぎです。コードのいたるところで、ドメインコンテキストの説明が必要になってしまいます。ドメインコンテキストの説明は、そのソフトウェア全体に付属した文書が負うべき責務です。コードを読む前に、これだけは背景知識として当然知っておくべき、という文書です。未来の自分がその文書の存在すら忘れたら、と心配するのは、まあ杞憂でしょう。そこまで言ったら、未来の自分はプログラミングを忘れているかもしれません。記憶喪失になった未来の自分が、コードを読んだ瞬間、色々なことを思い出したら素敵な話かもしれませんが、そんなことを想定してコードを書くのは病んでいます。

(*1)「伽藍とバザール」(http://cruel.org/freeware/cathedral.html)に「何を書けばいいかわかってるのがよいプログラマ」というくだりがあります。可読性の良いコードを書く指標ではひっかけられない「良いプログラマ」のひとつのタイプです。

(*2)今、自分の目の前のコードを、よく理解しないまま書いているプログラマは論外です。忘れて理解できないことと、そもそも理解せずに目の前のコードを書いていることは全然違う話です。

(*3)結果論として、凝集度の高いコード、結合度の低いコードを目指すことになります(暗黙の依存関係なんて絶対忘れます)。これらは、本に書いてあるからそうするのではなく、自然とそうなるものなのです。

(*4)今回のような話をすると、この「なんでも説明すべき症候群」に陥る人がいます。膨大な情報の中から、何が重要で、何が重要でないかを未来の自分が識別できると考えるのは、やはりこれもコンテキストに浸かっているからこそだと思います。じゃあ、どうすれば良いのか、と言われそうですが、経験から得たテクニックめいたものはありますが、披露できるほどの自信はありません。

The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/lost-time/tbping

Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.