2013年7月31日

Blogで簡単にシンタックスハイライトを実現する3行のおまじない

body終了タグの直前に以下を書いておけばよろしい。Markdownで書いたコードブロックとかが簡単にシンタックスハイライト対応になる。

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
<script>$(function(){$('pre > code').addClass('prettyprint');prettyPrint();});</script>

外部リソースに直接向けてあります。パーソナルユースなら問題ない感じがします。jQueryもGoogleにしてあるのは、https対応しているので、//始まりのURLが記述できるからです。

jQueryのバージョンは適宜調整して下さい。jQuery2系はlatest versionへのリンク的なやつは公開しないポリシーみたいですね。

html出力時にサーバーやジェネレーター側で変換するとコストが大きいし、HTMLは汚くなるしであんまり好きじゃないですね。

投稿者 Songmu : 02:41

2013年7月29日

Puncheurのご紹介改めオレオレWAFを作ってしまった件

職質テックトークでもちょっと話したのですが、 PuncheurというWAFを作ってCPANにもあげてしまいました。

読み方はパンチャーですが、パンツァーでもパンチラでもなんでもいいです。

気軽に開発を始められてカスタマイズ可能なWAFとなっております。 最低限のユーティリティーを提供しつつ、DispatcherとViewは差し替え可能になってるという、最近よくあるあれです。 実際かなりAmon2からコピペです。

ちょっとしたPSGIアプリケーションをCPANで配布する的な用途に向いているのが大きな特徴となっています。

主な特徴としては以下。

  • Perl5.8切り捨て
  • すべてMyApp->new(%opt)から始まる
    • MyApp->new(%opt)->to_psgi; って書ける
    • my $c = MyApp->new(%opt); ってCLIで書ける
    • Lite的な奴も.psgiにべろっと書かずに、ちゃんとpackage書いて、plackup -MMyApp -e 'MyApp->new->to_psgi'すればいい
  • configファイル決め打ちじゃなくて、指定もできるように
  • myapp.pl みたいなサーバー起動スクリプトが書きやすい
  • プロジェクトディレクトリ前提ではない
  • 比較的一枚岩。あんまFlavor有りきにはしない
  • Puncheur::Requestが高速(なはず)

Perl5.8切り捨て

//とかstateとかsayとかが使えると捗りますね。

すべてMyApp->new(%opt)から始まる

MyApp->new(%opt)->to_psgi とか書くのが分かりやすいんじゃないかなーと思います。コンストラクタにオプションとか渡せると分かりやすそう。

my $c = MyApp->new(%opt) とかやればそのままコンテキストオブジェクトとしてCLIでも使える感じ。Plugin::Modelを使えば、 $c->model(...)みたいなやつもできます。

1ファイルアプリみたいなのもPuncheur::Liteを使えば書けますが、psgiにベロっと書くんじゃなくて、ちゃんとpackage書いてplackup -MMyApp -e 'MyApp->new->to_psgi'すればいいんじゃないか的な思想になっております。

configファイルも決め打ちじゃなくて指定できるように

従来の多くのWAFだとconfigファイルが規約で決まっていたりするわけですが、同じリポジトリでメインアプリと管理画面を管理したいみたいなときに困ることがあります。

Puncheurでは、MyApp->new(config => $conf:filename|HashRef)などとすることにより設定を差し替えることが可能です。

Amon2と同様にload_configをオーバーライドすることで設定読み込みを変更することも可能です。

myapp.plみたいなサーバー起動スクリプトが書きやすい

割と目玉機能のつもりですが、以下の様なスクリプトを書けば簡単にサーバーとして使うことができます。plackupに指定するオプションや、MyApp->newに渡すオプションを 混ぜこぜで使うことができます。(ちょっとこの辺りは変更の可能性があります)

% cat my-app.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Puncheur::Runner;
# MyAppはPuncherアプリ
Puncheur::Runner->new('MyApp', {
    # default plack settings
    server => 'Starlet',
    port   => 1988,
})->run;

% ./myapp.pl -p 9955 --config my_config.pl

プロジェクトディレクトリ前提ではない

単なるプロジェクトディレクトリ形式だけではなく、CPANで配布する用のアプリを作りやすくなっています。例えばテンプレートディレクトリの デフォルト配置配置が share/tmpl になっているところもそんな狙いが伺えます。

比較的一枚岩。あんまFlavor有りきにはしない

Puncheur.pmを読めば比較的処理が分かるんじゃないかと思います。Flavorとか使わないでも気軽に書き始められる感じになっております。 現状Flavor機構はないのですが、そのうち追加はしたいなーとは思っています。

Puncheur::Requestが高速(なはず)

req->urireq->baseをキャッシュしたり、クエリのパースにURL::Encodeを利用したりと高速な感じになっております。 この辺はNephia::Requestで得られた知見を盛り込んでおります。 クエリのパースに関しては、Plack::MiddlewareのどこかでPlack::Requestが使われたりするとあんま意味が無かったりします。 Plack::Requestが自動的にPlack::Request::XSとかに差し替わるようになってると嬉しいのかなーとか思ったりもしましたが、 クエリのパースコストがそこまで支配的になることは少ないのかも知れません。


テストがない。ドキュメントがない。メモリリーク周りケアできてるかよくわかってないと三重苦ですが、その辺を解決しつつ、 その後はflavorとかPluginとか多少充実させるかなーとか思っております。

Puncheurを使った、RijiというBlogアプリケーションもCPANに上げてありますがその説明はまたそのうち。

Puncheurの名前の由来としては、元々PHPっぽい名前ってことで、PhiloPurple(紫が好き、的な造語)という名前にしていたのですが 覚えづらいし、思ったよりまともな出来になってきたので、ちゃんとした名前にしたいなーと思ったので変更した次第。

“Roadie”という名前も考えたのですが、RubyにHTMLメールを配信するための同名のgemがあり、メンテもしっかりされている 感じだったので諦めた感じでした。Puncheurも自転車用語ですがそのへんの話も職質テックトークで 軽く触れていますので、お聞きいただければと思います。

投稿者 Songmu : 22:14

2013年7月15日

Kyoto.pmに行ってきました

トークもさせてもらって来ました。資料は以下

http://songmu.github.io/slides/kyoto0713/start.html

折角nekokakさんがゲストなので、Tengに絡めた話をしたらいろいろ質問とかもしてもらえてよかった。 DBIx::TransactionManager::EndHookの話をしたら「これ本家に取り込みますよ」的なことも言ってもらえたのも大分収穫だった。 やっぱ、直接コミュニケーションしたほうが色々速いってのはありますね。

Kyoto.pmはだいぶ良かった。Perlをいろいろな用途に使っている人がいて、そのへんの話も聞けたのが興味深かった。 モジュールとか使わせてもらってるけど普段あまり接点ないはてなの人とかと話せたのも大きかった。

Onishiさんと色々話せたのが有意義でした。motemenさんとも話したんだけど「Class::Accessor::Lite::Lazy使ってます!」 って言えなかったのは残念でした。

また地方pm、お邪魔したい。

azumakuniyukiさんが話してた、Hainekoがだいぶ面白くて、 HTTPでメールが送れるってのは大分胸熱だなーと思いました。

投稿者 Songmu : 01:29

2013年7月 9日

Teng::Plugin::SearchJoinedとSQL::Maker::JoinSelectとKyoto.pmの話

N+1問題という近年まことしやかに語られるようになった言葉があります。当たり前の事象に大げさに名前をつけるのどうなのかと思ったりもするわけですが、名前が付いていると案外説明に便利だったりして「名前重要」だなーとか思ったり思わなかったりするわけです。

最近はTengを便利に使わせてもらっているわけですが、Tengはシンプルな分、何も考えないで使うとN+1問題が多発してしまいます。そう言う思想なわけです。

クエリ数を抑えるためにJOINしたクエリを投げたくなるわけですが、そうなると自分で投げるしか無くて、それはまだいいとしても、普段Rowオブジェクトを使い慣れているゆるふわエンジニアとしては、JOINして複雑なデータを取った挙句、途端に生々しいハッシュを使わないといけないのはだいぶつらいものがあります。

ということで、

  • JOINしたクエリを分かりやすく記述できる
  • Rowオブジェクトをちゃんと取りたい

という目的をかなえるために、Teng::Plugin::SearchJoined というものをリリースしました。使い方はSYNOPSISとほぼ同じですが、以下の様な感じです。

package MyDB;
use parent qw/Teng/;
__PACKAGE__->load_plugin('SearchJoined');

package main;
my $teng = MyDB->new(...);
my $itr = $teng->search_joined(user_item => [
    user => {'user_item.user_id' => 'user.id'},
    item => {'user_item.item_id' => 'item.id'},
], {
    'user.id' => 2,
}, {
    order_by => 'user_item.item_id',
});

# $itr->suppress_object_creation(1); も可能
while (my ($user_item, $user, $item) = $itr->next) {
    ...
}

割と直感的でいいんじゃないかとおもいます。デフォルトINNER JOINですが各種JOINにも対応可能です。その辺りは、ドキュメントをご確認ください。

このプラグインはSQL::Maker::Plugin::JoinSelectというモジュールに依存しており、これもまた、SQL::MakerでJOINしたクエリを分かりやすく記述するために書いた拙作のモジュールです。

このモジュールを作るにあたっては、SQL::Makerに幾つか細かいp-rを送り付け、挙句一時的にTengをぶっ壊したりして大変ひどい感じだったのでした。いつもながらしょうもないp-rに素早く対応してくれるtokuhiromには感謝です。

今週末のKyoto.pmでトークさせていただくのですが、多分このへんの話をするんじゃないかと思います。

宿とか何も決めていないので誰か宿を提供してくださったりすると大変嬉しいです。ただし当方いびきがうるさいです。

あわせて読みたい。 http://blog.64p.org/entry/2013/07/09/114744

投稿者 Songmu : 00:57

2013年6月28日

Test::mysqldのcopy_data_fromでテストが更に捗る話

少し前ですがTest::mysqld 0.17からは copy_data_fromというオプションが加わっています。

これは、Test::mysqld起動時にコピー元のdataディレクトリを指定できるもので MySQLの起動時間を節約することができます。テスト開始時にDBに大量のデータを 入れておきたい場合に特に有効です。

特にゲームなどの場合は、大量のマスタデータもコードの一部と言えるので、ちゃんと 全部流し込んでからテストを実施したいという要件があるので重宝します。

さて、そのdataディレクトリをどうやって作ればよいかという話になるのですが、 それも、Test::mysqldに事前に作らせてどこかに配置しておけば良いでしょう。

手順としては例えば以下のようになります。

  1. ‘tmp/test_mysqld_data’ をdatadirにしてTest::mysqldを起動
  2. DDLとマスタデータの流しこみを行う

上記を事前にやっておき、実際にテストを実施する時は、’tmp/test_mysql_data’. からcopy_data_fromします。

コードは以下の様な感じになるでしょう。

use Path::Tiny qw/path/;
use Test::mysqld;
sub prepare_mysqld_copy_data {
    my $datadir = 'tmp/test_mysqld_data';
    path($datadir)->rmtree;

    my $mysqld = Test::mysqld->new(
        base_dir => 'tmp/test_mysqld',
        my_cnf   => {
            datadir => $datadir, # $datadirを指定
            'skip-networking' => '',
        },
    ) or die $Test::mysqld::errstr;

    # データ流し込み
    deploy_test_database($mysqld->dsn);

    # ここで一旦処理終了
}

deploy_test_databaseの中見は以下の様な具合です。 スキーマの流しこみと、これまたリポジトリにコミットしてcsv管理してある マスターデータを流し込んでいます。 先日書いたDBIx::FixtureLoderが活躍していますね(ステマ)。

use DBI;
use DBIx::FixtureLoder;
sub deploy_test_database {
    my $dsn = shift;
    my $dbh = DBI->connect($dsn);

    # スキーマ流し込み
    my $source = path('sql/myapp_ddl.sql')->slurp;
    for my $stmt (split /;/, $source) {
        next unless $stmt =~ /\S/;
        $dbh->do($stmt) or die $dbh->errstr;
    }

    # マスタデータ流し込み
    my $loader = DBIx::FixtureLoder->new(dbh => $dbh);
    $loader->load_fixture('data/master/item.csv');
    $loader->load_fixture('data/master/job.csv');
    $loader->load_fixture('data/master/skill.csv');
}

これで、’tmp/test_mysqld_data’ 以下にデータが作られます。 以降は各テスト実施時に以下のようにTest::mysqldを起動すれば良いだけです。

my $mysqld = Test::mysqld->new(
    copy_data_from => 'tmp/test_mysqld_data',
    my_cnf         => { 'skip-networking' => ''},
) or die $Test::mysqld::errstr;

テストファイル毎にTest::mysqldを起動する形になりますが、 マスタデータが多い場合、

  • Test::mysqldのプロセスを使い回して起動時間を節約するよりも、データを流し込む時間を節約するほうが効果が高い
  • テストケース毎の競合を考える必要がない
  • テストでデッドロックなどが発生することを心配する必要がなく並列度を上げやすい
  • 各テストで初期化処理やクリーンアップ処理を複雑に考えずに済む

といったメリットもあるので、この形を採用するに至りました。

実際今やっている案件だと、素直にTest::mysqldを起動してデータを流し込んだ場合、10秒程度時間がかかりますが、copy_data_fromを使った場合は1秒程度に短縮されますtempfs的なものを使えばもっと速くなるでしょう。

OSXでtmpfs的なことをするのは村瀬大先生のエントリーが参考になります。

ちなみに、本来は

  • datadirがない場合のケア
  • マスタデータやDDLが更新された場合のdatadirの作り直しの処理

などが必要なので、それも考慮した形だともうちょっとコードは複雑になります。その辺の話はそのうち書くかも。また、このdatadirを元に開発用のMySQLを立てたりもしていますがその辺の話もまたそのうち。

実はこれと同様のことを自力で頑張っていたりしたので、これは神機能来たなーと、リリース直後にkazuhoさんがアナウンスする前にChanges読んで思っていたのですが、使ってみたらやっぱり神だったのでBlogろうと常々思っていてやっとblogった次第。

ちなみに最初に自力で頑張っていたのは僕ではなくて、テスト番長の335先生で、copy_data_fromがなかった時代の苦労が綴られております

彼も今年は、perl な web application のためのテスト情報という形でYAPCのトークに応募しているので、非常に楽しみですね。

投稿者 Songmu : 01:36

2013年6月23日

CPANで意図しない名前空間の取得を防ぐために

だいたいこのへんで教えてもらった話のまとめです。

http://lingr.com/room/perl_jp/archives/2013/04/03

CPANで名前空間を取るのは簡単です。今ならCPANに上げるコードベースの「どこか」に package Hoge; と書けば、CPAN Indexerにインデックスされていとも簡単にHoge名前空間のオーナーになれます。 (執筆時現在Hogeのオーナーはいません)

これはlib/以下の.pmファイルやファイル先頭のpackage宣言だけに限った話ではありません。 例えば、example/MyApp.pmとかも対象です。

ちなみに誰がどの名前空間を持っているかは以下を見ることでわかります。

http://www.cpan.org/modules/02packages.details.txt

多くの場合この挙動に困ることはありませんが、以下の様な場合に困ることがあります。

  1. example codeを同梱してその中にpackage宣言を含む場合 eg. package ExampleApplication;
  2. 自分が持っていない他人の名前空間のpackage宣言をする場合 eg. package Plack;

1の場合は、特に欲しくもないExampleApplicationという名前空間を取得してしまいま す。あまりかっこよくありませんし、もし他の人がその名前空間を欲しがったら困るでしょう。

つい最近だと、Mozilla::DOMのexampleにMinilla.pmが同梱されていて、名前空間がす でに取られていたので、Minillaでは交渉して名前空間を開けてもらったみたいな話もあったりし ました。

2の場合は「権限のない名前空間を取ろうとするんじゃねーよ!」ってCPAN Indexerに怒られます。 そして無常にも ** UNAUTHORIZED RELEASE ** の烙印を押されます。

そういうことを起こさないために以下のような対応が必要です。

  • 適切にnoindexを設定する、またはnoindexをケアしてくれるauthorizing toolを使う
  • packageの後に改行を入れる # hide from PAUSE ハックを使う(あまりやるべきではない)

適切にno_indexを設定する、またはno_indexをケアしてくれるauthorizing toolを使う

CPAN::Meta::Specのno_indexの項 に書いてあるように、インデックスしてほしくない項目をno_indexで指定することができます。 Makefile.PLやBuild.PLに適切な設定項目があります。

一応、t/やinc/などはIndexerはskipしてくれるようになっていますが、そういう挙動 に期待せずに、ちゃんと指定した方が良いです。

また、MinillaやMillaだと、

directory => ['t', 'xt', 'inc', 'share', 'eg', 'examples', 'author']

を自動的にno_indexに追加してくれているので、その辺気にしなくて良いので楽チンです。

packageの後に改行を入れる # hide from PAUSE ハックを使う(あまりやるべきではない)

他人のモジュールに対して、モンキーパッチしたいとか、メソッドを追加したいそうい うそもそもお行儀の良くない要件がごくたまにありますが、そういう時に、素直 にpackage宣言を書いてしまうと、名前空間を取ろうとしてしまうので良くありません。

そういう時は以下のように改行とコメントを入れることでインデックスをさせないこと が可能です。

package # hide from PAUSE
    Plack;

こういう他人のモジュールに動的に手を入れたいという要件の時のみに使うべきで、 そもそもそういうお行儀の良くないことはあまりやらないほうがいいでしょう。

逆に、ファイルの先頭に書かないinner packageなどで、package宣言の後に改行を入れて しまっているケースをたまに見かけますがこれはあまり良くありません。

なぜかというと、サブパッケージであっても、その名前空間を取得しておかないと、 他の人にその名前空間を取られてしまうかもしれなくて悲しいからです。


余談ですが、CPANモジュールはlib/ 以下にモジュールを配置するのが一般的な形ですが、 あくまで慣例であって、別にそう決まっているわけではありません。 また、Inner Packageなどもあるので、ファイル名とパッケージ名が一対一対応しているとも 限りません。

なので涙ぐましいパース処理をIndexerは行なっています。

その様子は https://github.com/andk/pause/tree/master/lib/PAUSE 辺りのソース を読むと良いでしょう。

投稿者 Songmu : 02:02

2013年6月22日

勝手に続:DBIx::Tracerを使って流れているSQLのテストをしてみた話

http://shibayu36.hatenablog.com/entry/2013/01/22/080049

このへん見て、もっと汎用的に手軽に使える感じにしたいなーとか常々思ってたので以下の様なユーティリティーをプロジェクトのt::Utilに追加した。

sub trace_sqls(&) {
    my $code = shift;
    my @sqls;
    require DBIx::Tracer;
    my $tracer = DBIx::Tracer->new(sub {
        my %args = @_;
        push @sqls, $args{sql};
    });
    $code->();
    @sqls;
}

以下のように使う。

my @sqls = trace_sqls {
    $dbh->do('UPDATE ...');
    ...
};

@sqlsに流れたSQLが入ってきます。便利。

みたいなことを社内IRCで発言したら、soh335先生に「あーDBIx::QueryLog版だけど同じようなの半年前に作ってたわー」って言われて涙目であった。

なんか最近やっとテストを楽に書く方法とかそういうのを色々考えられるようになってきて、テスト番長であるsoh335先生の背中が見えてきた感じがする。

投稿者 Songmu : 19:21

2013年6月17日

DBIx::FixtureLoaderってのを書きました

https://metacpan.org/module/DBIx::FixtureLoader

これもまたどこも同じようなの作ってるんでしょうけど、テストとかでさくっとfixture 読み込んでInsertして欲しい的な要件で作りました。使い方は以下の様な感じ。

use DBI;
use DBIx::FixtureLoader;

my $dbh = DBI->connect(...);
my $loader = DBIx::FixtureLoader->new(dbh => $dbh);
$loader->load_fixture('item.csv');
$loader->load_fixture('item-2.yaml', update => 1); # ON DUPLICATE KEY UPDATE

ORM非依存で$dbhを渡すだけで簡単にお使いいただけます。

CSV、YAML、JSONのfixtureをよしなに読み込んでくれます。ファイル名からテーブル名と フォーマットを解決してくれるゆるふわな感じになっております。

CSVはヘッダ行付きのCSV、YAMLとJSONはArray<Hash> もしくは、ActiveRecordみ たいなHash<Hash>形式のデータを受け付けます。一応Test::Fixture::DBI形式のYAMLも 受け付けるようになっております。

基本的にテストコードで使うことが前提ですが、開発環境のDBをサクッと作りたい的な 場合にも有用なんじゃないでしょうか。

ちなむと最近はGoogle Spreadsheetでテストデータ作って、それをローカルにサクッと取り込んでリポジトリ管理とかそういうことが多いです。

依存少なめで作る予定だったのですが、結局SQL::MakerとMooとか使いました。

SQL::Makerマジ便利ですね。いつの間にかPlugin::InsertOnDuplicateもある。

Mooもやっぱこれくらいは使いたいな!って感じで、個人的にもMouseとの違いとかにも 慣れてきたので、CPANモジュールには積極採用していきたい。

プロジェクトでは引き続きMouse使うけどね。

投稿者 Songmu : 00:52

2013年6月 7日

サーバーマシンのコア数に応じてworker数を調整する方法

PSGI/Plackアプリケーションの起動方法いろいろと本番環境アレコレ

便乗ポスト。最近は、上記内の「シェルスクリプトでラップする方法」で運用していることが多いです。その場合のone more tips.

appサーバーごとにマシンスペックが違う場合がたまにあって、その場合マシンごとに worker数を調整したいけど、deployの都合上サーバー起動スクリプトは同じやつを使いた いってことがあります。

そこでおすすめなのが、CPUコア数に応じてworker数を計算する方法です。

シェルスクリプトの場合、

% cat app.sh
#/bin/sh
NCPU=`getconf _NPROCESSORS_ONLN`
WORKERS=$(expr $NCPU \* 5)
exec plackup -E production -s Starlet --max-workers=$WORKERS

となります。この場合だと、コア数x5のworkerが起動するはずです。 この方法はfujiwara氏に教えてもらいました。

もちろん、CPUコア数のみにworker数を比例させるのはいささか乱暴なので、 ちゃんとチューニングしたいのであれば、サーバーごとに調整したほうが良いのは 言うまでもありません。

投稿者 Songmu : 17:31

Redis::LeaderBoardっての書いてた

RedisのSorted Setがランキング作るのとかに便利だよーってのは今や多くの人に知られるところですが、 同率問題とかがめんどくさかったりするので、その辺解決したやつを書いてみました。 というか、このへんみなさん個別に書いてると思うんですけど、色々めんどくさくなってカッと なってCPANに上げました。Synopsis丸コピですが、以下のような感じで使います。

use Redis;
use Redis::LeaderBoard;
my $redis = Redis->new;
my $lb = Redis::LeaderBoard->new(
    redis => $redis,
    key   => 'leader_board:1',
    order => 'asc', # asc/desc, desc as default
);
$lb->set_score('one' => 100');
$lb->set_score('two' =>  50');
my ($rank, $score) = $lb->get_rank_with_score('one');

# memmber object (オブジェクトが欲しい人のため)
my $member = $lb->find_member('two');
$member->score(90);
my $rank2 = $member->rank;

$rankings = $lb->rankings(offset => 0, limit 10);
  • 同率問題を考慮したランキングが取れる
  • ランキング一覧が取れる
  • 値が昇順の場合でも降順の場合でも同じようなインターフェースで扱える

と言った感じになっています。

Redis2.8で同点問題解消したやつが入るってことで、それを待とうかと思ってたん ですが、以下のissueを見ると、今提案されているパッチがそのまま取り込まれる 訳ではなく再設計みたいな流れになっているようで、もう少し時間がかかりそうだったので、 取り急ぎユニークランキングの実装が必要だったのでCPANに上げた次第。

https://github.com/antirez/redis/issues/943

ご利用下さい。

投稿者 Songmu : 11:09

2013年6月 5日

cpanfileのrequiresにURLを直接指定するのは好ましくない

cpanfileでは、requires "git:..."; のように、gitやtarballのURL等を指定すれば cpanm --installdeps . でモジュールがインストールできる「裏ワザ」があることが 結構知られているようです。しかし、これは好ましくありません。そもそも CPAN::Meta::Spec準拠ではありません。

これはあくまでcpanm側が第1引数にgitやtarballのURLなどを指定すればよしなに インストールしてくれるから現状は「偶然」そういう動きになっているだけです。

(cpanm git:...でインストールできるので、requires "git:..."; って書いてあれば 入れてくれてしまうってことです。)

あくまでインストールにcpanmを使った場合に動くってだけの限定的な話で、しかも今後は 動かなくなる可能性が高いです。

実際問題、requires $any_url; としてしまうと、モジュールのバージョン比較とか ができずに、毎回愚直にdownloadしてきてインストールし直すようになってしまうの で、これは色々嬉しくない。

じゃあどうするのか

現状、requires "Module::Name", "1.01", git => "git:...";などと書けるように する仕様が話しあわれています。

なので、そのあたりの仕様が固まるまで待ちましょう。

待ってられないなら、OrePAN2とかでcpan mirrorを立てよう

とは言えそんなに悠長に待ってられないって話もあるでしょう。実際問題、CPANに上がって ないけど、gitから入れたいってことはままあるかとおもいます。

その場合は、CPANに上がっていないモジュールをOrePAN2でcpan mirror運用しましょう。 OrePAN2の使い方はググって下さい。

OrePAN2を使うと、git URLから簡単にcpan mirror形式のディレクトリを作れるので、 それをそのままローカルで使ってもいいし、どっかで静的ファイル配信してもいい。 gitで共有してもいい。楽チンです。

cpan mirrorを使ってモジュールをインストールする方法はcpanmとcartonでそれぞれ 以下の様な感じです。なんかmirrorのみ指定だと依存モジュールとかが上手く入らない ようです。

% cpanm --mirror=http://cpan.metacpan.org/ --mirror=http://oreore/orepan/ --installdeps .
% PERL_CARTON_MIRROR=http://cpan.metacpan.org/,http://oreore/orepan/ carton install

今の職場だと、Arkをそういう感じで運用していたりします。OrePANで今年運用 始めたんだけどそしたらいきなりOrePAN2が出てきてだいぶタイミング悪かった感ある。

Arkのrepoの.travis.yml を見るとそのへん色々頑張ってるな!っていうのが伺えます。

そういや、Arkのリポジトリをいつの間にか移動させてました。しかしそろそろCPANにあげたいですね。クリスマス辺りには上がるんじゃないですかね。

投稿者 Songmu : 23:15

2013年5月27日

Cache::Redisってのを書いたら意外と大変だった件

最近Redis使うのは当たり前で、開発とかテストでmemcachedすら立てるのめんどくさくて、なるべくRedisに寄せたいと思っている。

セッションストレージもRedisで良くねって思って、ArkだとCache::Cacheなインターフェースのモジュールがあれば簡単にセッションストレージを差し替えられるようになっているので、Cache::Redisってのを書いた。

先のエントリーでも書いたとおり データに対するメタ情報をRedisの場合もたせられないので、[$data, $flags] って データを作ってそれ毎まるっとシリアライズするという乱暴な作りになっている。

なので、ストアされているデータをredis-cliとかで読もうとしても読めないのが難点。

redis-cliで読めるように値をRedisのリスト型にして持たせることも検討したけど、普通に setする場合と比べて大分遅くなってしまったのでとりあえずやめた。

シリアライザにMessagePackも指定できるようにはしてあるけどStorableと比べて全 然速度差が出なかったり、今のところutf8決め打ちだったりするのでこの辺も変わりそう。

バックエンドは色々検討した末にRedis.pmになってる。再接続のケアとかがしっかりし てるのが現状の決め手。

Redis::hiredis使おうかと思って、いくつかp-rを送って取り込んでもらったりもしたんだけど、 いかんせん(当然ながら)プリミティブな実装なので、再接続とかその辺のケアをしてくれる ラッパーモジュールを書かないと厳しそう。

ただ、やっぱRedis::hiredisは大分高速で、単純に差し替えてベンチを取った場合、 3倍近く速くなる。そうなるとCache::Memcached::Fastには及ばないまでも遜色ない感 じにはなるので、出来れば差し替えたいなーとは思っている。

現状開発では使っているけど、実サービスでは使っていません。なのでインターフェース は変わらないと思うけど裏側は結構変わると思うので、使っている人がいたら注意して下さい。

フィードバックいただけると嬉しいです。

投稿者 Songmu : 00:47

2013年5月26日

memcachedのflagsってのが何のためにあるのかっていう話

memcachedで値をセットするときに以下みたいな感じでセットするわけですが、 この<flags>ってのが何のためにあるのかいまいちよくわかってなかったわけです。

set <key> <flags> <exptime> <bytes>
<data>

で、Cache::Redis書いてた時にCache::Memcached::Fastの実装を見てたら、 あーこれ大事だわってなった。C::M::Fだと、ストアされているデータが

  • シリアライズされてるか否か
  • 圧縮されてるか否か
  • 文字列か否か

みたいな情報をこのflagsに持たせています。

C::M::Fはオブジェクトやリファレンスはシリアライズして、 単一スカラ(数値や文字列やバイナリ)はシリアライズせずに値をストアするように なってます。これはデフォルトのシリアライザであるStorableが単一スカラをシリアラ イズできないというのもありますし、単一スカラであればシリアライズしないほうが 情報が人間に読みやすいってのもありそうです。

その場合、例えばシリアライザがStorableの場合だと、memcachedから値を取得してき た値がバイナリだった場合、それはシリアライズした結果バイナリなったものなのか それとも、元からバイナリデータが突っ込まれていたのかがその値だけでは判別出来ません。 そこでflagsを見て判断するようになってるわけです。(具体的には0x1との論理積をとっている)

もう一つ例を出すと、シリアライザがJSONの場合、[1]っていうデータが入っていた として、それが配列なのか、文字列としての’[1]’なのかがそれだけだとわからないって話です。

一定サイズ以上の文字列を圧縮してストアするみたいなことも、C::M::Fはできるよう になっているので、そのへんの判別もflagsを見てやるようになっています。

値に対する最低限のメタ情報を値とは別に持たせられるようにしてあるのは 実用性を考えたいい設計だなーと思ったわけです。

Redisの場合だとそういう値とは別のメタ情報をもたせられるようにはなってないので (もちろんやりようは色々あるわけですが)、Cache::Redisを書く際にちょっと苦労した という話。その辺の話は次のエントリーで書きます。

投稿者 Songmu : 23:49

2013年5月24日

Params::TinyとHash::MultiValue、もしくは本物のTinyについて

tl;dr

  • Params::Tinyってのを書いた
  • 驚きのTiny
  • ニーズ無さそう
  • Hash::MultiValueがparamメソッド持ってれば良くね?ってなったけど、Requestクラスじゃない単なるデータコンテナクラスがそういうの持ってるの微妙なのかなー?ってなってる

本題

旧来からPerlにおいて、古くはCGI.pm、最近ではPlack::Requestまで、Requestオブジェクト 的なやつは $req->param が呼び出せることが期待されておりました。

なので、FormValidator的なモジュールはCGIが来ようがCatalyst::Requestが来ようがPlack::Request が来ようが値の検証が行えておりました。Duck typing的なあれです。

しかし逆に、単にハッシュとかからサクッとparamの生えてるオブジェクトを作るのは 大変というか、ニーズもないし逆に簡単すぎるので、誰もあんまそういうモジュールを 作ったり使ってこなかったのだと思います。一応、 Class::Paramってのはあるようです。

たまーにそういうの欲しいなーって思うことはあるんですが、だいたいテスト用の モックだかスタブだかで欲しいだけなので、CGI->newで良いかってなるわけです。

ただ、今回FormValidator::Liteにハッシュ渡したいみたいな要件があったみたいで、 じゃあなんかそういうブリッジをするやつを書いてもいいのかなーと思ったら、 驚くほどのTinyコードになった。予想はしてた。 Hash::MultiValue継承してparamメソッド追加しただけ。

こういうのって、CGI.pmぽいコンテキスト見るparamメソッドになってるのが良いのか なーと思ったので、Hash::MultiValue使っててPlack::Requestと同じような感じになってる。その辺の話は このへん

結局Yoshina::Validatorみたいなのをsoh335先生が作るってことで落ち着いた。別にこ のコード使われると思ってなかったし、使おうとも思ってなかった。

Hash::MultiValueにparamメソッド生えててもいいのかもなー、でも微妙だしそもそも ニーズ無いけど、たまに欲しいしなーとか思った。

ぼくはこう思う

コード書くよりこのエントリー書くのに何十倍も時間かかってる。

投稿者 Songmu : 22:27

2013年5月21日

Perl製のWebアプリケーションをherokuで3分で動かすの法

PSGIアプリなら簡単にherokuで動かせます。

Miyagawaさんのbuildpack(https://github.com/miyagawa/heroku-buildpack-perl)を 使います。使い方もREADMEに書いてあったけど、以下にも書きます。

アプリ側の準備

deployしたいアプリケーションのgitリポジトリ上で以下をやります。

  • cpanm --installdeps . で依存モジュールがちゃんと入るようにする(cpanfile使うのがオススメ)
  • アプリ起動用のapp.psgiを配置する

herokuにアカウントを作る

https://www.heroku.com/

toolbeltを入れる

https://toolbelt.heroku.com/

インストールが終わるとherokuコマンドが使えるようになります。

% heroku login と打ってコマンドライン上でherokuにログインします。(鍵の登録とかよしなにやってくれる)

アプリを登録する

gitリポジトリ上で以下のように打って登録します。

% heroku create appname --buildpack https://github.com/miyagawa/heroku-buildpack-perl.git

ここの、”appname”がherokuappのサブドメインとしてグローバルに登録されるので注意。どういうことかと いうと、僕が % heroku create ukigumo とかやったら、http://ukigumo.herokuapp.comがしれっと 取れてしまいました。

—buildpackの指定が面倒くさくて、「オレはperlでしかherokuに上げないぜ!」って いう強者は以下のようにすれば、defaultのbuildpackを指定できる模様。

% heroku config:set BUILDPACK_URL=https://github.com/miyagawa/heroku-buildpack-perl.git

アプリをデプロイする

先ほどのコマンドで、gitのherokuのremote repositoryが追加されています。そこにgit pushすれば commit hookが走ってアプリがデプロイされるオシャレ仕様。

% git push heroku master

enjoy!

落穂広い

動作環境は?

system perlの5.10でapp serverはStarmanです。

任意のバージョンのPerlを使えるようにするみたいな案はあって、issueは上がっています。

https://github.com/miyagawa/heroku-buildpack-perl/issues/3

上のissueでは参考例としてNodeが上がっていますが、これは他のEC2のインスタンスでコンパイル したバイナリを使うというかなり強引で頑張った作りになっているようです。

誰か頑張ってみてください。

お金かからないの?

単一アプリケーションを何のオプションも無く動かた場合は、ギリギリ無料範囲に収ま るようになっているみたいです。以下の資料が参考になりました。

http://www.slideshare.net/shunjikonishi/heroku-15670119

投稿者 Songmu : 22:59

2013年5月16日

Perlの引数の渡し方の想像上の歴史

一般的な以下の様な渡し方について。

  1. func($foo, $bar);
  2. func({foo => $foo, bar => $bar});
  3. func(foo => $foo, bar => $bar);

昔は1だったけど、2って書けるのも分かりやすくて良くね?ってなって、1でも2でも指定できるような書き方が出てくるようになった。

だんだんこの場合は1にすべき2にすべきっていう住み分けができてきて、両方の指定ができるみたいなのが減ってきた代わりに、じゃあ3の書き方で良くね?ってなってきた。今度は、2でも3でも指定できるみたいな書き方が出てくるようになった。

僕は最近は3決め打ちで良くね?って感じてきている。MouseとData::Validatorを便利に使わせてもらってるんで結果的には両方いける感じになっていることが多いけど。

値をhashに詰めるのとhashrefに詰めるのどっちが好きかって好みの問題もありそうではある。僕はタイプ数が減らせるし、なるべくhash使いたい派。逆に色々sigil使いたくないって人はなるべくhashrefに統一するのもひとつの手だとは思う。

2だと参照渡しになる分若干早くなるのかもしれないけど、逆に意図せず値が書き換わるリスクがある。事前に値をhashrefに詰めておいて、後でガバッとメソッドに渡すやり方をするとそういうバグが起きやくすくなる印象。

3だと順番も保持されるし同じキーを複数回指定するみたいなのもハンドリングしようと思えば可能なのも良い感じ。

1の使いどころも勿論あって、引数が1つか2つで明らかにそういう渡され方をするってのが客観的にも自明であれば使ってもいいと思う。その場合英語的に自然かどうかってのも大事な判断材料だと思っている。 $s->v($o, $c); みたいな。

英語に自信がないのであれば(僕もない!)、引数が少なくても迷わず3の形の名前付き引数を採用するのが安全かなーと思います。

【追記】

fujiwaraさんの体感値だと、

func($foo, $bar) -> func( foo => $foo, bar => $bar ) -> func({ foo => $foo, bar => $bar })

の順で見かけるようになったとのことです。確かに、perl4の時代はHashRefとかなかったので、Hash渡ししかできません。実際、歴史あるCGIモジュールはHash渡しになってます。

https://metacpan.org/module/CGI#SYNOPSIS

  • Catalist, DBIC辺りから、HashRef渡しをよく見るようになった
  • 最初はhash直で、その後hashref渡しが流行って でもぜんぶhashrefって微妙じゃね、ってなって揺り戻しが来てる感じかなあ

というお話で、そっちの方が正しい感じがします!

投稿者 Songmu : 02:12

2013年5月14日

CSRFDefender的なやつでコンテンツフィルタはしないほうがいいんじゃないかという話

本日の組長のお話。

Ark::Plugin::CSRFDfenderに機能追加したりいろいろバグっていたりしたのに手を入れていたのだが、それに対して組長に意見を頂いた話。結論はタイトルの通り。

CSRF対策をフレームワーク側で入れるのは良いと思うが、フィルタしてformに自動的にhiddenを埋め込むのはあんまよろしくないんじゃないかという話です。

CSRFDefender的なやつには以下のような機能があるが、それぞれに関して述べる。

  • POST, PUT, DELETE時に自動でtokenチェックしてエラー画面強制表示
  • 自動的にコンテンツフィルタしてform要素にhiddenを埋め込む

POST, PUT, DELETE時に自動でtokenチェックしてエラー画面強制表示

OK。安全側に倒している。

自動的にコンテンツフィルタしてform要素にhiddenを埋め込む

あまり好ましくない。厳密に安全側に倒すのが難しい。

例えば、formのaction要素に外部URLが入っていた場合に簡単にtokenが外部サイトに漏洩してしまう危険性がある。(例えば検索窓など)

  • methodがGETのフォームはフレームワーク側でフィルタしない
  • 外部URLに直接POST指定とかするな!

という話ではあるが、意図しない使い方をされることで逆に危険になるような設計は好ましくない。

form.actionはJSで上書きもできてしまうので、フィルタ処理側でそのformがhiddenを埋め込むべきか否かを厳密に判断するのは実質不可能に近い。

どうするのが良いのか?

自動tokenチェックをしてCSRFエラー画面で「あなたの予想に反して、このページが見えているでしょうか?」的なことと対応ガイドラインが表示されるようになっていれば、hidden漏れに開発時に気づける。ので、開発者が手でhiddenを都度埋め込めば良い。そのためのヘルパー関数をpluginが準備しておくのも良いと思います。

コンテンツフィルタ機能は便利っちゃあ便利なので、リスクを承知した上で、その機能 をオンできるようになっているのは有りだとは思いますが、デフォルトでその挙動になってるのは危ないんじゃでしょうか。

Ark::Plugin::CSRFDefenderは非互換にはなりますがその方向で修正する予定です。

余談ですが、csrf_tokenはsession_idで十分だという話もあったりますが、上記のように漏洩リスクがあるので、session_idを元にハッシュ化したものをtokenにしたりする方が良いのかなとかなんとなく思いました。

【追記】tokuhiromにそもそも漏れても問題ないようなtokenを使ったほうが良いんじゃないかという指摘をもらいました。それならば、自動的にコンテンツフィルタを入れていて、tokenが漏れたとしても大きな問題にならないので。こういう機能において、漏れては困るようなtokenを埋める処理を入れるのが筋悪って話ですね。

結論

めんどうくさいWebセキュリティ

投稿者 Songmu : 18:43

2013年5月12日

最近のModule::InstallでTravisるときのポイント 2013年5月度版

tl;dr

  1. Module::Install::CPANfile を使う
  2. cpanfileのon ‘develop’セクションにModule::Install関連の依存を記述する
  3. .travis.ymlにinstall: cpanm --with-develop --installdeps --notest .を書く

あらすじ

最近のModule::InstallでTravisるときの注意ポイント ってのがあるが、折角DSLなのに、BEGINに色々書くのは悲しかったが、今はcpanfileがあるので、Module::Install::CPANfileで解決できるよって話。

Module::Install::CPANfile を使う

依存関係をcpanfileに記述します。Makefile.PLからそのままコピペしてきて良いでしょう。featureとかはちょっと書き方が違ったりします。そもそもfeatureとかの扱いがどうなってるのかちょっと良くわからなかった。

Makefile.PLからは依存関係の記述を削除して、その代わりに

cpanfile;

と書きます。

cpanfileのon ‘develop’セクションにModule::Install関連の依存を記述する

cpanfileに以下のような記述を追加します。

on 'develop' => sub {
    requires 'Module::Install';
    requires 'Module::Install::CPANfile';
    requires 'Module::Install::AuthorTests';
    requires 'Module::Install::Repository';
};

.travis.ymlにinstall: cpanm --with-develop --installdeps --notest .を書く

cpanmのオプションに—with-developを渡すと、cpanfileのon ‘develop’のモジュールもインストールしてくれます。travisのデフォルトだと—with-developはついていないので、.travis.ymlで設定を上書きしてやればok。

最小の.travis.ymlは以下の通り。

language: "perl"
install: cpanm --with-develop --installdeps --notest .

これでok。Happy travis life!

落穂拾い

なんでon configureじゃなくてon developなの?

M::Iはinc/に同梱するものなので、ユーザーにon configureでインストールさせるのはおかしいですねって話です。

あと、on configureだと—installdepsで入れてくれなかったりしたのと、—with-configureみたいなオプションも無いってのもある。(この辺深く追ってない)

元のハックと比べるとgit repoからモジュールをインストールしようとした時のエラーメッセージがわかりづらくなるんだけど?

仕方ないので諦めましょう。

Module::Install をつかっているモジュールを git からインストールできるようにするためのパッチ」、みたいな話もあったみたいですが、ちょっとその後どういう決着になったのかちょっとよくわかってない。

結論

cpanfile、cpanm周りはまだまだ流動的なのでベタープラクティスは変動していくと思うし、今回の記事も怪しい部分がある気がしているので、フィードバックあると嬉しいです。

投稿者 Songmu : 16:58

MySQLのsql-modeで一番厳しいやつはTRADITIONAL

このへんに書いてありました。

http://dev.mysql.com/doc/refman/5.5/en/server-sql-mode.html#sqlmode_traditional

なので、これを設定しておけば良いんじゃないですか。STRICT_TRANS_TABLESと大きく違うのは、日付周りをより厳密に処理してくれるようになる点ですね。

「えっDATETIME型使うの?」とか言われることもあるんですけど、MySQL shellで読みやすいし、partitioningしたときにpruningも効くしいいじゃないですかね。INT使うのとかだいぶバッドノウハウ感あるし。とか思ったら最近はTIMESTAMPでもちゃんとpruning効くっぽくて泣いてる。

‘TRADITONAL’なのに一番厳しいのがMySQLのゆるふわ感を醸し出していて良いですね。

投稿者 Songmu : 03:44

DBD::mysqlでmysql_enable_utf8しつつutf8mb4使いたいとき

今のところの結論として、接続時に

SET NAMES utf8mb4;

するしか無いんじゃないかなーという感じがしている。SET NAMES使うのかよ!ってdisられそうで怖いです。

DBICやTengの場合はon_connect_do、生DBIやSunnyの場合はCallbacksで指定できます。

なんか、mysql_enable_utf8していると、DBD::mysqlがMYSQL_SET_CHARSET_NAMEでutf8に決め打ってしまうので、さらにSET NAMES utf8mb4して上書きしてやらないといけないという感じ。ソースとしては以下の辺り。

https://github.com/CaptTofu/DBD-mysql/blob/4_022/dbdimp.c#L1803-L1816

DBD::mysql側でなんか対応して欲しい気もするけどどうするのが綺麗なんでしょうかね。

ちなみに、あんま深追いしてないけど、SET CHARACTER SET utf8mb4 だとダメでした。

mysql_enable_utf8は未だexperimentalだけど皆使ってますよね。いちいちデータを全部文字列化するとかだいぶタルくてやってられないし絶対どこかで漏れて文字化けとか起きるし。

投稿者 Songmu : 03:00

pullreqを別ブランチにマージしたいとかsquash mergeしたいとき

以下のようにして、git fetch-pullsを登録しておけばpullreqの内容を手元に持ってこれるので、手元でmergeしてpushすれば良い。

何らかの形でmergeさればpullreqも自動的に閉じるようになっています。(場合によってはcontributorにpullreqしてもらった人が表示されなくて悲しい思いをしたりはする)

pullreqを別ブランチにマージしたいケースとしては、例えば、failするテストケースだけをpullreqしてもらったりした場合に、それをmasterにcommitしたくないよね、的なやつです。

squash mergeとかも気にする人に対して、pullreq時に「commitまとめてくれ」とか言われたら「そっちでsquash mergeしてくれ」って言えるのが良いと思います。

なので、勿論限度はありますが、汚いcommit logのbranchからpullreq送っても良いし、コケるだけのテストケースをpullreqするのもいいんじゃねーのって話です。少なくとも僕はwelcomeです。

投稿者 Songmu : 02:22

3分でpull request

サクッとpull requestを送るために。

tl;dr

  • % git config —global push.default simple しておく
  • ブラウザでfork押して、そのリポジトリをcloneする
  • % git checkout -b feature/hogehoge ってやってbranch作る
  • 変更してコミットする
  • % git push —set-upstream origin feature/hogehoge として修正をpushする
  • ブラウザからpull request

あらすじ

ikachanを導入しようとした所、AnySanがssl未対応だったのでpullreq送ろうとしたらすでに同僚のmix3先生がpullreqしていて、mix3++であった。しかし、masterブランチからpullreq送るのは良くないよねってことで練習のためにtopicブランチを切ってpullreqを送り直してもらうなどした。早く取り込まれるといいね。

以下説明。

% git config —global push.default simple

本題とはあまり関係ないんですけど、この設定をしておくと % git push したときに分かりづらい挙動にならないので設定しておくと良いと思います。Git2.0からはこの動きがdefaultになるようです。

ブラウザでforkしてそのリポジトリをcloneする

そのまんまですね。以前forkしていてそのリポジトリが古くなってた場合は追随する方法もありますが、わからない場合は消してforkし直しましょう。

% git checkout -b feature/hogehoge ってやってbranch作る

masterで作業せずにすぐブランチを切ります。branch名は、機能追加はfeature/、ドキュメンテーションはdoc/、バグフィクスはfix/とかつけておくとわかりやすくて良いんじゃないかと最近思っております。

変更してコミットする

なるべく1commitにまとめましょう。少なくとも、作業の試行錯誤が見えるような汚いcommit logを残さないように。

コミットメッセージはなるべく英語で書きましょう。

% git push origin feature/hogehoge として修正をpushする

ここでおもむろに % git push とかすると以下の様なエラーが出ます。

[Songmu]$ git push
fatal: The current branch feature/hogehoge has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/hogehoge

% git push —set-upstream origin feature/hogehoge するといいよ!て書いてあるのでありがたくコピペして実行するとちゃんとリモートブランチが作られます。

ブラウザからpull request

そのまんま。これもまたなるべく英語でメッセージを書きましょう。相手が日本人でも、なるべく公開の場では英語でやり取りして、IRCとかで日本語で相談するのがいいんじゃないかなーと最近思います。

あとはmergeされるのを待ちましょう。残念ながらrejectされてしまうこともあるかもしれませんがめげないで頑張りましょう。

落穂拾い

pullreq後、作者から修正要望がついた場合は?

修正内容をブランチにcommitしてpushすれば大丈夫です。もう、ブランチからオプション無しのgit pushするだけでremoteに反映されるようになっています。

pullreqがmergeされるなり決着がついた場合は?

今後あまり継続的にpullreqを送らないのであれば、forkしたリポジトリを消してしまっても良いでしょう。しばらくたってpullreqを送りたくなったらまたforkすれば良いのです。

今後もforkしたリポジトリを本体に追随させていきたい場合は?

fork元のオリジナルのリポジトリを登録する。

% git remote add upstream git://github.com/...

masterブランチで定期的に追随して自分のリモートにもpushする。

% git checkout master
% git pull upstream master
% git push
複数の機能や項目をpullreqしたい場合は?

個別にブランチを切って、別々にpullreqを送りましょう。

pull requestが取り込まれる前にその機能を使いたい場合は?

複数pullreqを送っていてその両方の機能を手元では使いたいとかそういう場合は、oreoreブランチを作ってそこにbranchを両方マージして使ったりしています。

投稿者 Songmu : 01:47

2013年5月 4日

Config::PLというのを書きました

https://metacpan.org/module/Config::PL

.plファイルを設定ファイルとして使う時のユーティリティです。以下の様な感じで使えます。

use Config::PL;
my $config = config_do 'config.pl';

do 'config.pl'のハマりどころや不便な点を解消しています。doの問題点は具体的には以下の様な点。

  1. config.plにsyntax errorがあってもエラーにならない
  2. 絶対パスで指定しないと危ない。doはモジュール読み込みと同じルールでファイルを探しに行くので、@INCを探しにいってしまう。config.plが@INCに置かれているとそっちが優先的に呼ばれる(!)
  3. config.plから他のファイルを相対パスで読み込めない

これらに対してConfig::PLは、

  1. syntax errorやhashrefを返していない場合にエラーになる
  2. @INCをlocalizeして、cwdとそのファイル自身がおいてあるディレクトリしか探さない
  3. そのファイル自身が置いてあるディレクトリをlocalizeした@INCに含むので、相対パスで読み込み可能

というようになっています。

設定ファイルが置いてあるディレクトリで、同じディレクトリにある他のファイルを環境変数に応じて読み込みたい時なんかに便利で、

以下の様な構成になっている時に、

[songmu@localhost]$ ls config
common.pl  development.pl  production.pl  test.pl

例えばこのような感じで環境変数に応じた設定の切り替えが可能です。

# config/common.pl
use Config::PL;
config_do "$ENV{PLACK_ENV}.pl";

以下のように書くよりわかりやすくていいんじゃないかと思います。

use File::Spec;
use File::Basename;
do File::Spec->catfile(File::Basename::dirname(__FILE__), "$EVN{PLACK_ENV}.pl")

環境変数に応じた設定に切り替えに関しては@cho45氏のConfig::ENVが非常に便利ですが、Config::ENVの作法を覚えないといけなかったりするので、もう少し通常の作法に近い解決方法をサポートしようと思い、書いてみました。普段使っているArkが、config(?:_local)?.pl 決め打ちだってのもあります。

同様のモジュールとして、これもまた@cho45氏のConfig::Doってのがありましたが、これはconfig.plにエラーがあった場合ににエラー終了することを保証するもので、Config::PLのように@INCをlocalizeするようなお節介をしないところが異なります。

依存もないので簡単にお使いいただけます。お試しください。

投稿者 Songmu : 11:54

2013年4月16日

Perl QA Hackathon 2013 Satellite at Tokyoに行ってきた話

なんかやることとかもよくわかってなかったんですが、面白そうなので行ってきた。テスト関連とかそういう話だったので、とりあえずUkigumoでもいじってようかなーと。

出した成果?はUkigumo::Client をMinilla化して、Notify::Growlを追加してCPANに上 げたくらいです。Minillaだいぶ便利。minil migrateしたら挙動がよくわからなくて tokuhiromに色々直接教えてもらえたので良かった。

あとはherokでのperlのバージョン指定みたいなissue が上がってたので、ちょっとやってみようかと思いつつ調べて、herokuでUkigumo-server動かしたりしてた。

heroku-buildpack-perlは今はmiyagawaさんのやつでちゃんと動く模様。

http://ukigumo.herokuapp.com/

割と簡単に動いたんで、herokuでの動かし方のdocument追加したりした。

インスタンス1つだけだったら、お金かからないらしいんで、とりあえず立てたままに してある。

本題のherokuでのperlのバージョン指定に関しては、nodeの実装 見てみたら割とめんどくさい感じだったのでそっ閉じ。

僕自身はそんな成果出さなかったけど、tagomorisさんにFluent::AgentLiteをCPANに上 げてほしいって言ったらCPANizeしてくれたり、plenvとかcartonの話とかの現状の話を miyagawaさんとかtokuhiromとできたりしてだいぶ有意義だった。

投稿者 Songmu : 00:28

2013年4月10日

パスワードはサーバー側で生成したほうが良いんじゃないかという話

いつまで文字列ベースのパスワードを使うんだって話は置いておいて、Webサービスのパスワードはもはや、人間には覚え切れない領域に達しているわけです。

  • サービス毎に異なるパスワード
  • 大小英数数字記号混じり12文字以上

みたいなのは必須で、それに加えて意味があるかどうかは甚だ不明ですが、定期的に変更必須みたいなポリシーがあるところもありますね。

言ってしまえば、もはや人間が覚えられる程度の強度のパスワードでは弱すぎるわけで、そうなるともう否応なしにパスワード管理ツールを使うしかありません。

そのような「パスワードは覚えきれない」という前提に立つと「もはや覚えやすいパスワードを使う必要がないという」逆説が生まれます。

となると、もう、パスワードはサービス側がランダムな文字列を発行してしまって、それを強制的に使わせる形で良いんじゃないかとふと思いました。以下の様な具合です。

  1. 大小半角英数数字記号混じり20文字程度の(サービス提供側が十分な強度だと認識できる)パスワードを生成
  2. ハッシュ化したものをDBに格納
  3. パスワードを画面に表示してユーザーに使わせる

サーバー側のDBへの保存方法等は従来と同様です。

これには以下の様なメリットがあります。

  • 覚えやすい強度の弱いパスワードを使われる危険性がない
  • 他のサービスで同じパスワードを使われる可能性が低い (発行したパスワードをその後別サービスで使われてしまう可能性はある)
  • パスワード定期変更ポリシーも適用させやすい

ユーザー登録や利用の敷居を下げたいカジュアルなWebサービスでは使いたくない手法でしょうが、業務アプリや管理ツール、Saas等では一考の余地があるのではないでしょうか。

ユーザー登録のフローなんかは以下のように考えてみました。

  1. ユーザー登録画面(メールアドレス必須)
  2. ユーザー登録確認メール送信確認画面
    ここで「秘密の質問」を出して、答えを入力してもらう
  3. サーバーでワンタイムURLを発行してメール送信。URLの期限はなるべく短く(30分程度)
  4. ワンタイムURLにアクセスすると、先ほどの「秘密の質問」が表示される。それに再度答えてもらう
  5. 秘密の質問の解答が正しければ、パスワード生成ボタンが表示される。
    生成前に「覗かれていないか周りを確認すること」等を注意書き
  6. パスワード生成ボタンを押すとパスワードが画面に表示される。再表示は出来ないので、必ず何処かにコピーするなりパスワード管理ツールに登録することを促す

秘密の質問はあくまでも、パスワードを発行するための一時パスワードに過ぎないので、強度はそれほど強くある必要はありません。「秘密の質問」形式をとっているのは「一時パスワード」という形で登録させてしまうと、それを「サイトログインパスワード」だと勘違いしてしまうユーザーが出てくる可能性があるので「秘密の質問」という形にしている次第です。

パスワード変更なども、自分の好きなパスワードを決められるのではなく「再生成」することになります。パスワードリセットなんかは登録とほとんど同じフローになるでしょう。

サーバーにパスワード生成させるのはどうなの?って話はあるかと思いますが、平文をどこにも保存しない作りにすれば良いだけなので問題ないかと思います。パスワードを平文保存してるかどうかなんてのはどちらにしたって信頼ベースなので。実際問題として今でも世の中の半数以上のサービスはパスワードを平文保存してると僕は思ってます。

カジュアルなWebサービスでいきなりそのフローを辿らせるのは敷居が上がるので採用しづらいとは思いますが、この方向性を指示する人に対してはオプションでこの登録方法を選んでもらうのはアリなんじゃないかと思います。

はてなさんとかが、そういう登録方法をオプション選択させるのはユーザー層のリテラシー的にもアリなのではないかと。そういうところからの草の根活動。

投稿者 Songmu : 01:27

2013年3月23日

「仕事に対する愛と情熱とプライド」若しくは新卒に向けたスピリチュアルな話

そろそろ新卒研修とかどうしようかとかで、エンジニア陣でわたわたしたりしています。「Songmu先生にはスピリチュアルな話をしてもらわないといけませんね」みたいなことを言われてなんかスピリチュアルキャラとして定着しているのもどうかと思います。

去年も「『仕事に対する愛と情熱とプライド』ってお題でソーシャルゲームチームの新卒向けに話してください」とか研修担当の人に言われて、なんでそんな熱いキャラとして認知されてるか謎だったんだけど、それで30分くらい話しました。

それが結構評判良かったみたいで、直接はあまり言われなかったんだけど「研修の時の先輩の話の中で一番印象に残っている」って言ってくれている人が多いって話を2年目の人から又聞きで知って嬉しく思っていました。

とか思っていたら、hisaichi5518の人は「なんかすごくいい話してた覚えはあるんですけど内容全く覚えてません」とかsoh335の人は「話したことすら覚えていない」とか言っていて、まあそんなもんですよね、っていう。

とはいえ、今年何か話すにしてもあまり去年と同じ事は話したくないなってのがあって、幸い去年の発表資料が残っていたのでそれを元にどんなことを話していたかを思い出しながら差し支えない範囲で書き起こしてみることにしました。

ちなみに以下の内容は僕個人が一年前に感じていたことであって、所属している会社の見解とは一切関係ないということを念のため申し上げておきます。


Songmuです。現在とある野球ゲームのリードエンジニアと最近出たばかりのゲームのインフラ周りのチューニングとかをやっています。

リードエンジニアって何をしているかというと、開発だけじゃなくて、スケジュール管理とか、ディレクションとかプロジェクトの動き全体を取り仕切るようなことをしています。

今のプロジェクトチームは売り上げ的に成果を上げているだけじゃなくて、社内のソーシャルゲームの中で、一番バグ発生率が少ないし、CS関連のチケットを0に保つことにプライドをかけています。ソースも一番モダンで綺麗だと自負しています。

現在、中途に入って2年目になったくらいです。Perlに関してはゲーム事業部では一番詳しいと思います。Perlが好きで今の会社に入ったようなもんです。

ただ、Perlに詳しいってのは決して技術力が一番あるってわけではないです。この辺りは非エンジニアにはわかりづらいかもしれません。他の事業部にはもっとPerlに詳しい人もいます。更に言うとPerlに関してだったら、そこにいる新卒のsoh335さんとかhisaichi5518くんの方が詳しかったりしますね。

野球が好きで、中国語が話せます。ロードレーサー2台とボウリングのマイボールを2個持ってます。これはどうでも良いですね。


愛と情熱とプライドっていうお題だけど、自分のことはたいしたことないと思っているからあんまプライドとかは無いかも知れないです。エンジニアとしては底辺だと思っています。

仕事に対してはドライなつもりです。土日とか働くことを薦めたくないし、そうなってしまっているのは、仕組みとしてイケてないからであってそういう働き方をしていることにたいして自己満足に陥ってはいけない。

個人の馬力で何とかしてしまうのはイケてないし、長く働いている人は無能だと思っています。僕自身も。

非日常に高揚感を感じるのはオナニーでしか無いし、成功体験としてしまうのは危険。徹夜してやりきったみたいなのに満足するんじゃなくて恥じるべき。

とは言え、僕自身は夜遅くまでコード書いたりするのは楽しかったりするけど、そういう状況を俯瞰的に捉えられた方が良い。

行列のできるラーメン屋に何十分も並ぶことは馬鹿馬鹿しいけど楽しくもあったりするみたいなようなこと。

「今年もきっと戦後最大の危機です」って社長が言ってたことがあって、これはすごく面白い言葉だなーと。決して揶揄の文脈じゃなくて、それはもうそういうもんで、そう捉えてそれに乗っかっちゃったほうが面白いんじゃないかって話。

そういうことを自覚しながらバランスをとることが大事だと思う。

仕事ってのは試合のようなものだけど、試合だけじゃ強くなれないと僕はスポーツとかやってきた経験から思ってるから、長時間仕事するのはやっぱ良くないと思っています。


今の会社の文化と仕事に関して去年強く感じたのは

  • 何をするかより誰とするか
  • のっかる文化

の2点。

入社式の時に代表の一人がわけわかんない英語か何かを発話してたけど実は良いこと言ってて、あれは岡本太郎の言葉で

情熱があって何かを始める人なんて少なくて、普通は何気なく始めたことに無意識のうちにのめり込んで、そこから情熱が生まれる

ということです。これは本当にそうだなーと思って、僕自身一年間働いてきて、周りは本当に良いやつらばかりで一緒に働くのがすごく楽しかった。入社した時はソーシャルゲームとか好きでも嫌いでもなかったけど、今は情熱を持って取り組んでいます。

入社してしばらくしてから野球ゲームの新規プロジェクトチームにジョインできたのがすごく運が良くて、それによって僕自身がすごく野球が好きだったってことを思い出すことができて、開発しているゲームに対して思い入れを持てたし世界観に入り込むことができました

あと、プロフェッショナルなエンジニアとか、凄腕のデザイナーとかがいるすごくいいチームで開発ができた。

前の会社までは僕はデザイナーと近くで仕事をしてなかったけど、今の職場は美大出身とかの本気のデザイナと机を合わせて仕事できる。これはエンジニアにとって、モノつくりをする上でとてもよい環境だと感じています。

そのチーム中で僕自身も必要とされたから、自分のプロダクトに誇りと責任を持たざるをえないし、その期待に応えることがモチベーションにもなっています。

そのプロジェクトが結果として成果を上げることができていることもあって、すごく良い成功体験をさせてもらえたと思っています。

今年から引き継いでリードエンジニアをやってるけど、その位置に居るのは僕自身の意識が高いとかじゃなくて、いろいろな意味で運が良かった。運が良かったけど、それは状況に素直に乗っかっていったから掴み取れたものではあるかなとは思っています。

今運営している野球ゲームは、ユーザー同士でチームを組んで試合が行われたりするんだけど、こちら側が思いもよらないようなドラマチックな展開が生まれたりします。強いのになかなか優勝できない悲劇のチームとかが、念願かなって優勝したりすると運営側も盛り上がったりします。普通に野球の試合を見ている感覚ですね。

ユーザーと一緒にゲームの世界を創り上げている感覚があって、それは経営理念の「つくる人を増やす」にもつながっていると手応えを感じています。


今ソーシャルゲームに対しては色々ネガティブなことが言われていて、僕自身も抵抗が全くなかったといえば嘘になります。ただそこに何故飛び込んで来ることができたかと言うとこれまでの経歴が無縁ではありません。

僕はかなりダメな人生を送ってきてて、大学はSFCだったけどコンピュータとかあまりやらずに中国語ばっかやってました。一応機械翻訳の研究とかもやってる体でしたが基本適当でしたね。卒論も書かないで卒業しました。

僕が就職活動してた時期は、俗に言う就職氷河期だったんだけど、SFCの学生ならSEには比較的なりやすかったようです。実際に受けてないからわからないんですけど。

でも大学でコンピュータをあまりやってなかったし、周りが(僕よりもコンピュータを扱えない人でさえも)どんどんSEになる中、僕は尚更安易にSEとかになりたくないみたいな屈折が生まれてしまって、出版社志望を気取ってたんだけど、結局どこも内定取れずに就活に失敗しました。大分厨二ですね。

それで、大学卒業後に中国に行ってそこでITベンチャーの立ち上げ手伝ったりとかしてました。結局ITかよって話です。で色々あって、給与未払いみたいなことが起こりそうになって、お金が底を尽きて日本に帰ってこざるを得なくなった。突き詰めると僕自身の実力不足です。

それでお金がないからどうしよう、でももうITの仕事はコリゴリだとか思って、結果として見つけたのが語学学校。駅前留学とかそういうやつです。

中国語のスクールマネージャの営業職に応募したんだけど、連絡が来ないのでダメ元でこっちから電話したら英語と中国語のオンライン/電話レッスンの営業担当兼システム担当全般みたいなポジションで雇ってもらえることになった。結局ITから別れられません。

後から聞いたら応募フォームの情報チラ見で落とされてたみたいなんだけど、電話した時に担当の人が再度情報を見なおしたら以前IT系の仕事をしていたことが目に止まって、そういうポジションの人がちょうど足りなかったから採用してもらえたようです。

そんな感じで、わらにもすがる気持ちで入った語学学校業界なんだけど、入った当初は業界を馬鹿にしていた部分がありました。馬鹿なOLとかリーマンを喰いものにする業界だろ?的な。

ところが実際は教務の人とかは圧倒されるくらい情熱を持っていて「日本人が英語・中国語を話せるようにするにはどうすればいいか」という命題に真剣に取り組んでいる。営業の人も本気でお客様の事を考えられる人が結果を残すことが多かったです。

「ネイティブ講師つけておけば大丈夫だろ」的な適当なことをやっている学校もありますが、僕が勤めていたところはそうではありませんでした。

口先ばかり上手い営業の人は新規契約率は高めだったとしても、更新率が低くなる。ちゃんと契約後にお客様の事を考えてケアできる人は更新率が高くなります。実際、新規契約率は水物だけど、更新率は努力次第で大きく上げられるから、そっちのほうが成果につながるんですよ。

入る前は全然未知で偏見すら持ってた業界だったけど、入ってみるとそういう風に実は得るものが大きかった。その時の体験があるから、何かと言われてるけどソーシャルゲーム業界に入っても得るものはきっとあるだろうなと思うことができました。

ちょうどその頃は、とある語学学校が色々消費者問題とかを起こして経営破綻したとかそういう問題で騒がれた時期でもあって、世間の語学学校業界に対するネガティブな印象がすごく強かった。なので今のソーシャルゲーム業界に似ているなーってのも感じたので逆にソーシャルゲーム面白そうだなと思った部分もあります。

その事件もあったのでお客様を搾取するモデルは結局長続きしないなってのを確信しました。誠実に運営することが最終的に成果につながるっていう僕自身のポリシーを、単なるキレイ事以上のレベルでこの頃から信じられるようになった。僕自身嘘をつくことが苦手なのでそう信じて動けたほうが気分が良いってのもあります。今もそう思いながらゲームを運営しています。


それでなんで今エンジニアやってるんだ?って話になります。これまでの話の通り、避けていたつもりのITが何故かずっと付いて回ってきてたんだけど、それでも「ITはあくまで仕事の手段でしかない」とか厨二臭いことを思っていたわけです。ただ、それが段々楽しくなってきて「あ、僕Web好きだ」って認めた瞬間に僕の中でブレークスルーがありました。すごく視界がひらけて自分のやりたいこととかが明確になった。

それで転職してSIer勤務を経て今の会社にいます。後から思えば、ツンデレじゃなくて素直にさっさと「好きだ」って認めちゃったほうが良かったなと思います。


仕事に対する愛の話なんですけど、僕は最後は「愛」だと思っています。

これは人それぞれスタイルがあると思うけど、僕はこれまであんま先のことは考えずに、妻に対する愛だとか自転車に対する愛だとかプログラムに対する愛だとかPerlに対する愛だとかプロジェクトに対する愛だとか、そういうものに突き動かされて生きてきたので、それが一番パフォーマンスを発揮する方法だと感じています。

ただ「仕事を愛しましょう」とかアホくさいことを言うつもりはないです。「愛国心を持て」という言葉みたいに滑稽ですからね。ちなみに僕は日本好きですよ。

束縛しようとしたって束縛できないし、束縛しようとするのは自分に自信が無い証でしかない。愛せる人になるのが大事だと思います。自分から愛するものにコミットするってだけで、愛させるとか愛してもらうとかどうでも良いのです。

その愛が単なる身勝手に終わらないためには「好きな事しかしない覚悟」を持つことが大事かなーと思っています。

よく「自分事化」とか「全部自分の責任」とかそういう言葉が社内では出るんですけど、間違ってはいないんだけどちょっと息苦しい感じがして嫌だなーと思う部分があって、僕としては「好きな事しかしない覚悟を持つ」と思っていた方が気分が良いなーと思っています。

よっぽどまともな判断力を奪われた悲惨な状態とかじゃない限り、自分の人生の選択に対して最終的に判断を下しているのは自分なんだから、それは結局アナタが選んだアナタが好きなことでしょってことです。

今僕はエンジニアとして働けていて、自分の好きなコトやっているのですごく充実しています。


僕は苦行が嫌いで、そういう自分を傷つけて自己満足みたいなのは低レベルなオナニーでしかない。仕事も一緒だと思っています。

僕はほぼ毎年ハーフマラソンに出てるんですけど、ハーフマラソンは楽しく走れるから出てるだけで、苦しみたいから出てるわけではないんですね。何の努力もせずにマラソンを走って、苦しんだ自分を褒めてやりたいみたいな人はまあ低レベルです。

それでも練習不足の時はハーフマラソンが苦行になっちゃうこともあって、それは結果としては色々反省するわけですけど、やっぱ良いことじゃないなーと思います。つらい思いはしたくないんで。

フルマラソンは苦行だから出ないようにしてるんですけど、フルマラソンが苦行じゃなくなったら自分としてはステップアップかもしれません。


仕事に対するプライドなんですけど「自分にしかできないことを見つけてそこにプライドを持つこと」が大事なんじゃないかと思っています。

そうは言ったものの「自分にしかできないこと」なんてそうそう見つかるもんじゃないと思ってしまうかもしれません。

でもそんなに難しくない方法があります。それは「レッテルに乗っかる」ことです。

僕の場合は例えば、コードが綺麗とかバグが少ないとかそういう「レッテル」を貼られるとそれに対してプライドを持つようになるし、バグをすぐ潰すようになる。

あとは、僕は今教育が得意とか、ドキュメンテーションが得意とかそういう「レッテル」を貼られていて、ホントは全然そんなこと無いんですけど、それに乗っかって、社内フレームワークのドキュメントを整備しなおしたりしました。

ただ、結局自分の評価ってのは他者が決めるってのが世の中の常だし、そういう「レッテル」が貼られるってのはどこかしらそういう側面なり素養なりがあるんだろうから、それに乗っかっちゃって強化してしまうのは結構有効なんじゃないかと思います。


エンジニアじゃない人も多いのでエンジニアって人種に少し触れておこうと思うんですけど、エンジニアは技術そのものが好きで、目的と手段が入れ替わってる人が結構多いかなと思います。技術に理解のない人は信用しない職人気質な人も多いですね。

エンジニアに限らないかも知れないんですけど、仕事だけじゃスキルが向上しない部分があるので、エンジニアの人は仕事以外でちゃんと勉強するとか、社外の人と交流を持つことも大事です。

この会社はWebクリエーターの会社ということになってるので、エンジニアに限らずHTTPは喋れないといけないと思います。喋るって言うと難しそうに思えるかもしれないけど、単にメッセージのやり取りの方法なのでどういうことをやっているかって感覚は持っておいたほうが良いと思います。

僕個人としては、プログラミングは今後必須スキルになってくると思うし、学校とかでも教えたほうが良いと思ってます。英語よりも大事なんじゃないかな。

まあそんな感じで気難しい人も多いですが、よろしくお付き合いください。


最後に感謝することについて話したいんですけど、僕は基本的に「自分にできないことが出来る人はすごい人」だと思っていて尊敬と感謝をしています。

なので、チームのメンバーとかもそうなんですけど、CSとか管理分門とかインフラの人たちには本当に感謝しています。

特にCSとか管理分門とかインフラの人達とかは僕等のクリエイターとしてのパフォーマンスを上げる仕事をしてくれているわけで、感謝してもしきれないですね。

普段は目につかないものとか見えないものに対する想像力ってのはクリエイターにとってすごく大事だと思うんですけど、CSとか管理分門とかインフラとか普段あまり接点のない人達がどれだけのものを僕たちに与えてくれているのかよくよく想像してみると良いと思います。

ちゃんと感謝を伝えると良好な信頼関係を築くことができるし、信頼関係が築けていると建設的に意見をぶつけあって喧嘩することも可能になります。

ゲーム運営をしていると、CSチームと関わることが多くなるんですけど、僕はお問い合わせの最前面にいて対応してくださるCSの皆さんにはものすごく感謝しているし、CSの声はユーザーの声だと思っています。CSからくるチケットとかを丁寧に迅速に返すことがユーザーの満足度に繋がって、結果としてお金を使ってもらえる、ゲーム運営を長く続けられると僕は信じています。

もちろんCSの負担を減らすためにも、とにかく不具合は出さないことも重要です。

CSチケットを後回しにしたりとか、CSに共有せずにイベント始めたりとかそういうことを続けていると、CSチームと関係性が悪くなってしまいます。元々CSは常にユーザーさんとやり取りをしているので、どうしてもユーザーさん側の熱量に押されて感情移入をしてしまいがちな部分があります。

なので、CSと信頼関係が築けていないと、CSにも開発チームが悪者扱いされて四面楚歌になってつらくなりますし、運営にも支障をきたします。

逆にCSチームと関係性が築けていると、些細なバクの兆候とかも早めに伝えてくれるようになったりします。またCSがユーザー側に感情移入しすぎている時でも、信頼関係さえあれば、開発側の熱量をぶつけても建設的な意見交換ができ、開発側の意見も汲み取ってもらいやすくなります。

なので、感謝は人のためならずな部分もありますし、ちゃんと周りに感謝を伝えながら仕事をしていきましょう。

投稿者 Songmu : 23:13

2013年3月18日

carton execでTest::mysqldが起動できなくて泣いた

% carton exec -Ilib — prove -lv t/mysqld.t
*** mysqlinstalldb failed ***
Can’t locate lib/core/only.pm in @INC (…

結論から言うと、carton execしたperlと別バージョンのperlがどこかで使われて、 そのPerlにlocal::lib(lib::core::only)が入っていないと死ぬ。

Test::mysqldだと、mysql_install_dbっていうMySQLのコマンドをキックしている んだけど、それが実はperlスクリプトで、/usr/bin/perlってshebangに書かれていて System perl前提にしているのだけど、それにlocal::libが入っていないとコケる。

Carton:CLI#cmd_execの中でPERL5OPTを以下のようにセットしているんだけど、 それが配下のプロセスにグローバルに影響を与えてしまうのが原因。

local $ENV{PERL5OPT} = "-Mlib::core::only -Mlib=$lib";

とりあえず手元では sudo cpan local::lib して凌いだ。cpanコマンドとか何年ぶり だろうかw

perlで書かれてSystem perl前提にしているコマンドをキックしているような場合に 軒並み動かない可能性があるので場合によっては困りそう。

根本的な解決は難しそうだなーという気はしているんだけど、とりあえず、 issueあげておいた。

該当のperlにlocal::lib入れれば解決するので、同様の現象で悩んでいる人も いるかもしれないのでとりあえずblogった。

local::libがperl coreに入れば徐々に解決といえば解決ではある。

3/18 23:45 追記:

ということで、既知の問題で修正を考えているとのことです。なんかこうmiyagawaさんから反応あるとすごく嬉しいですね!

投稿者 Songmu : 11:00

2013年3月12日

おもむろにbrew upgrade mysqlしたらTest::mysqldが起動しなくなって泣いた

*** mysql_install_db failed *** FATAL ERROR: Could not find my-default.cnf

If you compiled from source, you need to run ‘make install’ to copy the software into the correct location ready for operation.

If you are using a binary release, you must either be at the top level of the extracted archive, or pass the —basedir option pointing to that location.

5.5から5.6に上がったので、なんか壊れちゃったかなーと思ったけど、 mysql自体は起動するので、どうもhomebrewとTest::mysqldの相性の問題であった。

Test::mysqldではmysql_install_dbコマンドの場所からmysqlインストールパスを探しているようなの だけど、homebrewだとwhich mysql_install_dbで返ってくる /usr/local/bin/mysql_install_db は単なるシンボリックリンクなので、そのへんでうまくいっていない模様。

なんか、

% ls /usr/local/Cellar/mysql
5.5.28/ 5.6.10/

とかなっていて、5.5のプログラム自体残っていたので、それが影響しているのかなーと思いきや、 エイヤッとrm -rf 5.5.28してもコケたままなので、なんでそもそも動いていたのかが謎い。

とりあえず、実行ファイルがシンボリックリンクだったら、readlink呼んで実体パスの 解決を行うようにしたら動くようになったので、とりあえずpullreq送らせてもらった。

Test::mysqlのCPANTesters見たら 見事にオールグリーンで自分の環境が悪いのかと一瞬怯んだけどdarwinはなかったので安心(?)した。

ちなみにreadlinkとか初めて使ったというか知らなかった。

追記:ちょっと調整して取り込んでもらった!ありがとうございます!

投稿者 Songmu : 15:24

2013年3月10日

App::Xaicron構想

タスクの定期実行としてcronが使われ続けていることに問題意識を抱えている人は数多く居れども、多くは惰性で使い続けている。何を隠そう私もその1人である。

そんな中、近年ではcronの代替としてjenkinsを使うという斜め上の発想が蔓延りつつあるが、 そんなことをすると「cronに500Mもメモリ使ってられるかー」と椅子が飛ぶこと請け合いなので非常に難儀するものである。

斯くの如く問題意識を抱えていたものの、やはり惰性でcronを使い続けていたのだが、 昨日、代替cronのネーミングとして “xaicron” という非常に格好良い名前を思いついてしまったので、 この際代替cronについて考えてみることにする。

懸念事項としては、将来RPMパッケージ化などされた時に、実行ユーザーとしてxaicronが作られてしまって、 万が一xaicronというユーザー名を使っている人がいた場合に困るというのがあげられる。 (世界中のjenkinsさんは困ってないんでしょうか)

または、そのネーミングだと午前中は仕事してくれなさそうだという意見も頂いております。

ネーミング駆動でまだ全然イメージ湧いてないのですが、とりあえず、cronのpros/consを思いつくままに書いてみます。

cronの良い点

  • 枯れている
  • crondが落ちて阿鼻叫喚みたいなことはあんま考えなくて良い
  • Unix系なら大体どこにでも入っていてすぐ使える
  • 記法は大体みんな知っている(謎記法だけど)
  • 一つのエントリが一行に収まっているので綺麗に書けば一覧性はある(かも知れない)
  • 実行権限がユーザーごと別れてたりとか最低限の環境変数しか設定されてないとかセキュリティに配慮されてる
  • unixという考え方に則りsetlockとかsoftlimitとかcronlogとかtimeoutとかそういう細かいツールを組み合わせれば色々できる

cronのイケてない点もしくはcronができないこと

  • 記法が謎で初学者にやさしくない。間違えて毎分設定にして泣く人続出
  • setlockとかcronlogとかtimeoutとかsoftlimitとか覚えないといけないので敷居が高い
  • $PATHがちゃんと設定されていなくて動かないとかでハマりがち
  • crontabで環境変数の展開とかしてくれないの大分ダルい
  • 設定の横幅が長くなりがちだったり、ちゃんとスペース調整しなかったりすると読めなくなる
  • ちゃんと実行されるかどうかの確認に3分くらい待たないといけない
  • 後続の処理とかこの処理が失敗したらこの処理は走らせたくないとかそういう処理の親子関係みたいなのが設定できない
  • 標準の通知先がメールなので、いちいち全部のエントリーに| loggerとか書くのがだいぶダルい。結果としてログを捨てる人続出
  • 時間単位でしか設定できないし秒単位の設定ができない
  • 通知を受けてジョブを走らせるみたいなことができない
  • 設定を動的に変更するとかそういうことがやりづらいしやらないほうが身のため
  • Webインターフェースがない
  • 並列/排他処理とかは自分で頑張るしかない
  • 複数サーバーをまたいだジョブ管理とかができない
  • リトライとかタイムアウトとかできない
  • VCSとの連携(チェックアウトして実行とか)
  • 可視化ツールとの連携
  • プラグイン機構が無い

上記を踏まえていまぼんやりと考えているのは以下のような感じ。

  • 分かりやすいジョブ設定・環境変数設定
  • ジョブ管理デーモンがいて、うまいことクライアントと連携する
  • トリガによるイベント駆動的なジョブ実行(定時実行もそのうちの一つに過ぎない)
  • プラグイン機構
    • ジョブ実行前・実行後のフック機構
    • ログや通知機構の充実
    • 可視化
  • Webインターフェースは敷居を下げるためには必要

クライアント側に関してはUkigumo::Clientがだいぶイケてるので、そのへんからパクってくればいいかなーと思っている。 Ukigumo::Clientをもうちょっと抽象化したやつを切り出して、Ukigumo::Clientはそっちに依存する形でも良いのかなーとか思っている。

デーモン側はno plan。

こういう時参考実装とかをサクッとかけたりすればカッコいいんですけどねー。

投稿者 Songmu : 15:30

2013年3月 9日

もにかじでオレオレ監視ツールについて話してきました

オレ自身を監視するツールって話なんだけどな!発表資料は以下。

オレオレ監視ツール

自分が触っているアプリケーションでのタイプ数を可視化するツールです。

なんか手元のMacにGrowthforecastが簡単に入らなかったのでカッとなって VPS上に構築しました。これで僕の行動が世界中からまるわかりです!

3/11追記 手元にHRForecast立ててそれで代用したのでURL消しました

適当に設定したら偶然にも調度良く赤系(iTerm,Macvim)が仕事、緑系(Chrome, Limechat) がサボり系になりました。Limechatがちゃんとライム色になっているのが素晴らしいですね。

仕組みとしてはごく単純で以下のような感じ。

  • KeyRemap4MacBookをdebugをONにしてキーイベントをログ出力
  • Slateでアプリの切り替えを検知してそれをログ出力
  • それらのログをtailで読み込んでperlスクリプトでゴニョってfluentdに投げる
  • あとはfluentd-growthforecastにお任せ
  • ソースとか設定とかこのへん https://gist.github.com/Songmu/5109279

本当はUkigumoについて話す予定だったのですが、木曜日に思いついてしまって、 社内IRCの雑談チャンネルでアイデアについて話したらKeyRemap4MacBookを使う アイデアをtypesterからもらい、Slate使うアイデアをsugyanからもらって、 なんか簡単にできそうだなーと思って木曜の夜に夜なべして作った次第。

調べたら、edvakfさんがすでに同じようなことをされている ことに気がついたのですが気にしないで作りました。

あと、帰ってから嫁にこのことを話したら

  • 去年のYAPCの川崎さんのトークでそういう話があった
  • isuconみたいなやつで全員コレ使えば面白そう

などとFBをいただきました。そういえばoDeskがそういうアウトソース監視の仕組みを 入れているって話をしていましたね。

ということでだいぶガイシュツネタでしたが、アリ物使ったら簡単に実現できるよってことで一つ。

運用寄りの猛者が集う中で、アプリ寄りの僕としては場違い感があり、しかも 参加者全員発表というモヒカンルールがあるのですが、ネタに走って凌いだ感じです。

「そんな風にアプリ寄りとか言っているとなんとかモリスさんて人にDisられますよ」

とか言われるし、モヒカン怖いですね。

そういやUkigumo大分イケてる感じなので、その話はそのうちまとめます。

投稿者 Songmu : 22:32

2013年3月 7日

DBIx::Schema::DSLがWeek's winnerになりました

tokuhiromに教えてもらったのですが、なんかここで取り上げられられていました。

だいぶ数字が低いので、どさくさで運が良かった感がありますがありがたい話です。フィードバックも頂きたいものです。

解説すると、metacpanにはfavの仕組みが合って、https://metacpan.org/module/DBIx::Schema::DSLを見るとわかると思うんですが、 ログインした状態で、モジュール名右側を押すとfav的なやつを付けられるようになっています。

実はそれはこのへんで集計されていてランキングが見られたりします。

数字が寂しい感じなので、みんなもっと使って盛り上がると面白そうですね!ログインはgithubの認証で簡単にできますよー。

投稿者 Songmu : 10:53

2013年3月 3日

DBIx::TransactionManager::EndHookが便利だけどCPANに上がっていない件

後輩だか先輩だかわからないsoh335さんが作った DBIx::TransactionManager::EndHook が地味にかなり便利。

入れ子になったtransactionでcommitが走った時に走らせたい処理を登録できます。 RDBだけで完結しない処理(ログやKVS連携等)を書きたい時に有用です。

何が嬉しいかは、335さんのエントリにも書いてあるんです が、例えば、ひとつのトランザクションの中で、

  1. アイテム付与メソッド
  2. ボーナス付与メソッド

みたいなメソッドを呼び出されていて、それぞれのメソッドの中でログを投げていた りとかするとします。コードにすると以下のような感じ。 (Tengっぽく書いてますが、DBIx::TransactionManager直でも全然構いません)

my $txn = $teng->txn_scope;

$user->take_item($item);
$user->try_to_take_bonus; # ここで死ぬと困る

$txn->commit;

...
sub take_item {
    my ($self, $item) = @_;
    $self->items->add($item);
    log('take item!');
}

この場合、もしtry_to_take_bonusの中で例外が発生したりrollbakeが呼ばれたりすると、 take_itemの処理も正しくロールバックされるのですが、take_itemの中でログ書き込み 処理とかが行われているとそこまでは正しく巻き戻すことはできません。

それじゃ困るってことで、DBIx::TransactionManager::EndHookの出番。先ほどの take_itemを以下のように書き換えます。

use DBIx::TransactionManager::EndHook;
sub take_item {
    my ($self, $item) = @_;
    $self->items->add($item);
    $teng->transaction_manager->add_end_hook(sub {
        log('take item!');
    });
}

このようにすることで、commitが走った後にログ書き込みをすることができます。

ログなんかの他にもcommitが走ってから確実にRedisのランキングデータを更新したい みたいな場合にも有用です。

僕なんかは「Rollbackとかめったに起こらないし、そこで多少ログ間違えて吐いても良 くね?」くらいに思っていたのですが、soh335先生はそこが気になったみたいでこうい う痒いところに手が届くモジュールが出来上がりました。

DBIx::TransactionManagerのメソッドをRedifineしたりとかしてるので、CPANに上げる のをためらっているようなのですが、まあprivateメソッドを書き換えたりしているわ けじゃ無いので良いんじゃないでしょうか。不安だったら、#dbix-skinny@irc.perl.orgとかで相談したらいいんじゃないかみたいな話をしております。

soh335先生は結構細かいところが気になる人で、とにかく綺麗にテスト書かないと気がすまなかったり「わたし、気になります」ばりに質問力を発揮したりこういう痒いところに手が届く便利ツールを作ってたりするので一緒に仕事をしていて捗ります。

そんな中生まれた、Test::Cond::Deepも地味に便利です。 →Test::Cond::Deepに関するエントリ

なんか、二番煎じの宮崎あおいばかり注目を集めていて、 彼が作った有用なモジュールの情報があまり知られていないようだったので勝手に宣伝しました。

ということで、DBIx::TransactionManager::EndHookもCPANに上げてほしい。

投稿者 Songmu : 23:39

CartonConference行ってきた

当日からCarton触りだしてon testとかproveとの連携がどうたらとかtwitter言ってたら、tokuhiromとかmiyagawaさんに補足されて、その辺の現状とこれからの話とか知れてだいぶ良かった。カンファレンス駆動で学び始めるのだいぶ良い。

CartonCon自体もBundlerとの比較の話とか、現状のユースケースとかの話が色々出ててだいぶ捗った。

終わった後の懇親会が大分ひどくて楽しかった。

投稿者 Songmu : 23:10

Hachioji.pm#25に行ってきた

もう一週間前ですが、大分面子が揃っていて非常に楽しかったです。

  • ytnobodyさんがTengよりも先にIrohaっていうORM作っていてだいぶ時代を先取りしていた
  • perl5.17でハッシュオーダーがかわった影響でJSON.pmのテストコケててリリースブロッカーになってる話
  • DBIx::Schema::DSLのフィードバックをmakamakaさんから頂いた
  • yanchaのタグでメッセージを管理する機構がだいぶ面白い
  • TengにTeng::Iterator 差し替えられるpullreq送った
  • LTE早くてテザリングが捗った

Hachioji.pmはcharsbarさんやmakamakaさん、hideo55さんなど渋目の超一流Perl Hackerとお話できるのがすごくいいですね。

karupaneruraさんにTengのIterator差し替えるpullreq送った話をしたら「それ僕も欲しかったんですよねー」とか言ってもらえて良かったです。

ちょうど(今も)messagepackが紛糾している時期だったので、makamakaさんにJSONでは そういうこと無いのか聞いたら「JSONの仕様よりもLehmann先生(JSON::XSの作者)とコ ミュニケーションとる方が大変で面白い」とか言っていたのが大分面白かった。

makamakaさんはAcmeの人というイメージが強そうですが、Perlのコアモジュールであ る、JSON.pmのメンテナなのは普通に世界的にすごい人ですよね。

最近Amon2を使い始めていたので、hirobanexさんとお話できたのも良かったです。

なんか最近ORMにしてもWAFにしても、ヘビーすぎるか軽いかのどちらかしかなくて、 調度良い具合のを作るには自分で何とかしないといけない部分が多くて結構コストが かかるってことを感じていたんですけど、そういう風に感じている人はやっぱ少なく無 いんだなってこととかを色々話して感じられたので良かった。

また顔だそうと思います。

投稿者 Songmu : 23:07

2013年2月15日

今週のおーぷんそーす活動と、Dist::MakerのModule::Build対応とか

深夜のテンションで「おりゃっ」とpullreqを送りつける今日この頃、皆様いかがお過ごしでしょうか。

そんな雑なpullreqに対応してくださってる皆様、本当にありがとうございます。

てことで、今週のpullreq活動。

Dist::Maker

愛用させてもらっているモジュール雛形作成ツール。

Module::Build対応とModule::Buildを使った雛形DefaultMBをpullreqして0.07でshipit してもらいました。

以下のようにすればM::B形式で簡単にモジュールが作成できます。簡単ですね!

% cpanm Dist::Maker

# 設定。設定ファイルの位置は ~/.dim/config
% dim config --import-from-gitconfig
% dim config template.default DefaultMB

# 雛形作成
% dim init My::Module
% cd My-Module

# モジュール書いた後のCPAN Upload処理
% perl Build.pl
% ./Build distmeta
% ./Build manifest
% shipit

これでアナタもシーパン王サー!

これだと最低限ですが、Dist::Makerの雛形書くのは簡単なんで、 Dist::Maker::Template::* を見ながら、自分用にカスタマイズしたの用意すると良いかと。

M::Bの説明書くのめんどくなってきたんで、これでM::B使えますよってことで一つ。

Time::Piece::Plus

Time::Pieceを継承してDateTimeライクなインターフェースを追加した日付モジュール。

結構便利なんじゃないかと思うんですが、あまり使われている気配がなくて不思議な感じがしています。皆様日付処理どうしているのでしょうか。わたし、気になります。

これのadd/subtractメソッドにDateTime的なインターフェースを加えてpullreqして取り込んでもらいました。以下の様な感じ。

my $time_pp = Time::Piece::Plus->localtime;
$time_pp = $time_pp->add(days => 7);

DateTimeと違うのは破壊的じゃないところですね。

これでDateTimeで僕が使ってる機能は大体Time::Piece::Plusに揃ったので、大手を振って以降予定。


両方共俺得でしか無いフィーチャーですが、勇気を出してエイヤッとpullreqした次第。

gfxさん、takuji31さん、ありがとうございました。

DBIx::Schema::DSLも「俺得でしか無いんだよなー」とか言っていたら@typesterに「俺得でも全然良いから出しなよ」とか言われてかなり勇気をもらったりしました。

そういや、Parse::Crontabも俺得でしかないと思っていたけど、機能要望が届いていたりしてありがたい話だなーとか思いました。俺得は誰かの得にもなる、…かも知れない。

おれとくでもいいじゃない、にんげんだもの。

投稿者 Songmu : 02:32

2013年2月13日

CPANモジュールのパッケージングの歴史

最近同僚が次々とCPAN Authorになってて良い流れだなーとか思っています。

ただ、CPANへのモジュールの上げ方がわからないとか、M::Iを使えばいいのか M::Bを使えばいいのか、それらがそもそも何やってるのか分からないという話も 聞くので、僕自身もその辺の知識を整理してアップデートしました。

とりあえず、今はModule::Buildを使っておけば良いんじゃないかと 思っていますが、そこに至る歴史的経緯をまとめてみます。

大体、以下に書いてあることに加えて、最近の動きを書いています。

Module::Build:MakeMakerの後継者を目指して

PerlでCPAN形式のモジュールを配布する場合は、Makefile.PLなりBuild.PLなりを モジュール作者が用意して、それがインストールに必要なファイル類を自動生成 するという流れになっています。

既存の雛形を使うと色々ファイルができてぎょっとしますが、最低限必要なのは lib/以下のモジュール本体と、(Makefile|Build).PLだけです。

ExtUtils::MakeMaker(EUMM)

Unix系OSではビルドツールに昔からmakeが多く使われているのは御存知の通り。 Perlモジュールもmakeでビルドしてインストールするのが楽だろうってことで、 make用のMakefileをPerlで書き出す仕組みが作られた。

それが ExtUtils::MakeMaker 。20世紀末くらいの話。

Makefile.PLの中でuse ExtUtils::MakeMaker;WriteMakefile(…);とかやって使う。

Perl5当初からコアモジュールなので、Makefile.PLの中でuseしてもCan’t locateとか 怒られない。

これで、以下の様な今のPerlモジュールインストールの形の基礎が作られました。

% perl Makefile.PL
% make && make test && make install

実際のところcpanm?コマンドもtarball落としてきて、こういうインストールコマンド を自動的に実行してくれています。

makeフェイズで実際に何をやっているかとかは以下が参考になります。

Perlのmakeフェーズの挙動

Module::Build(M::B)

make installでやってることってそんな大したことなくて、特にPurePerlの場合は ファイルの配置くらいだし、それってPerlの方が得意じゃね? ってことで、makeに頼らないPerlモジュールビルドツールってことで作られたのが、 Module::Build 。初リリースは2001年。

Build.PLというファイルを作ると、perl製のビルドスクリプトをBuildという名前で作 成する。

モジュールインストール手順は以下の通り。外部ツールに頼らずにPerlだけで完結して いる。

% perl Build.PL # Build ファイル作成
% ./Build test
% ./Build install

単にビルドスクリプトを作るだけではなく、モジュールのメタデータの自動生成と その仕様を定義し始めたのが功績で、 META.yml なんかはExtUtils::MakMaker 側にも入ることになります。これ後々の重要ポイントです。テストに出ますよ。

ただ、

  • 当然ながらModule::Buildがインストールされていない環境だと動かない*
  • CPAN Shellが上記のインストール方法に対応してくれるのが遅かった
  • XSモジュール作成用には弱かった

等の問題があり、また次に述べるModule::Installに多くの人が移行してしまったため 一旦あまり使われなくなります。

* 一応、Perl5.10からはコアモジュール入りしています。
また、ExtUtils::MakeMaker形式のMakefile.PLを自動生成する機能も 後から追加されたので、それを使って、モジュール作者側でパッケージに Makefile.PLも同梱するという回避策もあったりはします。

Module::Install(M::I)

そこに現れたのがM::I。正しくパッケージングすればサラの環境でも モジュールインストールが可能で、他にも良いことづくめなので、一世を風靡します。 今でもかなり使われていますね。

多くの人が使っているので、見よう見まねで他の人が書いているM::I形式の Makefile.PLを作ったことがある人も多いんじゃないでしょうか。僕がそうでした。

最初に作られたのは2003年くらい。特徴としては以下。

  • Makefile.PLをDSLでかっこ良く記述できる
  • インストール方法は従来のmake
  • プラグインで拡張可能 
  • inc/ の活用

前項でも述べましたが、EUMMにはコアモジュールならではの強みがあり、 サラの環境でいきなりperl Makefile.PLしてもちゃんと動きます。

ところがコアモジュールじゃないモジュールだと、エンドユーザーが事前にその モジュールをインストールしないといけないという問題が発生します。

じゃあどうするか。そこで、考えられたのが、

インストールモジュールをパッケージに同梱してしまう

というエポックメイキングな力技です。perl Makefile.PLすると、Makefileや メタファイルが作られるとともに、inc/が作られてそこにM::I自身や付随する プラグインが格納されます。

configure_requires登場によるinc/のオワコン化とM::B再び

inc/ は確かに現実的な解決策ですが、さすがにやりすぎ感があります。

インストール時にいきなり(Makefile|Build).PLを走らすから事前にインストールモジュールが 必要になるからこうなったわけですが、それを動かす前に必要なモジュールをインストールする 仕組みがあればよさそうです。

そこで利用されたのがMETA.ymlです。META.ymlはもともとCPANサイト掲載に必要なメタ情報 なんかをまとめてあるファイルですが、そこに事前にインストールされている必要があ るモジュールの情報を含めてしまえばよさそうです。

それがconfigure_requiresセクションです。

今はEUMMもM::IもM::Bも適切にPLファイルを書けば、META.ymlにconfigure_requiresを出力 してくれるので、それをパッケージに同梱します。

また主だったモジュールインストーラー(cpan(m|p)?)も現在はconfigurerequiresに対応 していて、Makefile.PLを走らせる間に、META.ymlのconfigurerequiresセクションを見て、 そのモジュールをインストールしてくれます。

このようにconfigure_requiresを使えば、inc/に色々同梱する必要はなくなりました。

configure_requiresに関しては以下にまとまっていました。

https://www.socialtext.net/perl5/configure_requires

また、M::Iの利点であるプラグイン機構も、昨年tokuhiromによって開発された Module::Build::Pluggableを使えばM::Bで実現出来ますし、M::B自体も継承すれば なにげに簡単に拡張できるようになっています。

そうなるとM::Iの利点はDSLと既存のプラグイン資産くらいです。それにDSLにも良し 悪しがあるし、M::I自体のが動作が不安定だった時期もありました。

だったら、M::BはPerl5.10からコアモジュールだしそれ使えばよくね?となってきてるのが 最近の流れ。

githubの存在も無縁じゃなくて、Module::Build使ったほうが色々楽だったりします。 具体的には以下の様な感じです。

  • Travis連携が超絶楽
  • cpanmでgithubからモジュールを簡単に直接インストールしてもらえる

まとまらないまとめ

とりあえず、今日はここまで。次はファイル構成の話なんかを気が向いたら書きます。

なんかざっくり書く予定が、途中から丁寧になって長文化してしまうのが悪い癖。

投稿者 Songmu : 12:50

2013年2月11日

DBIx::Schema::DSLってのを書いている話

https://github.com/Songmu/p5-DBIx-Schema-DSL

Teng使って開発しててDDLを直接書くのに大分疲れてきたので、RDBのスキーマを定義、 管理するDSLモジュールを書いています。

Podに書いてあるのとほぼ同じですが、こんな風にスキーマ定義しておいて、

package My::Schema;
use DBIx::Schema::DSL;

database 'MySQL';
create_database 'my_database';
default_unsigned;

create_table 'book' => columns {
    integer 'id',   primary_key, auto_increment;
    varchar 'name', null;
    integer 'author_id', not_null;
    decimal 'price', 'size' => [4,2];

    add_index 'author_id_idx' => ['author_id'];

    belongs_to 'author';
};

create_table 'author' => columns {
    primary_key 'id';
    varchar     'name';
    tinyint     'age';

    add_index 'age_idx' => ['age'];

    has_many 'book';
};
1;

こんな感じで、DDLを出力できます。

use 5.014;
use My::Schema;
say My::Schema->output;       # output DDL
say My::Schema->no_fk_output; # without fk constraints

そんな違和感ないんじゃないかなーと思います。

内部的にはSQL::Translatorを使っていて、SQL::Translatorオブジェクトを 組み立てるDSLを提供しているだけとも言えます。

案の定、@fujiwaraには「直でSQL書けばいいじゃん」とか言われてしまったのですが、 @typesterには「ちゃんと完成したら使うよ」と評価を頂いております。

作っている動機としては

  • DDL直接書くのはクオートとかカンマとか気をつけないといけないし、冗長な記述も多いのでたるい
  • DDL直書きスタイルだと、複数人開発だと微妙に書き方がバラバラになったりするのがイヤン
  • ER図描画等のため、MySQL workbenchには外部キー制約つけたDDL食わせたいけど、本 番ではある程度インデックスを間引きたいので、外部キー制約つけてないDDLも出力 したいとかそういうニーズがある
  • ゆくゆくはORMと連携させて、クラス定義とか、リレーションメソッド生やすとかそういうことできると良さそう

という感じですかね。

本番で外部キー制約つけないとか「SQLアンチパターン」に見事にアンチパターンとし て書かれていましたね。仕方ないね。

あと、SQL::TranslatorがMoo依存になってたので、Moo使っております。

今やってるプロジェクトで使い始めてるんで、もうちょっとしたらCPAN上げる予定。

投稿者 Songmu : 00:31

2013年2月 2日

2013年のGetopt::Long

完璧な引数処理モジュールなどといったものは存在しない。完璧なGetopt::Longが存在しないようにね。

バッドノウハウの宝庫として有名なGetopt::Longですが、なんだかんだでデファクトで、gnu parallel等、名の知れたコマンドラインツールで使われていたりします。標準モジュール縛りでサクッとコマンドラインツールを書くこともあるでしょうし、そうではなくても、Getopt::Longで片付くことも多いので、個人的なベタープラクティスとかtipsとかを書きます。

Perlでコマンドラインオプションの解析に Getopt::Long を使う時、絶対に忘れてはいけない引数

大事なことは上の記事に書いてあるので、まずはこれを読んでください。

サンプルコード

僕がスクリプトを書くときのの雛形は大体以下の様な感じ。

#!/usr/bin/env perl

=head1 DESCRIPTION

サンプルです

=head1 SYNOPSIS

    % sample.pl

=cut

use strict;
use warnings;
use utf8;

use Getopt::Long qw/:config posix_default no_ignore_case bundling auto_help/;
use Pod::Usage qw/pod2usage/;

# ハッシュで受ける
GetOptions(
    \my %opt, qw/
    foo=i
    var=s
    all
/) or pod2usage(1);

# 必須オプションのチェックとか
my @required_options = qw/foo/;
pod2usage(2) if grep {!exists $opt{$_}} @required_options;

# 処理
my $app = MyApp->new(%opt);
...

podとpod2usage

pod書いておくと、pod2usageで出てくるし便利。上の方にpodを書いているのは、仕事で使うツールだと、先に説明と使い方を書いておいたほうがすぐ使えるし分かりやすいという判断。

posix_default no_ignore_case

上のtagomorisさんの記事を熟読のこと

gnu_compatは指定不要

configにgnu_compatは指定していません。上記記事では、「—option=value といった、これはこれで馴染みがある形式の指定がデフォルトでは無効のため、」と書いてありますが、これは勘違いで、—option=valueの形はデフォルトで有効です。

じゃあ、gnu_compatは何なのかというと、—option=valueでvalueに空文字列を指定し たいときに—option= とかやると、エラーになるのを回避してくれるというオプションです。

bundling

引数をまとめられるのは嬉しい。

それよりも個人的に嬉しいのは、このオプションを指定すると、ロングオプションを 必ずハイフン2つで始めなくてはいけなくなるということ。

例えば、上で allというオプションがあるが、デフォルトだと-allでも有効に なってしまうが、bundlingを指定すると—allじゃないと有効にならない。

auth_help

—helpとかした場合に、pod2usage出力を呼んで処理を抜けてくれる。

pod2usage(0) if $opt{help};とか書かなくて良くなるのが微妙に便利。

同様にauto_versionてのもあって、—versionのハンドリングを自動でやってくれる。 $main::VERSIONが指定してあったらそれがバージョン番号として使われる。

これもちょっと便利だけど、普段は必要ないなーという感じ。

GetOptionsはハッシュで受ける

変数ではなくハッシュで受けてるのは、上記のように必須オプションのチェックがし やすいし、上記のようにそのまま引数として使えるのでスッキリして良いんじゃないかと思っている。

また、%optをさらにData::Validatorに掛けると良いんじゃないかと、typesterが言っていました。そういうこともやりやすくなります。

以前は変数で受ける派でしたが、typesterの影響でハッシュで受ける派になりました。

GetOptionsでエラーが有った際に処理を中断するように or pod2usage(2); とやるのは定石。

pass_through

上記では指定していないし、普段は指定しないが、GetOptionsを複数回指定したい時などに使うのがpass_throughオプション。

通常@ARGVに余計な引数があれば警告を出してGetOptionsも偽値を返すが、それを無効にするオプション。

foo=var --all -- hoge=fugaのように引数を--で区切れば、順番に処理をすることも可能ですが、必要な引数がごちゃまぜになっている場合はうまくいかないので、pass_throughを指定します。

ままあるのが、Plackアプリを作って起動スクリプトを作った時に、port指定やらサーバー指定やらも混在してしまう場合。

まあ、書いててもなんのことやらだと思うので、拙作Plack::App::Directory::Markdownに同梱してあるpad-markdown.plのソースを一部抜粋して説明に変えます。

use Getopt::Long qw/GetOptions :config auto_help pass_through/;
...
GetOptions(\my %options, qw/
    root=s
    encoding=s
    title=s
    tx_path=s
    markdown_class=s
    markdown_ext=s
/) or pod2usage(2);

my $app = Plack::App::Directory::Markdown->new(%options)->to_app;

push @ARGV, '--port=9119' unless grep {/^(?:--port|-p)\b/} @ARGV;
my $runner = Plack::Runner->new;
$runner->parse_options(@ARGV);
$runner->run($app);

ここでは、GetOptionsを2回読んでいるわけではありませんが、$runner->parse_options(@ARGV) がGetOptions同様の処理を行なっています。

configが上の説明とだいぶ違いますが、これを書いた頃はベタープラクティスが固まってなかったので、ご容赦下さい。

投稿者 Songmu : 16:45

Module::Advisor便利ですね

こういう時こそ、Lの出番です。

% perl -ML -E 'Module::Advisor->new->check'

投稿者 Songmu : 14:47

Plack::Middlewareで$envの中身を見るテストを書く方法

Plack::Middlewareの中で $env->{'psgix.hoge'} 的な何かを突っ込むことはあるん じゃないかと思うが、そのテストをどう書くかという話。

Plack::Testだとレスポンスは見られるが、$envはもう見られない。

結論を言ってしまうと、$envをシリアライズして、response bodyに突っ込んでしまう $appを作るのが乱暴かつお手軽かと思う。

以下サンプルコード。

package Plack::Middleware::Hoge;
use strict;
use warnings;
use parent 'Plack::Middleware';

sub call {
    my ($self, $env) = @_;
    $env->{'psgix.hoge'} = 'fuga';
    $self->app->($env);
}

このMiddlewareをテストする。

use strict;
use warnings;
use Test::More;
use Plack::Test;
use Data::Dumper;
local $Data::Dumper::Terse  = 1;
local $Data::Dumper::Purity = 1;

use Plack::Middleware::Hoge;

my $app = sub {
    my $env = shift;
    [200, ['Content-Type' => 'text/plain'], [Dumper $env]];
};
$app = Plack::Middlware::Hoge->wrap($app);

test_psgi $app, sub {
    my $cb = shift;
    my $res = $cb->(GET '/');

    my $env = eval $res->content;
    is $env->{'psgix.hoge'}, 'fuga';
};

JSONでシリアライズすることも考えたけど、Data::DumperはPerl5.8でも標準添付 なのでそれでよいかな、と。

以前は$appのなかにokとか書いてたんだけど、そうすると、リクエストに応じて、$app 作り変えないといけなかったりしてめんどくさいのでこういう形に落ち着いた次第。

Plack::Middeware::Outh::OAuthもこの形式でテストがりっと書き換えました。

投稿者 Songmu : 14:35

2013年1月 5日

運用におけるcrontabのテストとParse::Crontab

Vixie cron形式のcrontabをparseするモジュールをリリースしました。 Vixie cronと言えば、けんじおじさんに「カビ臭い」とかdisられそうな代物ですが、なんだかんだで利用している人は多いでしょうし、僕も使っています。

https://metacpan.org/release/Parse-Crontab

最近携わるプロジェクトではcrontabはリポジトリ管理しているのですが、それをあまりちゃんとテストをしてなかったので、それを解消すべく書きました。

以下の様に、crontabのテストを書くことが可能です。

use strict;
use Test::More;
use Parse::Crontab;

my $crontab = Parse::Crontab->new(file => 'data/crontab.txt');

ok $crontab->is_valid or diag $crontab->error_messages;

for my $job ($crontab->jobs) {
    my $command = $job->command;
    # 実行ファイルがちゃんと存在するかのチェックとか
    ...
}
done_testing;

さくっと書く予定だったのですが、大分重厚長大な感じで、MouseOO厨感丸出しになっておりますが気にしないで頂きたい。 気に食わなかったらParse::Crontab::SimpleなりLiteなりを作っていただければと思います。もちろんPullreqもお待ちしております。

ちなみに、リポジトリ管理しているcrontabは以下の様な感じで本番サーバーに反映しております。

# 差分確認
% diff -u <(crontab -l) data/crontab.txt
# 反映
% crontab data/crontab.txt

このモジュールを書きながら調べていて、実はcrontabの指定形式は色々奥が深い(複雑な)事を知ったのですが、それは別のエントリーにでも書きます。

ところで、とあるプロジェクトで cat data/crontab.txt | wc -l したら90とか返ってきて、自分の目を疑ってエディタで開いて確認しなおしましたが間違いありませんでした。そりゃちゃんとテストしないといけませんな。

投稿者 Songmu : 02:39

2012年12月24日

ワンライナーでOOなPerlモジュール使うときに、2回もモジュール名を打ち込んでいられるほど人生は長くない件について

ランダムな文字列を求めたい時に以下のようなコマンドを打つことがあるが、String::Randomを2回も打ち込んでいられるほど人生は長くはなかった。

% perl -MString::Random -E 'say String::Random->new->randregex("[0-9a-z-A-Z]{12}")'

なので、Lというモジュールを書いてみた。

https://github.com/Songmu/p5-L

これを使うと上と同様の処理が以下のように書ける。

% perl -ML -E 'say l("String::Random")->new->randregex("[0-9a-zA-Z]{12}")'

ただ、lという関数をかますのがダサい感じなので、

% perl -ML -E 'say String::Random->new->randregex("[0-9a-zA-Z]{12}")'

みたいに書けるとなお良いが如何せんPerl力が足りないので、実現可能かどうかわからないのであった。

autobox + AUTOLOADを使えば以下のように書けるんじゃないかという意見もいただいております。

% perl -ML -E 'say "String::Random"->new->randregex("[0-9a-zA-Z]{12}")'

なんかうまいやり方がないか、Perl Magiciansのご意見をお待ちしております。

追記

tokuhiromがサクッとpullreqってくれて、UNIVERSAL::AUTOLOAD使っていけるようになりました。tokuhirom++すぎる。

% perl -ML -E 'say String::Random->new->randregex("[0-9a-zA-Z]{12}")'

UNIVERSAL::AUTOLOAD定義するとか危なすぎるんで、ワンライナーの使用にとどめましょう。

マジカルなこと必要かとおもいきや、CoreモジュールだけでサクッとかけてしまうあたりPerlマジ黒魔術。

他にも意見くださった、_gfx_、fujiwara、__kan、ありがとうございました。

まだCPANにあげてません。さすがに一文字モジュールをCPANに上げるかどうかは迷いますなー。

2012/12/26 追記

14:04 Songmu: L.pm を CPANize したものか迷う。
14:04 Songmu: https://github.com/Songmu/p5-L
14:04 Songmu: 俺得でしか無いんじゃないか。
14:06 karupanerura: つかいたいです!
14:06 kazeburo: おなじく!
14:12 Songmu: じゃああげちゃいますよ...!
14:15 gfx
: (゚A゚;)ゴクリ
14:15 karupanerura: wktk
14:15 kazeburo_: ++
14:19 typester: -MFoo とかしてたらうしろでクスってされる時代来ちゃう

15:14 Songmu: https://metacpan.org/release/SONGMU/L-0.01/
15:14 Songmu: 上げてしまいました。gkbr
15:15 __kan: ktkr
15:18 bayashi_____: L イイ!

という感じでshipitしましたことをお知らせいたします!ご相談に乗っていただいた皆様ありがとうございました!

投稿者 Songmu : 01:45

2012年11月 7日

#isucon2 で連覇させてもらってきました

主催の皆様素晴らしいイベントの提供本当にありがとうございました。

まさかの2連覇ですが、@fujiwaraの恐ろしさを再認識するとともに、@typesterのチート性能を見せつけられた感があります。

まずは個人的な反省点から

  • 去年よりかは大分成長しているつもりだったのに、@fujiwaraとの力関係が何もかわっていなかったことに衝撃
  • @typester(Redis期)がRedis使ってくることはわかっていたのに、競技中に brew install redisとかやってるのはダサすぎ

ということで、isucon2を振り返ります。

事前準備

事前にIRCチャンネルを作っておいてnopate botを呼んでおいたくらい。カヤックから別チームも出ていたので、お互いのチャンネルには入らないという紳士協定。

去年の経験から、revサーバーに直接gitリポジトリを作れれば捗ることは分かっていたので、その辺調べておく予定だったのですが、結局当日は@typesterに任せてしまいました。

11:00-12:00 下準備

  • 配られた資料を見ながら構成情報を転記してIRCに貼るなどする。(Songmu)
  • revサーバーを踏み台にする。authorized_keysに各人の公開鍵書き込み
  • 各サーバーでの.ssh/configの設定 (fujiwara)
  • revサーバーにgitリポジトリ構築 (typester)
  • スキーマとアプリのソース確認 (typester Songmu)
  • redisブランチ立ち上げ(typester)
  • capistranoによるdeploy環境構築(fujiwara)
  • my.cnfのslow_queryの秒数を0.1に変更

下準備ですね。

git周りはtypesterが得意なので任せ。deploy周りは去年使ったシェルスクリプトを流用しようかなーとか思ってたら、@fujiwaraがcapistrano入れてた。俺空気乙。

typesterが速攻redisブランチを切ったのには吹きました。見切り発車で先行実装ってのは去年の@sugyanが頭をよぎりましたが、さすが@typester、格が違いましたね。

アプリを見た感じだと、以下の点には気が付きました。

  • サイドバーの生成部分でjoinしまくっているところが気になる
  • ORDER BY RAND()とかやっててウケる
  • チケットのtableのマスの描画が重そう

11:57:36 <Songmu> これ描画してるのすごく重い気がするけど、消しちゃダメなのかな。
11:58:00 <Songmu> 毎回全件スキャンしてる。
12:00:05 <Songmu> ORDER BY RAND() アル―

とは言え、気になってもすぐに手を付けるんじゃなくて、本当に手を入れるべきか計測してから手を入れるのが鉄則。

12:00-13:30 細かいチューニング

とりあえずベンチ走行。DBに負荷かかってるのを確認しながら細かく調整。

  • ORDER BY RAND() を削除 (Songmu)
  • 静的ファイルをapacheが返すように変更 (fujiwara)
  • URL毎にresponse time計測 (fujiwara)
  • index追加 (fujiwara)
    • CREATE INDEX stock_order_id ON stock(order_id);
    • CREATE INDEX variation_order ON stock (variation_id, order_id);
  • apacheのプロセス数調整 (fujiwara)

サイドバー描画部分はorder_idにindex貼ったら特に問題ないレベルに改善。JOIN3つしてるからボトルネックに見えてキャッシュとかしたくなるけど、完全に撒き餌で、正攻法でindex張れば改善するという。

なんか、普段だったら見つけられるはずのindexの張り漏れをあの場では見つけられないのはなんでなんでしょうね。そして、それをあの場でも高速で発見する@fujiwaraはなんなんでしょうね。

このあたりからしばらくトップ維持。地味な調整でジワジワを他のチームを引き離していく@fujiwaraのチューニング力にビビります。

ただ、どのチームもなかなかブレークスルーを起こせていない状況で、イノベーションが起きれば一気にひっくり返される差でしかない。

13:30-14:00 ボトルネック判明

  • apacheをnginxに差し替えたらスコアが激減する現象に悩まされる (fujiwara)
  • dbサーバーにredis立てたりする(fujiwara)
  • /ticket/以外は大分軽くなったので、/ticketの処理の改善 (Songmu)
  • redisブランチが大体できてくる(typester)

nginxに差し替えたらスコアが下がるのは、nginxが後ろに回しすぎてしまってappが詰まることが原因の模様。

/ticketは残席数のカウントに無駄なCOUNTクエリーが走っていたので、そこのクエリを削減するなどしたらスコアは少し改善。(今回僕が書いたコードはこの辺くらいなのですが、これも結局redisブランチ採用により使わなくなります(涙))

この辺でDBのボトルネックは大分改善されて、appがボトルネックになってくる。そして、スコアが改善するにつれて /buy の購入処理でのdead lockの割合が増えてきて、ベンチFailする割合が増えてきた。

ORDER BY RAND()は無いにしても、競合の起こりにくい販売ロジックを考える必要があるなーという話になる。

/ticketのtable部分はキャッシュしないとどうにもならんなーという感じになる。

この辺でスコアは1600ticketsくらい。Redisブランチは一旦pushされたもののまだバグっていて動かない。

この時点でのボトルネックと対策方針は以下2点

  1. /buyの販売の競合を避け、高速にさばけるようにする
  2. /ticketのtable部分をキャッシュする

14:00-15:00 Redisブランチ炸裂

  • redisブランチの調整と完成(typester)
  • Starmanのworkder数調整(fujiwara)
  • お昼ごはん

ところがどっこい、販売処理のボトルネックを劇的に解消する飛び道具が炸裂します。それがRedis。

MySQLの在庫テーブルstockと販売履歴テーブルorder_requestをそれぞれ、Redisのセット型としてリスト型として持つようにして高速に販売処理を捌く実装を@typesterが見事に作り上げます。この短時間であれだけのアプリの改造をやりきったことには舌を巻く他ありません。

これがバグなく動くようになれば、販売処理のボトルネックは一気に解消することになります。この時間帯はサーバ上もredisブランチに切り替えてベンチ走らせながらデバッグ。僕はticketの表の描画部分がバグってたのでその辺typesterに助言したくらいで、わりとこの辺空気。

Redisブランチは無事に完走し、1900ticketsを叩きだす。

スコアより大きいのは、ここで購入処理のボトルネックが一気に解消されたこと。

ただ、スコアは思ったより伸びないねーという感じ。やっぱ/ticketの描画をどうにかしないと厳しいけど、同期処理だとしんどいから非同期処理にしたほうが良いかなーという話が出る。

Starmanのworker数の調整をしてみるも、ベンチマークプロセスの同時並列数が多いので、そこまで減らせないというジレンマ。

そんなこともあり@typesterはnode実装の方を試し始めた。

14:39:36 <typester> ここまで並列度高いとforkモデルは不利なかんじする
14:50:53 <Songmu> このままredisブランチが炸裂してしまうと、僕が空気になるのでつらい
14:51:17 <typester> アプリ非同期にしたくてつらい

15:00-15:40

  • node実装検証(typester)
  • お茶くみ(Songmu)
  • /ticketの部分の処理のプロファイリング(fujiwara)

基本に立ち返りticketの部分の処理をプロファイリング。Devel::KYTProfを入れてボトルネックを検証。やはりテンプレートの処理が重く、他のページの描画は数msなのに、ここは数十ms以上かかっている。確証を得てそこのキャッシュ戦略を考え始める。

僕はコーヒーが来たのでお茶くみなどしておりました。

/buyのタイミングでキャッシュするという実装も少し書いたりはしていたのですが、buyは毎秒数十以上捌くわけだから、そこで毎回キャッシュ作成するのも筋悪だよねーという話になって個人的に手詰まり状態。

この辺でredisブランチ採用する流れになってきたんだけど、僕の手元では動かせなかったのでbrew install redisとかやってた。ダサすぎる。

@typesterはnode実装が手元で動かないとかで諦めて戻ってきた。

若干手詰まり感。このままのスコアでも上位には行けるだろうしもしかしたら優勝できちゃうかもしれないけど、それだと出題者に負けた感が強すぎるので何とかしたいという雰囲気。

15:40-16:15

  • キャッシュ作戦会議
  • 実装

ということで真剣にキャッシュ戦略を考え始める。

購入処理の度にキャッシュしてたら効率悪いけど、1秒以内に反映されていれば良いというレギュレーションだから、それ以内の時間ならキャッシュできるよねってことで、毎秒更新するワーカープロセスを作りましょうという話になる。

一から作るのはちょっと時間がかかるから、既存のアプリを流用して、/ticket/update_cacheというURLにPOSTアクセスが来たら、テーブル部分のキャッシュを更新するようにして、そのURLを叩きまくるスクリプトを別で作るという作戦。

この作戦立案は@fujiaraなんだけど、去年のキャッシュ戦略もそうでしたが、短時間で実現可能な現実的な「力業」を瞬時に立案できるその発想力が凄まじい。その力を得るために、これまでどれだけの修羅場をくぐってきたのか想像もつきません。

この実装は分担的に僕がやるところだったんだけど、僕の手元でredisブランチが動かないという大失態でわたわたしていたので、結局@typesterに実装をお願いすることに。情けない限りである。

KossyとかXslateは僕のほうが慣れていたので、僕が後ろから見ながらペアプロ的に実装。程なく実装は完了。

テンプレのキャッシュはRedisで十分高速なので、memcachedは使わずにRedisに格納するようにした。Redis大活躍。

16:15-16:40 特別賞僅差

キャッシュの実装が完了して実際に動かしてみる。多少バグはあったものの、スコアは5500ticket前後を叩きだし、暫定トップに返り咲く。

この少し前に一つ頭の抜けだしたスコアを山形組が叩きだし、特別賞を僅差で持っていかれたのが残念である。

16:24:47 <Songmu> 山形組キテる
16:28:22 <Songmu> 特別賞持っていかれた
16:28:44 <typester> もうちょいここ効率化する
16:28:51 <typester> 更新しなくても良いのもループ回してるから
16:37:14 <Songmu> 山形組安定しない。
16:37:21 <Songmu> 安定させれば勝つる
16:39:30 <Songmu> トップ奪還
16:40:22 <typester> おしいなー
16:40:23 <typester> おしい!
16:40:30 <typester> 特別賞的な意味で

ちなみに、@fujiwaraがこの辺でapacheをnginxに差し替えていたようです。appが高速化したのでnginxに差し替えても詰まることがなくなったということでした。

16:40-17:20 キャッシュの見直しとプロセス分割

一応一位に返り咲いたものの、Failすることも多く安定しない。原因としては5ページ分のキャッシュを作る処理がappの負荷状況によっては1秒以上かかってしまい、そこでコンテンツの不整合によりベンチで撥ねられるというもの。

revでもplack立てたり色々試行錯誤したのですが、結局、dbにキャシュ更新専用のplackを立てることに。かつ、ひとつの処理で5ページ分のキャッシュを更新するのではなく、処理のプロセスを分けることに。

@fujiwaraがdbでplackを動かす準備をしている間に、プロセス分割の処理の実装は僕が担当。

この間、@typesterはレギュレーションのCSVのデータ永続化周りが気になるので、redisが突然再起動かかっても大丈夫かどうかの確認や調査をしてもらっていました。

17:20-17:40 アプリの凍結と再起動確認

作戦は見事に成功。ベンチも安定し、もうこれ以上はいじってもバグるだけだろうとうことでここで凍結を決定。あとは再起動してからちゃんとベンチが通るかを確認するだけとしました。

全台再起動してからのベンチも成功し後は終了を待つだけというかなり余裕を持ったフィニッシュとなりました。

山形組との一騎討ちの様相を呈していたのですが、山形組が5000ticket前後なのに対して、5500ticket前後のスコアで安定していたので、多分勝てるんじゃないかと思っていました。

17:40:50 <typester> redisの布教ができそうでなによりでございます
17:41:28 <Songmu> 完走すれば勝てる
17:41:32 <Songmu> 去年と同じや!
17:41:53 <Songmu> buyのボトルネックをredisでふっ飛ばせたのは大きい。
17:41:57 <Songmu> 飛び道具だった
17:42:01 <typester> ほほほ
17:42:07 <Songmu> typester++
17:42:10 <Songmu> まだわからないけど。
17:42:21 <typester> まぁしってても、仕事で使ってる人じゃないとたぶんうまく使えないですよね
17:42:27 <Songmu> そっすね
17:50:06 <Songmu> ローカルにRedis立てて置かなかったのが反省点。
17:50:44 <typester> w
17:50:53 <typester> そういえばredisブランチのローカルのうごか仕方を
17:50:57 <typester> 共有してなかったw
17:52:45 <fujiwara> このままこけなければ勝てる

二連覇

ということで去年に引き続き優勝させてもらうことができました。@fujiwaraの相変わらずのボトルネック発掘力と作戦立案力もさることながら、@typesterがあれだけの改造をしかもプロダクションレベルで通用するレベルで成し遂げてしまったことには驚きを禁じえません。

ホント間近で良い物を見せてもらいました。僕自身は不甲斐なくて悔しい部分もあります。

懇親会で@typesterに

「Songmuさんがいなかったら、あそこまで迷わずにredisブランチを立ちあげられなかった」

ということを言われて少しは救われた気になりました。

去年同様うれしさはありますが、去年以上に悔しさの大きい結果ではありました。引続き頑張って、@fujiwaraや@typesterとの差を埋めていきたい。

最終的なソースは以下にあるので、興味のある方は御覧ください。

https://github.com/kayac/isucon2

投稿者 Songmu : 00:33

2012年10月 2日

shipped Plack::Middleware::Auth::OAuth

Plack::Middleware::Auth::OAuthをリリースしたのでお知らせします。

https://metacpan.org/release/Plack-Middleware-Auth-OAuth

ソーシャルゲーム開発等、OAuthの署名検証が必要な場面では必須のモジュールかと思います。ご活用ください。

いきなりバージョンが0.03になっているのはこれまでCPANに上がっていなかった中で変更が加えられてきたからです。そもそもこれは@hidekさんがgithubにあげているもので、僕は一回pull reqを送ったくらいです。それを@hidekさんの許可を得て僕が代理でCPANに上げました。

このモジュールは社内で活用していたので、CPANにあげて欲しいなーと思っていたのですが、YAPCの前夜祭後の飲み会で@hidekさんに「上げてもらえませんか?」みたいな話をしたら「あれ、まだ上がってなかったんだっけ?じゃあ代わりにあげておいてよ」とか言われたので、ありがたくそうさせてもらうことにしました。

以前ちょっとTwitter上で打診した時には「まだちょっとドキュメントが不十分だから」とか渋られてしまった経緯があるのですが、直接「活用しているから上げて欲しい」と伝えたらOKをもらえたので、やっぱYAPCとかで直接会ってお話できると話が早くて良いですね。

色々わがままを聞いてくださって@hidekさんにはほんとうに感謝です。

あとは、Path::AttrRouterのドキュメントを@nihenさんが書いてCPANにあげてくだされば社内的にかなり捗るので期待したいところですね。

…他人任せですみません。

投稿者 Songmu : 14:46

2012年9月30日

YAPC::Asia Tokyo 2012とスピーカーデビューと

今年もYAPC::Asia Tokyo 2012終わりましたね。毎年のことながら、素晴らしい場を提供してくださっているスタッフの皆様には本当に感謝申し上げます。

前夜祭からひたすら飲み食いして、夜もさくら水産で大ジョッキ連発。初日は懇親会の後まで呑んだくれ。最終日も呑んだくれた挙句終電を逃しタクシーで帰宅するという非常に過酷な3日間でした。

今年の個人的なビッグニュースは間違いなくスピーカーデビューです。スライドは以下。

http://songmu.github.com/slides/yapcasia2012/start.html

しかしかなり緊張してしまってひどいもんでした。最初は足がガクガクしていて、かなり早口になってしまい、途中で持ち直したものの、25分程度で終わってしまいました。

結構話慣れていたつもりなんですがYAPCともなりますと全然違いますね。まあ、時間帯の関係もありたくさんの人に聞いていただけて非常に嬉しかったです。

事前に練習した感じだと

  • 40分を少しオーバーしていた。
  • 最後の方のスピリチュアルトークの途中で終わるのは嫌だった。

というのがあって最初は早めに話すつもりではあったのですが、あまりにも飛ばしすぎました。トーク後@fujiwaraに「緊張すると早口になるからそれを考えたほうが良いよ」とか言われてなるほどなーと。知らず知らずのうちに早口になってるのに、更に早く話そうとするとしどろもどろになるのは当たり前ですね…。

前半は初・中級者向けに、現状PerlでWeb開発する上での僕の思う「一般的な構成」のオーバービューを丁寧に話したかったのですが飛ばしたせいでちゃんと伝わってないかもしれないなーと残念な思いもあります。

色々反省点があるので来年頑張りたい。

あと、なんか「カジュアルにdisってる」とか何人かに言われましたが、disは多くの場合愛です。

今年は例年に比べると割とスピーカーの入れ替わりがあった印象で、多くの人の身の丈にあったトークの割合も取れていてバランスが良かったですね。

何よりLTThonは素晴らしかった。あそこまでみんながカジュアルに発表したいと思える雰囲気作りをしたのは本当に奇跡的ですね。多くの人がやろうとして挫折してきた雰囲気作りを完璧に実現していたと思います。

今年はスピーカーになった関係でチケットが余り、嫁に「来る?」と聞いたら「行く行く」と二つ返事。僕のトークも聞きに来てくれましたが、なにより、普段僕が話しているスーパースター達の話を直接聞けたのがかなり面白かったようです。

Perl今昔物語をメモを取りながら聞く真面目ぶりで、その後も「じゃ、次はdankogai見に行くから!」とかノリノリで僕を残して移動してました。

今も「来年も行くからスピーカーやってチケット余らせてね」とか言っております。

ということでYAPCは非エンジニアも楽しめる素晴らしいお祭りだということを身を持って実感いたしました。

投稿者 Songmu : 23:37

2012年9月23日

Jenkinsをカジュアルに5分で立てる

プロジェクトの共同開発サーバー兼CIサーバーみたいなところにJenkinsを立てることが多い。その場合、Jenkinsを立てるのはwarを起動するコマンドをdaemontoolsなりで管理するのがベタープラクティスかなーと思っている。

事前にやることはjavaを入れるのと、jenkins.warをwgetしておくだけ。

runスクリプトはこんな感じ。

#!/bin/sh
JENKINS_USER=app
JENKINS_HOME=/home/$JENKINS_USER/jenkins

exec 2>&1
exec setuidgid $JENKINS_USER \
    env JENKINS_USER=$JENKINS_USER
    env JENKINS_HOME=$JENKINS_HOME \
    java -jar $JENKINS_HOME/jenkins.war 
         --httpPort=3002 \
         --httpListenAddress=127.0.0.1

あとはNginxでプロキシさせたりする。

リポジトリ追加すればyum等のパッケージ管理システムでjenkinsを入れられるようになるけど、

  • /etc/init.d に入るのはなんか大げさ
  • 実行ユーザーもjenkinsユーザー固定になってしまう
  • WebUIの「自動アップグレード」が動かない(動くかも) (動いた。気のせいだった)

という感じなので個人的にはあまりおすすめしない。

war起動にすれば、

  • 一般ユーザー権限でカジュアルに実行可能
  • 「自動アップグレード」がカジュアルに利用可能
  • $HOME/jenkins で完結しているので可搬性があり、バックアップもしやすい

というメリットがある。

Jenkinsはごてごてしていて複雑でわかりにくそうで敬遠してしまう部分があるかもしれないけど、とりあえずこんな感じでカジュアルに立ててみて色々いじってみるのをおすすめします。

慣れてきたらjenkins-cliとか使って構成テンプレートとか作ってセットアップ自動化とかしてみれば良いんじゃないですかね。僕はまだやってないけど。

話は変わるけどhomebrewでさくっとdaemontoolsが入るのが便利。LaunchDaemonsとかよくわからないし、xmlとか書きたくない。

投稿者 Songmu : 00:59

2012年9月 7日

たとえばgetを避ける

プログラムでは複数の意味を持ちうる単語は避けるというのがある。noとかrightとかが良い例だ。個人的に最近はgetも気をつけたほうが良いと思っていて、メソッド名にgetを使いたくなったときは大体間違えている。

Javaなんかのgetter/setter的なやつは、オブジェクト指向以前のパラダイムの名残でしかないと思ってる。手続きの内容をメソッド名にしているという、手続き型のパラダイムを引きずっている感。

例えば、

user.get_money

みたいなコードがあった場合に、ユーザーがお金を獲得するのか、ユーザーの所持金額を取り出したいのかが分からない。オブジェクト指向的には前者が正しいのだけど、歴史的経緯から後者の意味合いで使わえる事が多い。プロパティの値を取り出すことが期待されてしまう。それが気持ち悪いので、getは極力使わないようにしている。

オブジェクト志向では、メソッド名はオブジェクトのやりたいことに即した命名にするべきで、プログラマーのやりたいことに即するわけではない。スピリチュアル的に言うと「オブジェクトの気持ちになる」ことが大事ですね!?

Javaとかだとプロパティとメソッドがはっきり分かれていて、プロパティは名詞、メソッドは動詞、みたいな感覚もあるんだと思う。だからproduct.priceに金額を代入しておくけどそれは直接使わずに、product.getPrice()で税込金額を返すみたいな処理が書かれてしまう。

プロパティをそのまま外部から使うようにしておくと、後で内部処理に変更があった場合に困るからメソッドでラップしておきべきだけど、メソッドは動詞にしておくべきとか、思考停止でgetXXXとかつけてしまうとかそんな理由だと思われる。

その点、Perlだとプロパティもメソッドも全部関数だから、シンプルな分柔軟なのかな、とか思う。

ちなみに、どうしてもgetを使いたくて代替案も思いつかない場合はretrieveを使うようにしている。あとはcurrentとかも便利な単語ですね。

てことで、とにかくgetをプログラム内で使うのは避けましょう。

投稿者 Songmu : 01:20

grepのかわりにperlを使おう

ackを使うと良いと思います。perlで書かれていてperlの正規表現を使えるから最高ですね(これしか言ってない)。.ackrcとか作れば自分好みの設定もできます。

実際のところ、.svnとか.gitとかバイナリファイルをスルーしてくれるから高速に動作しますが、大きなログファイルを絞り込むとかそういう場合は、grepの方が多分高速なんで使い分け重要。

投稿者 Songmu : 00:27

sedのかわりにperlを使おう

あのmoriyoshiさんもこんなこと言ってます。

https://twitter.com/moriyoshit/status/184241026028941314

sed -i より perl -i -pe を覚えた方がきっと有益でしょう。

% perl -i -pe 's/hoge/fuga/g' **/*.mt

とかやれば一括置換ができます。perlの正規表現が使えるから最高です。

大体これをやってgit diffで差分を確認して、まずったらgit reset —hardという運用になっております。

投稿者 Songmu : 00:24

2012年9月 4日

エディタ編集したファイルを整形してPocketIOでリアルタイムプレビュー

すぎゃーんが以前書いてるやつを参考にさせてもらってとりあえず適当に書いてみた。

% perl md_preview.pl markdown.md

とかやってhttp://localhost:5000/にアクセスするとリアルタイムプレビューできるはず。

Text::Markup::Anyを使っていて、

% perl md_preview.pl xatena.txt --markup=Xatena

とかやればText::Xatenaでも試せます。

Text::Markup::Anyの使いドコロみたいなのをなんとなく示したかった。

投稿者 Songmu : 02:15

軽量マークアップ記法を使い分けたいあなたのためにText::Markup::AnyをCPANに上げた

Markdownはシンプルな分、拡張実装が乱立している。他にも軽量マークアップ言語(とか言うらしい)は数多くある。

人によって好みもあるので差し替えたりとかできると嬉しいんじゃないかと思ってText::Markup::Anyというものを書いた。

使い方は簡単。以下SYNOPSISまんま。

use Text::Markup::Any;

# OO Interface
my $md = Text::Markup::Any->new('Text::Markdown');
my $html = $md->markup('# hoge'); # <h1>hoge</h1>

# Functional Interface
my $tx = markupper 'Textile'; # snip 'Text::' in functional inteface.
my $html = $tx->markup('h1. hoge'); # <h1>hoge</h1>

Functional Interfaceと言うよりかはSyntax sugarの提供ですね。以下2行は同じ意味になります。

my $md = Text::Markup::Any->new('Text::Xatena');
my $md = markupper 'Xatena';

現状対応してるモジュールは以下のとおり。

  • Text::Markdown
  • Text::MultiMarkdown
  • Text::Markdown::Discount
  • Text::Markdown::GitHubAPI
  • Text::Xatena
  • Text::Textile

投稿者 Songmu : 02:10

2012年9月 3日

Text:Markdown::GitHubAPI書いてみた

githubのmarkdown rendering APIの話をちょくちょく聞くのでPerlから使うやつを書いた。

https://github.com/Songmu/p5-Text-Markdown-GitHubAPI

使い方は、Text::Markdownとかとほとんど同じです。これでgithubのmarkdownがお手元でも!

微妙にCache::LRUとか使って頑張っちゃってる。なんで最近こんなMarkdown期なのか自分でもわからない。

そういや、Plack::App::Directory::MarkdownはyusukebeがYomicoっていう同じようなのをだいぶ前に書いてた。

投稿者 Songmu : 15:46

2012年8月28日

Plack::App::Directory::Markdownその後

0.02出した。

  • Plack::App::DataSection に依存しつつコード整理
  • pad-markdown.pl という付属コマンドによるお手軽起動
  • Bootstrap 2.1.0 を入れてみたら色味が結構変わってびっくり

Changesそのままです。

「Plack::App::*ってname speceの割には盛り過ぎだから、単独ネームスペースにしたほうが良いのでは?」

とtypesterに言われてしまったので検討中。キラキラモジュールネーム!

これをベースにした、もうちょっと多機能で簡易WikiやBlog的にも使えるアプリケーションの構想があるので、それを単独ネームスペースで出そうかと思っている。

投稿者 Songmu : 00:27

Plack::App::DataSection is released!

ちょっとしたpsgiアプリを公開するときに、画面の体裁をCSS等で軽く整えたいと思うことがあると思います。そういう時に静的ファイルをどのように配信するかが悩ましいところです。

そこで、ディレクトリの中身をモジュールファイルのDataSctionにpackしてそれを簡単にpsgiアプリとして使えるようにPlack::App::DataSectionというものを公開しました。

使い方は簡単です。cpanmした後、以下の様なファイルを準備してください。

package MyApp;
use strict;
use warnings;
use parent 'Plack::App::DataSection';
1;
__DATA__
@@ index.txt
あいうえお

このファイルを保存すれば以下のように利用可能です。簡単ですね。

% plackup -MMyApp -e 'MyApp->new->to_app' &
% curl http://localhost:5000/index.txt
あいうえお

もちろん、このようなファイルをちまちま作るのは現実的じゃないので、生成するスクリプトを用意しています。以下のようにすれば、ディレクトリの内容をモジュールへとpackしてくれます。

% dir2data-section.pl --dir=static/ --module=MyApp

バイナリはbase64形式でDataSectionに突っ込むようになっているので、画像も配信できます。

MyApp->new->dump_dir('static');

などとすれば、ディレクトリに書き戻すこともできるので、ちょっとしたひな形作成にも使えるかもしれません。

Plack::App::Directory::Markdown::Staticで利用しているので、中身を見てもらえればどういうことをしているかが分かると思います。jQury, Twitter Bootastrap, Google code prettify等の静的ファイルをガツっとpackしています。

それを、Plack::BuilderをつかってmountしてやることでJS,CSS等のファイル配信を実現しています。以下、Plack::App::Directory::Markdownから引用。

sub to_app {
    my $self = shift;

    my $app = $self->SUPER::to_app;
    my $static_app = Plack::App::Directory::Markdown::Static->new->to_app;

    builder {
        mount '/_static' => $static_app,
        mount '/'        => $app,
    };
}

ちなみに、MIME typeからバイナリ判定をしているis_binaryメソッドが適当な感じなので、何か良いモジュールがあれば使いたいところだけど、ニーズが無さそうな割にはメンテナンスがめんどくさそうなので自分では書きたくない。

投稿者 Songmu : 00:22

2012年8月21日

Plack::App::Directory::Markdownが便利な件

https://metacpan.org/release/Plack-App-Directory-Markdown

自作自演乙。

意識の高いエンジニアの皆さんなら、markdown形式でメモを残しているんじゃないでしょうか。

plackup -MPlack::App::Directory::Markdown -e 'Plack::App::Directory::Markdown->new->to_app'

のような感じで、ディレクトリ内のmarkdownファイルの一覧を出してくれるとともに、markdownファイルはhtmlに変換して出力してくれます。皆さんが見飽きたBootstrapデザインになっております。

padm とかでalias作るときっと楽ですね。

alias padm="plackup -MPlack::App::Directory::Markdown \
       -e 'Plack::App::Directory::Markdown->new->to_app'"

コンストラクタにmarkdown_classを渡せるようになっているのがちょっとしたおしゃれポイントです。Text::Markdownがデフォルトです。こんな仕様にしたのは個人的にText::Markdown::Discountを使いたかったってのが大きな理由です。

DiscountはCで書かれたMarkdown実装+拡張で、割と精力的に開発がおこなわれており、Perl、Python、Ruby、Lua、Haskell等のあらゆる言語のバインディングもあるので面白いんじゃないでしょうか。微妙な記法もありますが、github flavored markdownやPHP Markdown Extraの記法なんかも鋭意取り入れているようです。ググラビリティが低くて困ります。

また、Dataセクション内のデフォルトのXslateテンプレートが気に喰わない場合はtx_pathにテンプレートのパスを渡すことで差し替えることが可能です。その場合index.tx、md.txの2つのテンプレートを用意してください。

Xslateがpathにhashrefでファイルのマップを渡せるようになっているので、こういうふうに簡単にテンプレートを上書きできる仕組みが作れて、Xslateマジ便利ですね。

XslateのData::Section::Simple連携の仕組みに関してはgfxのエントリにも書いてありますが、@tokuhiromに教えてもらいました。tokuhirom++

ちなみに、使われているCSSやJS、画像等はPlack::App::Directory::Markdown::StaticというファイルのDataSectioにpackされており、それをPATHに応じて返する作りになっています。こういうちょっとしたアプリケーションを配布するときにこの仕組みは便利なんじゃないかと思って、もうちょっと汎用化してからまたCPANに上げるかもしれません。

投稿者 Songmu : 01:36

2012年8月14日

そういえばYAPCのチケットうってるらしいですよ

http://yapcasia.org/2012/talk/show/1cc88df4-da3a-11e1-b11f-0d4e6aeab6a4

僕もしゃべります。

なんというか、一言で言うと
YAPCで僕のトークをみにきてください。本物の中規模開発とはどういう物かお見せしますよ
というかんじです。

ちょっとした小ネタも用意してあります。
Perlなスピリチュアルトークに興味ある人もみにきた方がいいです。

(参考) http://blog.64p.org/entry/2012/08/14/191118

投稿者 Songmu : 19:24

2012年7月28日

awkの代わりにperlを使おう

perlのコマンドラインオプションには-aってのがあります。これはawkモードです。perl --help見るとautosplit modeとか書いてありますが。

perlは-pや-nオプションを渡す事によってファイルを一行づつ処理してくれますが、その時に-aオプションを渡すと@F配列にフィールドの情報を自動的に入れてくれます。

フィールドのセパレータはデフォルトではスペースですが、-Fオプションで指定可能です。

カンマ区切りのテキストの、最初のフィールドだけを表示したい場合は以下の様な感じ。

% cat test.txt
server1,1343363124,30,/video.php
server2,1343363110,20,/profile.php
server3,1343363115,7,/login.php
server1,1343363105,8,/profile.php
% perl -aF, -nE 'say$F[0]' test.txt
server1
server2
server3
server1

awkでは$1,$2..にフィールドが入りますが、perlでは$F[0],$F[1]...に入ります。

行毎の処理をperlの文法で書けるので、僕はawk使わないでperl使うことにしています。僕がシェル力が足りないのもあって、なるべくperlでやりたい派。

てことで以下の問にも答えてみます。現実的に自分がやりそうな方法と、無理やりperlワンライナーやった方法を載せます。自分がperlでしかやらないなーってのはperlの方法だけ。

http://d.hatena.ne.jp/Yamashiro0217/20120727/1343371036

問1

% cat test.txt
% perl -pe '' test.txt

問2

% perl -aF, -pe '$_="$F[0],$F[3]"' test.txt

問3

% cat test.txt | grep ^server4
% perl -ne '/^server4/&&print' test.txt

問4

% cat test.txt | wc -l
% perl -ne 'eof&&print$.' test.txt

問5

% cat test.txt | sort -t',' -k1,1 -k3,3n | head -5
% perl -e 'print for map{join ",",@$_}sort{$a->[0]cmp$b->[0]||$a->[2]<=>$b->[2]}map{[split /,/, $_]}<>;' test.txt

問6

% cat test.txt | sort | uniq | wc -l
% perl -nE '!$m{$_}++&&$n++;eof&&say$n' test.txt

問7

% cat test.txt | cut -f3 -d, | sort | uniq | wc -l
% perl -aF, -nE '!$m{$F[2]}++&&$n++;eof&&say$n' test.txt

問8

% cat test.txt | cut -f4 -d, | sort | uniq -c | sort -nr | head -1
% perl -aF, -nle '$m{$F[3]}++;eof&&print join" ",@{(sort{$b->[0]<=>$a->[0]}map{[$m{$_},$_]}keys%m)[0]}' test.txt

問9

% perl -aF, -ple '$_=$F[0];s/server/xxx/' test.txt | sort | uniq -c
% perl -aF, -nlE '$_=$F[0];s/server/xxx/;$m{$_}++;eof&&say for map{"$m{$_} $_"}sort keys%m' test.txt

問10

% perl -aF, -nlE '$F[2]>9&&say$F[2]' test.txt | sort -n | uniq
% perl -aF, -nlE '$F[2]>9&&$m{$F[2]}++;eof&&say for sort keys%m' test.txt

投稿者 Songmu : 16:46 | トラックバック

2012年6月17日

DBIx::CSVDumperっての作った

DBIx::CSVDumper

SQLの結果をそのままCSVで出力したいと思って作った。使い方はSynopsisまんまだけどこんな感じ。

use DBIx::CSVDumper;
my $dbh = DBI->connect(...);
my $dumper = DBIx::CSVDumper->new(
    encoding    => 'cp932', # 出力エンコーディング(デフォルト: utf-8)
);
my $sth = $dbh->prepare('SELECT * FROM item');
$sth->execute; # プレースホルダーなければ省略可能
$dumper->dump(
    sth     => $sth,
    file    => 'tmp/item.csv',
    #fh     => $fh # ファイルハンドル渡したりも出来る
);

別にシェルでゴニョればできるしPerlでやる必要はなさそうなんだけど、Excelで食えるCSVを出力したいとかそういう大人の事情があったので、カッとなってモジュールを書いた次第。

あんまPerl環境が整ってない環境(Windows機とか)でもサクッと使えれば良いなと思っているので、Text::CSVくらいにしか依存しておりません。Text::CSV_XSが入っていればそちらを良しなに使ってくれたりします。

最初はいろいろな形式にダンプ出来るとか壮大なこと考えてたけど、とりあえずCSVだけで良いやとか考えなおしてこんな感じになりました。ちなむとText::CSV(_XS)?使ってるので、それで出せる形式であれば出力可能です。TSVとか。

DBIx::DumpってのがCPANにあったのですが、ちょっと古くてマルチバイト対応が怪しかったりしたので別のを作りました。インターフェースはなんとなく似た感じになっております。

もうちょっと整えてCPANに上げるかもね。

投稿者 Songmu : 23:06

2012年5月28日

WindowsとVMWare開発においてpbcopy的なやつ

僕は最近のWeb開発者にしては珍しくメインマシンがWindowsで、開発は全てVMWareのLinuxにputtyで繋いでやっています。

そうなると、やっぱクリップボードと連携したいとかそういう時があります。screenのペーストバッファをWindowsでも使いたいとか。

これまではマウスで選択して貼り付けてとかやってたんですが、screen縦分割とかしてると矩形選択モードに切り替えないといけないけどやり方忘れたりするし、何よりダサい。

Macにはpbcopy/pbpasteという便利なコマンドがあり、それと同じようなことが出来れば万事解決です。

解決策は簡単で、WindowsとVMは普通にTCP通信ができる(当たり前!)ので、Windows側にサーバーを立てて、クリップボードの読み書きが出来るAPIを提供すれば良い。

僕はWeb屋でPerl屋なので、plackでHTTPサーバー立てて、REST APIを提供するのが楽。

てことで作りました。

WinPB

Windows側のどこかに適当に落としてきて、winpb.batをダブルクリックするだけでとりあえず動くと思います。(動作にはPerlとPlackとRouter::Simpleが必要で、app.psgiをそのまま使う場合は、Plack::Middleware::Auth::QueryStringも必要です。)

上手いこと、起動したら、以下にアクセスしてみてください。

http://localhost:52225/?key=change_on_install

クリップボードの中身が見えたら成功です。

とりあえずそのままだと危険なので、タスクマネージャーからwperl.exeのプロセスを探して停止して下さい。

config.plを設定して認証keyの設定をしたり、plackupの引数で、VM用のnat側のIPアドレスしかlistenしないようにするなどすると良いでしょう。ひととおり設定したら、もう一度、winpb.batを起動。念のためブラウザでも確認してみて、OKならばスタートアップにも登録しておくと良いでしょう。

Windows側の設定は以上です。

あとは、VM側のLinuxの設定ですが、以下の様なスクリプトをパスの通ったところに置いておくと良いと思います。単にcurl使ってるだけです。

pbcopy

#!/bin/sh
. ~/.pbcopyrc
if [ -p /dev/stdin ];then
  PASTE=`cat -`
else
  echo 'usage: echo "hoge" | pbcopy';exit
fi
curl --silent http://$PBHOST/?key="$PBKEY" --data-urlencode "pb=$PASTE" > /dev/null

pbpaste

#!/bin/sh
. ~/.pbcopyrc
curl --silent http://$PBHOST/?key="$PBKEY"

設定ファイル~/.pbcopyrcに変数PBHOSTとPBKEYの設定をしています。

ちなみに、curlの--data-urlencodeオプションはPOSTデータをurlencodeしてくれる便利なオプションですが最近のcurlにしかないようです。CentOS5.5に入れようとしたら依存ライブラリ等の解決が色々めんどかったので、別途urlencodeしたりしました。

$ echo hoge | pbcopy

とかやって、ちゃんとWindowsのクリップボードにhogeが反映されるのを確認したら、以下のように.screenrcに追記すれば Esc-pでスクリーンのペーストバッファがクリップボードに入るようになって胸熱です。

bufferfile '.screen-exchange-file'
bind p eval 'writebuf' 'exec sh -c "cat .screen-exchange-file | pbcopy"' 'echo "paste to remote"'

すごく簡単な話です。なんで最近まで思いつかなかったのか。これまでWindows側にサーバーを立てるとかそういう発想があまりなかった。

ちなみに、Win32::ClipboardのUnicode対応がイケてなくて、残念ながらcp932領域の文字列しかWindows側に送ることができません。逆にWindows側でコピーしたUnicodeテキストはちゃんとutf8で取得できるようになっています。

投稿者 Songmu : 00:17

2012年5月27日

Plack::Middleware::Auth::QueryString

http://search.cpan.org/~songmu/Plack-Middleware-Auth-QueryString-0.01/

http://example.com/?key=yourpasswordhere 的な認証を提供するミドルウェアです。

当然Publicなサービスでは使いものにならない(使ってはいけない!)ですが、ローカルに通信用のHTTPサーバー立てた時に気分的に適当にちょっとした認証をかけたい時に使うと良いと思います。

基本的な使い方はSYNOPSISにも書いてありますが、passwordのマッチングはスマートマッチを使っているため、Array Referenceやサブルーチンを受け付けることが可能です。

enable "Auth::QueryString", password => [qw/passa passb passc/];
enable "Auth::QueryString", password => sub {
   ...
};

スマートマッチを使っていることから分かるように、perl5.10.0以降でしか動かない適当モジュールです。OAuth2の最後の部分だけを切り出したとも言えます。

実際、スマートマッチはこういう用途にすごく向いているし、そこを狙って仕組みでもあるんだろうけど、正直理解しきれないし、false value絡みで意図せぬ挙動も多いので、配列の存在チェックくらいにしか使わないのが賢明でしょう。

あと、cpantestersでv5.16.0 RC0のテストがこけていて謎い...。

投稿者 Songmu : 23:46

シェルスクリプトで標準入力をパイプ経由でのみ受け付ける

ファイル演算子 -p を使って、標準入力がパイプ経由かどうかで調べることが出来る。`cat -`で標準入力をそのまま飲み込むことが可能。

#!/bin/sh
if [[ -p /dev/stdin ]];then
  VAR=`cat -`
else
  echo 'usage: echo "hoge" | command';exit
fi
echo $VAR

投稿者 Songmu : 23:30

Windows上でdos窓開かずにPerlプログラムを実行する方法

定期的に実行するスクリプトが起動した時に一瞬Dos窓が開いたり、常駐プロセスでDos窓が開きっぱなしになってしまうのを回避する。

ActivePerlだとwperl.exeってのが同梱されているので、それ経由でperlスクリプトを実行すれば良い。plackupも可能なので適当なサーバープロセスを立てたい時に重宝する。

wperlで起動したプロセスを止めたい時は、タスクマネージャーのプロセス一覧からwperlを探して停止するしか無いと思う。

ちなみに、psgiアプリをWindows起動時に起動させたい場合は、以下の様に記述したbatファイルをpsgiファイルが置いてあるディレクトリに準備して、そのショートカットをスタートアップに登録しておけば良い。

start C:\Perl64\bin\wperl.exe \Perl64\site\bin\plackup

最近はWindowsでもカジュアルにplackupできるので胸熱ですね。あんまそういう発想がなかったんですが、実はWindwos側に色々立てておけばVMとのやりとりが色々捗る。

投稿者 Songmu : 23:22

2012年5月26日

perlbrewのperlをrsyncでばら撒くときの注意点

結論:なにも考えずに--updateオプションをつけているとハマる。--updateは付けちゃダメ!絶対!

perlbrewでインストールしたPerlをrsyncでばら撒くという運用をしているところは多いと思うんですけど、そこで最近一点ハマりました。

cpanモジュールをインストールした時にpmファイルのタイムスタンプは、tar ballの中身のファイルのタイムスタンプがそのまま保持されています。

ただし、コアモジュールのタイムスタンプはPerlインストール時のものになります。

そして、コアモジュールをupgradeした場合は、タイムスタンプはtar ballの中身のタイムスタンプになるので、タイムスタンプが古くなります。以下例。

$ perl -MTime::Piece\ 999
Time::Piece version 999 required--this is only version 1.15_01.
BEGIN failed--compilation aborted.
$ ls -l Time/Piece.pm
-r--r--r--  1 app app 22729 May 10 15:00 Time/Piece.pm # <- 今年の5月10日
$ cpanm Time::Piece
...
$ perl -MTime::Piece\ 999
Time::Piece version 999 required--this is only version 1.20.
BEGIN failed--compilation aborted.
$ ls -l Time/Piece.pm
-r--r--r--  1 app app 23506 Mar 17  2010 Piece.pm      # <- 2010年!?

つまり、5月10日にインストールしたPerlのTime/Piece.pmのタイムスタンプはその時のものになってるんですけど、cpanmでupgradeしたら、2010年のタイムスタンプになってしまいます。

これは、一台で動かす分には特に問題は起きません。

ただ、別のサーバーにrsyncをかけているような場合に、--updateオプションを有効にしてると、タイムスタンプが古いファイルは転送されないという困った事態が起こりえます。

なので、perlbrewのperlをrsyncする場合は--updateオプションは付けないようにしましょう。

ちなみにArcher::Plugin::Rsyncだと、updateオプションがデフォルト有効になっているのでハマりました。

投稿者 Songmu : 15:24

Kyoto Tycoonでmemcachedプロトコルの圧縮オプションを有効にすると捗る

最近、セッションストレージはKyoto Tycoonを使っています。ゲームだとFlash生成時の情報をセッションに突っ込んだりするので、セッションデータが大きくなりがちです。それをユーザーごとに頻繁にGet/Setされると結構バカにならないトラフィックになったりulogがすごい勢いで溜まったりします。

Kyoto Tycoonはmemcachedプロトコルで使うことが多いでしょう。実はmemcachedプロトコルには、データを圧縮して通信するオプションがあり、Kyoto Tycoonでもそれを使うことが可能です。

Cache::Memcached::Fastだとこんな感じで指定できます。

my $kt = Cache::Memcached::Fast->new({
    servers   => [...],
    compress_threshold => 500,
    compress_ratio     => 0.9,
});

この例だと500byte以上のデータを圧縮してくれます。ただし、圧縮してもデータサイズが90%以下にならない圧縮効果が薄いデータは圧縮しないという設定です。

凄いのが圧縮・非圧縮のデータが混在しても大丈夫だということ。つまり、既に稼働しているKyoto Tycoonに対して、途中から圧縮を有効にすることが可能なのです!

実際、某サービスで途中から圧縮オプションを有効にして問題なく稼働しております。

この辺の情報は全て@fujiwaraに教えてもらったもので、基本的にfujiwara無双であります。

投稿者 Songmu : 15:21

2012年5月 3日

GWに読むと良い技術書4冊という釣りタイトル

有隣堂ヨドバシAkibaで「IT・WEB業界に入るならこれを読んでおいて損はない!」という技術評論社の特選フェアをやっています。同僚のtypesterが推薦した本も並んでいますので、興味のある方は行ってみると良いと思います。僕も行きたいです。

その流れで弊社のエンジニア陣でも4冊推薦図書を出してみようという話の振りがあり、僕も4冊出してみたのですが、それをここにも載せておこうと思います。

珠玉のプログラミング(Programming Pearls)

"Programing Perl"のタイトルの元ネタ。ソートや2分探索などの基礎的なアルゴリズム等、コード例を交えて分かりやすく面白い。

アルゴリズム入門書と思いきや、奥の深い一冊。

リファクタリング・ウェットウェア ―達人プログラマーの思考法と学習法

ご存知「達人プログラマー」著者による一冊。「脳」のことを「ウェットウェア」と呼び認知科学や神経科学の領域にまで言及。

如何に効率良く達人プログラマとなるか、より実践的に踏み込んだ一冊。

まつもとゆきひろコードの世界

表紙があれだが何気に良書。

オブジェクト指向・デザパタ・JavaScriptとWebプログラミング・Ruby・正規表現・文字コード・正規表現・セキュリティ・関数型言語等のトピックに分かれ、広く・深めに網羅されている。

教養書として若手に読ませたい一冊。

心の社会

人工知能の大御所、MITの人工知能研究所設立者マーヴィン・ミンスキーによる、心と人工知能に関する考察が書かれた読み物。

細かいプロセス(エージェント)が相互作用することにより心が生じるという考え方。つまり「心はプログラミング可能」だと論じている。

あまりに衝撃的な内容だったため「コンピュータには何ができないか―哲学的人工知能批判」という反論書まで出版された。(これも名書)

自己考察やそのプログラム可能性にまで踏み込んだ、ぞくぞくするような一冊。


次点は以下。

   


投稿者 Songmu : 16:23

2012年4月24日

PerlのIdiomをCPANモジュールを使って可読性を高くしてみる

今年からKayac技術部では以前以上にPerlを推進する方向で進めています。そんな中でこれまでPerlを書いたことのないエンジニアにもPerlを書いてもらうことも多くなってきたのですが、PerlのIdiomがやはりわかりづらいんだなぁということを感じています。

割りとサクッとやっつけでコードを書くことが出来るのもPerlの良い点ですが、まあ分かりづらいよね...、と言うことで最近はPerlに慣れない人に対しても可読性が高くなるように多少心がけています。

てことで、PerlのIdiomとそれを読みやすくしたものを幾つか。

ファイル一気読み

こんな感じで書いてしまうことが多いと思います。 use autodie; も併用することが多いので、or dieとかも書かない感じ。

my $content = do {local $/; open my $fh,'<:utf8',$file_name;<$fh>}

細かい解説はさておき、このコードをわかりやすく書きなおすと以下のようになります。

use Path::Class qw/file/;
my $content = file($filename)->slurp(iomode => '<:utf8');

ファイル一気読みは、Perl6::SlurpだったりFile::Slurpだったりもありますが、Path::Classを使っておいたほうが何かと捗るので、Path::Classの使い方を覚えるついでに一気読みのやり方も押さえておくと良いと思います。

Perlのファイル操作は何かと初学者にはハマりどころなので、素直にPath::Classを使ってもらった方が良いんじゃないかと感じています。OS等アーキテクチャの違いも吸収してくれますし。以下の様な感じでファイル操作ができるので良いですね。

my $fh = file($filename)->open('>:utf8');
$fh->print('hoge');
$fh->close;

間接オブジェクト記法とか使ってもらわずに済むので良いですね。

一秒以下のsleep

Perlの標準のsleepは秒数を指定するようになっていて、1秒以下のsleepには対応していないという若干残念な部分があります。そんな時には以下のようなコードを書くことがあるでしょう。

select undef, undef, undef, 0.5;

これはあんま良くない感じがしますね。undefいくつ書くのかよくわからなくなることもあるので、素直にTime::HiResを使うと良いと思います。

use Time::HiRes qw/sleep/;
sleep 0.5;

出力のバッファリングを抑止する

local $| = 1;

古のCGIやバッチ処理なんかに書かれているのを見かけます。というか書いています。これは、標準出力のバッファリングを抑止するためのものです。

$|とかよくわからないし、selectを組み合わせて標準出力以外のバッファリングを抑止することもできるのですが、さらに面倒くさくて覚えれられません。

そんな時はIO::Handleのautoflushメソッドを使うと良いでしょう。

use IO::Handle;
STDOUT->autoflush;
STDERR->autoflush;
$fh->autoflush;

可読性も上がって素晴らしいですね。また、use IO::Handleすると、$fh->print('hoge')とか書けるようにもなって間接オブジェクト記法を避けられるのも密かなメリットです。

エラー処理

$@を使うというのは結構知られているとは思いますが、実際ちゃんとやろうとすると、$@がグローバルだったりするのでlocalしておいたほうが安全とか色々あります。

my $err = do {local $@; eval {
    ...
}; $@};
if ($err) {
    ...
}

こんな感じでごちゃごちゃ書くのはめんどくさいので、多少ハマりどころはありますが、Try::Tinyを使うのが良いかと思います。

use Try::Tiny;
try {
    ...
}
catch {
    ...
};

ただ、Try::Tinyは中身の動作を理解して使わないと危険です。詳しくはとある言語の例外処理 またはTry::Tinyの落とし穴 辺りを読んでいただくとして、それも読むのがめんどくさいという場合は、tryやcatchのブロック(厳密にはブロックではない)の中でreturnは呼んじゃダメよ、絶対、ということだけは押さえておいてください。


ちなみにPerlは特殊変数が多くて大変とか言われますが、% perldoc perlvarすれば全部出てくるんで、簡単に調べられます。

投稿者 Songmu : 01:32

2011年12月31日

最近書いたPerlモジュールとかパッチとか

12月頭頃は、今年関わった案件を振り返って、共有できそうな部分をコード化したりとかしていた。そういう下回りを整備するような作業は割と好き。

その中で一応公開できそうなやつとかを以下に記す。

Encode::JP::Mobile::UnicodeEmoji

iOS5から絵文字がUnicode絵文字になってたりとかAndroid対応とかでUnicode絵文字対応がちょっと必要になって書いた。

昔はUnicode絵文字とか無かったのでEncode::JP::MobileはUnicode私用領域に絵文字をマッピングする仕様になってますが、Unicode絵文字領域の文字をそのEncode::JP::Mobileの私用領域にマッピングしてしまうという後ろ向きモジュール。

絵文字はEncode::JP::Mobileの私用領域のレンジでDBに保存しているとか言うことも多いので、そういうサービスでスマホにも対応させる場合、Unicode絵文字も同様の対応を取らざるを得ないこともあり、その変換をするためのモジュールです。

一応動きますが、実装は超適当です。ちゃんとしたマッピングを書いているわけではなく、Encode::JP::EmojiとEncode::JP::Mobileの合わせ技で無理やり実現しているという...。Fallbackとかもよく分からなかったんで指定していません!(キリッ

なので、現状githubのみ。

HTTP::MobileAgent::Plugin::SmartPhone

HTTP::MobileAgentにis_iosとかis_smartphoneとかそういうメソッドを生やしたかったので書いた。

これも一応動きますが、正規表現直書き判定でメンテナンス性とかを考えてないので駄目な感じ。なので同様にgithubのみ。

Archer

これはpull req送って取り込んでもらった。

今年初めの方から、このパッチあてて使ってたんだけど、パッチ送ってなかったのは、File::Rsync のバージョンによって出る問題だかと思って深く追ってなかったからなんだけど、File::RsyncのChangelog見てみたら実はそんなこと無かったので、取り込んでもらった次第。
(File::Rsync::(?:err|out)が以前はString返していたのが、Arrayを返すようになったとか想像していたら、もともとArray(?:_ref)?を返していてそんなことはなかった。)

File::Rsync::(?:err|out)はコンテキストに応じてリストかarray_refかを返すようになっている。そうすると、スカラコンテキストだと常に真になってしまうという問題があって(空のarray_refは真)、if () = $rsync->out;とかやって無理やりリストコンテキストで返すようにしている。カッコ悪い。

Archerは超便利に使わせてもらってるんだけど、情報が少ないし、まだ使いきれてない感があるから、もうちょっと知見を貯めていきたい。

割と弊社では活用されていますが、バラバラに使っていて知見が共有できておりません。

Plugin::ConfirmがPerl5.14では上手く動かない問題なんかもあるから、ちょっと手を入れてみようかな。

ちなみに、ArcherのwatcherがAuthor除くと弊社社員だけで吹いた。

投稿者 Songmu : 21:19

2011年11月 5日

Wiki記法的なものとか文書管理とかに思うこと

Wiki記法的なものとか文書管理とかに思うこと

最近社内向けのドキュメント書いてたりもするので、かねがね思っていたことを書く。かなり与太話。

文書管理とかについて思うこと

文書くときって使い慣れたローカルのエディタで編集したいじゃないですか。長いBlogを書くときって、結局ローカルで書いたのをテキストエリアに貼り付けて、みたいにやっている人は多いと思うんですよ。僕はそうしてます。

BlogにせよWikiにせよドキュメントにせよ、ローカルでテキストファイルを編集できて、バージョン管理して、リポジトリにコミットしたらサイト反映みたいになってると、楽だと思うんですよね。

複数人で編集するときにすごく効果を発揮するはず。Wikiとか編集が競合したらめんどくさいけど、今時のバージョン管理ツールなら上手いことマージしてくれたり、コンフリクトを検出できるし。

文書フォーマットをどうするかというと、LaTeXで書いてPDF出力してみたいな話もあると思うし、書籍を執筆するときなんかはそれで良いと思う。実際問題としてはHTMLに変換できる簡易マークアップ記法が良いんじゃないかと思っている。

HTML+CSSの表現力ってのはすごい

アウトラインを意識すれば文書を書くというレベルで不自由はない。アウトラインを意識せざるをえないってのがHTMLで文書を書く上で逆に良い点だと思う。print.css書けば印刷物としても十分耐えうる。レイアウトもかなり自由が効く。

実際、僕は職務経歴書はHTMLで管理している。「プログラマの職務経歴書なのに綺麗に整ってますね」とか良くわからない褒められ方をされたことがある。HTMLで書いたと言ったら非常に驚いていた。

書籍とかで目次や索引をつけてページ数との対応とかをやるとなると、ワープロソフトに軍配があがると思うけど、実際は逆にハイパーリンクを張れたほうが何かと便利。

ePubの議論も盛んになってきたので、HTMLを紙にした時の見え方やそれに関連するCSSプロパティの対応はだいぶ進んできている。例えば、少し前まで背景画像のサイズ指定ができない問題があったけどbackground-sizeに対応しているブラウザも増えてきた。

Wiki記法とか

ただ、HTMLを直で書くのはきついし、HTMLテキストは可読性も低い。HTMLで使う要素は限られているのだから簡易記法で書くのは理にかなっている。

Markdownはテキストファイルのままでも可読性が高いってのが優れている。

ただ、Wiki的記法に総じて言えることだが、簡易記法である分、HTML→記法の逆変換が難しいってのが問題点。あくまで簡易記法だからHTMLのすべてをまかなえるわけではない。

Markdownは直にタグを書けるようになっていて、Markdownでまかなえないことは自分でタグを書いて解決するという割り切った方針になっている。そして、Markdownが提供するシンタックスも最低限になっている。

その割り切りは好きなんだけど、シンタックスがちょっと最低限すぎるってのがある。ちょっと複雑なHTMLを書きたくなると、すぐにタグが入り交じって可読性が落ちる。やれることが最低限な分、独自拡張が乱立してるのも問題。

そして、タグを書けるようにしているってのは実装上かなり大変。Wikiパーサーはただでさえ処理の前後関係を整理するのが難しいのに、タグ直書きを実現するためにパーサーのコードはさらにカオスなことになっている。だから前後関係を崩さないように拡張するのも大変。

Markdownその他簡易マークアップ言語に不満な点

定義リストとテーブルは欲しい。

定義リストは議事録的なものをとるときに、質疑応答とか小テーマとそれに対する決定事項みたいなものを並べるときに使いたい。(議事録なんかをとるときに簡易マークアップ言語を使うのは、書式の統一がとれて良いと思う)

あと、ソフトウェアのドキュメンテーションとかやると、codeの他に出力やシェルプロンプトを出したいので、sampが書けるとうれしいよなぁと思う。

あと、そろそろHTML5対応した簡易マークアップ言語が欲しいと思うところ。

特にasideが欲しい。実際普通に文章を書いていて横道にそれた時とか、議事録なんかで本筋から外れた話を書くときに使いたいですね。

HTML5の目玉(?)である、セクショニングの頭でh1を使うみたいなのは、既存の基本でもバリバリやっちゃって良いと思う。

このへんの不満を解消すべく、KuaiWikiを書き始めた部分があるんだけど、色々コード的にイケてなさすぎるので、げんなりして開発が止まっている。それに結局こういうWiki記法ってのは使ってもらってなんぼですね。そういう意味ではてな記法は成功したと思う。

Sphinxは便利っぽいけどreSTがイマイチ

あくまで個人的な感想ですが、reSTはイマイチだと思う。

あと、SphinxはePub変換とかPDF変換とか謳ってるけど、ePubは所詮HTMLに辞書情報のXMLファイル付加してzipで固めただけだし、PDFもWkHtmlToPdfとか使えば、HTMLからPDF生成できるわけだからそんな特別な話では無い気がする。要は印刷を意識したprint.cssが書ければあとは自由自在。

HTMLとPDFとePubが出せれば他のフォーマットは特に必要ないだろうし、HTMLがあれば、PDFもePubも出せるのです。

リンクとかリソースとか

Wiki的なものを実現させようとするときに、ページ内リンクをどう実現するかってのは地味にめんどくさかったりする。(ページ名を変えたときのリンク張替えとか、マルチバイトのリソースをどう管理するかとか。ファイルとして保存する場合はファイル名を可搬性のある形でどう保存するかとか。)

数式とか

LaTeXで書けるようになってて、MathMLで出力される感じのシンタックスがあれば良いのかなぁ。MathMLどうなのかなぁ。今日のSugamoでも話題になってたけど。

図とか

blockdiagがすごすぎる。テキストファイルでUMLを記述して画像出力するという素晴らしさ。今後の継続開発に期待。

あとは、Cacooも素晴らしすぎる。前職で社内向にYapafiのドキュメント書いたときに使った。UMLの要素も揃っている。とかそういう話を今日のSugamoでも話が出た。

投稿者 Songmu : 23:57

2011年10月16日

YAPC::Asia Tokyo 2011

ありきたりで、毎回そして誰もが言うことですが、楽しかったし、刺激になった。

本当に運営の人はお疲れ様でした。毎年のことながら素晴らしいカンファレンスをありがとうございました。今年の運営はこれまでの経験が活かされていて、非常に洗練されていたと思います。

今年は話をしたかった人とかなり話せてすごくよかった。「交流しよう」というテーマに即して、全体的にすごく交流しやすい雰囲気を作り出していたと思う。深く考えていなかったけど「懇親会無料」ってのも、交流を促進させるための施策として素晴らしいものでしたね。それに、昼食の時間が取ってあったので、芝生で交流ができたのは非常によかった。

個人的にはブログやらTwitterやらISUCONやらで以前より名前や顔を覚えてもらえていることもあって、交流しやすかったというのもあります。勝手に後夜祭から帰途につくときに、「@lapis25 さんと話せなかったな」とか思っていたら、帰りの電車を待っているときに本人から声をかけていただけたのは感激でした。

まあ、そこまで有名になったわけでも無いのですが、実力に比べて若干名前先行の感があるのでもっと精進しないといけないな、と思います。

そして、Kamakura.pmで話した内容の焼き直しでも良いから、話しておけばよかったと少し後悔しています。年々トークのレベルが上がっているので、そろそろ話しておかないと置いていかれる一方だな、という感じがする。来年は話す。

印象に残ったトークとか

Perl 5.16 and beyond(Jesse Vincent)

Perlに対する誤解を解くだとかレガシーPerlがどうのみたいなことを言うフェーズは終わって、どんどんPerlを進化させていくというフェーズに入った。Perl自体をよりスリムに、ソースコードもリファクタリングしていく。

といった内容を話していたと思いますが、非常に力強いメッセージで、期待が持てました。

ORMに関する議論なんかで良く言われることですが、すわ関数呼び出しのコストが高いだとか、オブジェクト生成のコストが高いからといって、ハッシュばかり使うっていうのは、有効なのはわかりますが、バッドノウハウ以外の何者でもない。(DBICがオブジェクト作り過ぎなのは確かですが)

確かに、ハッシュはシリアライズもしやすいし、イチイチオブジェクトの流儀を覚えるよりも楽なことも多いのは確かですが、だからといって、ハッシュばかり使うのは他言語からしたらナンセンスに思えるのは確かだと思います。

そのあたりが、今後Perl自体のソースコードのリファクタリング次第で高速になっていくことを期待しますし、共通的なオブジェクトモデルがどうなっていくか気になるところです。


Mobage オープンプラットフォームの事件簿(Toru Yamaguchi)

モバゲーでサービスを作っていることもあって、Zigorouさんやriywoさんのトークも非常に自分にとって身近で興味が持てるネタでした。

特にZigorouさんのトークに関しては「ここまで話しちゃっていいんだ...」とかびっくりするような内容でした。

話していた障害の話は、自分が作っているサービスにもモロに影響がでたやつなんだけど、話を聞いてみると、規模は違えどこちらでも悩んでいるような話で、逆に親近感が湧くような話でした。

しかし、それらに対する解決策は目からウロコが落ちるような、でも真似したくないような驚くべき内容で、とはいえ発想の転換という点では非常に参考になりました。

初日の懇親会で、Zigorouさんとお話しましたが、「なんか欲しい機能とかありませんか」とか聞いてきてくださって、こちらが出した要望にも真剣に考えてくださって本当に嬉しかったです。

こういうエンジニアの横のつながりってのは、なかなか非エンジニアには理解しがたい部分でしょうね。

他者のエンジニアが弊社に遊びに来ることとかあるんですけど、「スパイかも知れないよ」とか冗談をいう人がいて、勿論冗談なんだけどそういう冗談が出てしまうのは非常に残念だなぁと思ったりすることもあるので。

あとは、riywoさんのトークでも、

  • 運用側にイベントの開始を伝えてない
  • 「リアルタイム」という言葉は特に危険

みたいなことを話していて「あるある」とか思いました。

Perlで構築された中規模サイトのDC引っ越し記録(FUJIWARA Shunichiro)

ベストスピーカー賞おめでとうございます。初日のほうが来場者が少ないし、投票を促されるのも二日目なので、二日目のトークが有利だと思われる中での勝利は見事としか言いようがありません。

弾座談会

トークじゃないけど、二日目の夕方にスウィーツエリアで日本と海外のハッカーたちによる座談会が行われていました。

そこではいつもは空気を読まない弾さんのファシリテート力に驚いた。それだけじゃなく、弾さんが途中で口を挟んでも、すかさずそれに口を挟み返す、みたいなことが頻繁に行われていて、「ああ、これが英語圏の会話なんだな」とか思いました。

スピーチとかはあるけど、英語の座談会的なものは初めて聞いたのは初めてだったので非常に面白かった。聞き取れた英語は3割くらい。


その他思ったこと。

ハッカー文化の啓蒙

こういうYAPCの雰囲気やハッカー文化的なものを、ビジネスサイドの人たちにも理解してもらうことは大事なのかなぁと思った。最後のhidekさんのトークを聞いてもDeNAなんかはそこにすごく成功しているんだと感じた。

自社のエンジニアの書いたコードが他社のサービスで動いているし、その逆もまた然り。そういう基本的なところからして、ビジネスサイドの人間はなかなか信じられなかったりする。

YAPCがビジネスビジネスしたイベントになるのはゴメンだけど、お金を出してもらうだけではなく、ビジネスサイドの人を引っ張ってくる努力もしたほうが良いんじゃないかと感じている。

今回はスポンサー枠みたいなのもあって、うちの管理部門の人もYAPCに来たりしたわけだけど、一人は「YAPCすごく楽しいですね!」と言っていた。そいつはなんでも本気で「楽しい」と言えるナイスな奴なので、逆に参考にはならないけど、そういうふうにYAPCの空気を非エンジニアに感じてもらうってのは重要なんじゃないかと思う。

キャリアとか家庭とか

Perl界隈は僕くらいの年代が多いと思うんだけど、家庭をどうするかに関して色々考えていている人が多いように感じました。JPA理事の牧さんも子供欲しいっておっしゃってますし。

刺身さん問題(僕しか言ってない)について刺身さんと話せたのも良かった。

一般的にWebエンジニアは家庭を大事にしますが、Webサービスは昼夜問わず対応しなければいけないことも多く、仕事との両立は頭の痛い問題です。

しかし、帰りの電車で、@lapis25さんも@kazeburoさんも「子供かわいいですよね」とかおっしゃっていて、非常に幸せな気持ちになりました。

てことで、Webエンジニアは結婚相手として非常におすすめですね。おすすめな理由はここでは語り切れないので、またの機会にあらためることにします。

投稿者 Songmu : 22:47

2011年8月28日

#isucon で優勝させてもらってきました

まずは、ライブドアの皆様、素晴らしいイベントの提供本当にありがとうございました。めちゃくちゃ楽しかったです。

Kayacのエンジニア3人 @fujiwara @sugyan @songmu の3人でチームfujiwara組を結成し、結果優勝することができました。

実際は周りの認識通り、@fujiwaraさんに優勝させてもらったようなもので、@sugyanと僕は手を動かしていただけです。まあ、空気にならずには済んだので、そこは安堵しています。

修正したisuconソースはフォークしてGithubに置きました。プログラムの修正部分のみで、my.cnfの修正なんかはここには反映されていません。

さて、@fujiwaraのコンテストでの動きや、帰宅後のBlogアップまであらゆる仕事が速くてビビるんですけど、詳しくは、#isucon で優勝してきましたを見てもらうとして、

  • どういうドタバタがあったのか
  • アプリの修正点とか
  • @fujiwara的には当たり前ですっ飛ばしてるけど僕には勉強になったこと

みたいなことを書きたいと思います。結果としては圧勝みたいになっていますが、かなり危うい部分や、苦肉の策なんかがあります。

事前作戦会議とか

前日のランチで軽く雑談。

とはいえ話したのは、「リバースプロキシはnginxにするでしょう」「memcachedはどこかで活用するんでしょうね」くらいの話。あんま変なモノは使わず、使い慣れている環境を使いましょう。あとは出たとこ勝負という話。

当日の役割分担

当日の役割分担は自然と決まって、作戦決定とOS・ミドルウェアの設定周りを@fujiwaraが担当して、それに従って@sugyanと僕が手を動かすという感じになりました。

初期設定とか 11:30-

まずはSSH周りの設定。authorized_keysにそれぞれ自分の鍵書き込んだり、hostnameの設定したり。rev(リバースプロキシ)を踏み台にして、他のサーバーに入る方針。

あとは、revにもアプリが入っていたので、そこでgit init。by @sugyan。それをローカルに落としてきて開発ってつもりだったんだけど、最後はサーバー上で開発になってました。

デプロイに関しては、revからappサーバー2台に、rsync -> SSHリモートコマンドでsupervisord再起動 みたいな簡単なシェルを書いた。(簡単なとか言いつつ、結構調べちゃいましたけどね!) by 僕

@fujiwara 組長にhostname等の設定をしてもらっている間に、アプリをざっと眺める。シンプルで綺麗。生DBIでテンプレートもxslate。こりゃPerlモジュールレベルじゃ全然高速化の余地はないなと、自分が空気にならないか心配になる。

PerlはSystem Perl。置き換えても良いかもしれないけど、他にやることはあるでしょう。MySQLが5.5だったのはスゲー意外。4.0とか覚悟してたんだけどw

チャットは社内IRC。チャンネル作ることも考えたけど、普段使っているチャンネルに。そっちのほうが社内の他のエンジニアへの実況になって面白いかな、とも。

最初の計測 12:30-

各サーバーでtop回しながらベンチマークスクリプト走らせる。まずは何はともあれこれ。スコアは800/min程度。

MySQLがネックになっていることが判明したので、今度はクエリログ眺めながらベンチマーク。そこでサイドバーを作るために発行している以下のSQLがネックになっていることが判明。

SELECT a.id, a.title FROM comment c INNER JOIN article a ON c.article = a.id GROUP BY a.id ORDER BY MAX(c.created_at) DESC LIMIT 10

クエリキャッシュを有効にしても焼け石に水で、1200/minくらいに向上したのみ。ただ、クエリキャッシュを適切に有効にしたことは、後々スキーマ変更した後のクエリ効率には貢献したので、もちろん有効な施策ではありました。

アプリ修正開始 13:00-

とりあえず、サイドバーが曲者だなってことで、まだ具体的な方針は決定はしていないものの、サイドバーの生成で上記クエリが走らないように、POST時にサイドバーの配列情報をmemcachedに突っ込んでしまうように先行して@sugyanがプログラムを修正することに。

で、よくよく考えたら、articleにlast_commented_atカラム追加すればjoinの必要なくなるしindexも張れるからかなり速くなるんじゃないか、と @fujiwara が指摘し、そのアプリの修正を僕、DBのAlterやデータ修正を@fujiwaraが担当。

僕と@sugyanがアプリの修正をしている間に、どうせ使うよねってことで、revにnginxとmemcachedを@fujiwaraがさくっとインストール。nginxのmemcachedプラグインも導入。

apacheからnginxにリバースプロキシを差し替えて、ベンチをとったらまさかの500/min。これは@kazeburoの罠で、時々keep-aliveを送りつけるベンチマーククライアントがいて、そのTCP接続が残り続けるのが問題だった。これはkeep-aliveをoffにすることで解決。

静的ファイルもアプリが返していたので、それもnginxでサーブするように変更。

僕の修正部分とnginxの合わせ技でベンチを取ったら20,000/min程度まで改善。@sugyanは大掛かりなコード修正で苦戦中。

このへんで一旦お昼ごはん。

キャッシュ戦略 14:00-

この時点で、DBのボトルネックは解消。次はアプリがネックになっている。フロントでnginxのmemcachedプラグインを使うってのは既定路線でそれを如何に有効に使うか。

データがPOSTされた1秒後にGETされるので、そこで確実に高速にレスポンスを返すためにまずはPOSTされた時点でGETされるであろうコンテンツを生成してキャッシュに乗せてしまおうという戦略。@fujiwara立案。

「GETされるであろうコンテンツの生成」はちょっとめんどくさいから、素早く実装できる方法として、localhostをFurlで叩いて、そのレスポンスボディをキャシュに載せてしまおうという力業。これまた@fujiwara案。このへんの見切り判断の早さがやばい。

その辺の実装を僕が担当。nginx memcachedプラグイン設定を@fujiwara担当。

リバースプロキシのアドレスをHostヘッダに入れてやる必要があるんだけど、FurlのHostヘッダの扱いに難があって、Hostヘッダを二重につけてしまったりしてしまう。あとで@xaicronに確認したところ、やっぱFurlの罠だった。結局LWP::UserAgentを使うことに。

その辺の変更を適用してベンチをとったら30,000/min程度までスコアが改善。ここまではすこぶる順調(のように見えた)。

14:40 (fujiwara) 現在1位

15:21 (fujiwara) 少なくとも惨敗はないなw


迷走時間 15:30-

キャッシュ戦略が有効に働き、ボトルネックがフロントに徐々に移行。「後はフロントの最適化」に専念。...とおもいきや「サイドバーの罠」にかかりここから苦戦することになる。

この時点でデータのキャッシュは上記の通りPOST時だけ。それを、GET時もキャッシュしてしまおうという戦略を@fujiwaraが立案。それを僕が実装。サーバー起動時に全URLにアクセスに行き、事前にキャッシュを温めてしまうウォームアップスクリプトを@fujiwaraが作成。

実装したところスコアはかなり改善したがエラーが頻発!

このへんで@sugyanのサイドバーの配列情報をmemcachedに入れる修正ができたので、マージして当て込んだところ、少しスコアは向上したが誤差の範囲内か。しかし、memcachedにミスヒットするとフェールオーバーしない男らしい作りだったため動作が安定せず、rejectすることに。フェールオーバー周りを改良して当て込む手もあったんだろうけど、残り時間の関係と、他のエラーも出てたので、問題点を絞りたかったってのが大きな理由。

この時点のエラー原因は後から振り返ってみると以下の4本。これが同時に起こったから、原因究明に苦労した。

  1. アプリ自体の単純なバグ
  2. アクセス増に伴うip_conntrack溢れ
  3. アクセス増に伴うnginx->memcachedでのローカルポート枯渇問題
  4. サイドバーの罠

3までは割とすぐ解決。@fujiwara がログを見る所が的確すぎて、原因究明が早すぎてビビる。

これで、問題完全解決とおもってベンチを走らせるも、サイドバーエラーが頻発。キャッシュをPOSTのみにするとエラーは起こらない。GETでもキャッシュさせるとエラーでベンチが通らない。

「謎だー」「DBコミットのタイミングかー」「でもオートコミットだよなー」

完全に迷走状態に。


恐るべきはサイドバーの罠 16:30-

いや、謎ではありません。以下を完全に見落としていたのです。

データがPOSTされると他のページのサイドバーも書き換わる

データPOST後の1秒後のGETだけではなく、他のランダムGETの処理でもサイドバーの整合性チェックをしていたのでベンチがコケていたのです。

考えてみればごく当たり前です。

つまりこれまで大丈夫だと思っていた、POSTの時だけキャッシュする戦略でも、GETの取られ方によってはベンチがこける可能性がある。

そもそものキャッシュ戦略が完全ではなかった

この恐るべき事実を突きつけられ、チーム内に衝撃が走ります。もう時間もない。

しかしここで、@fujiwaraの起死回生の一言がチームを救います。

「cacheに秒数付けて調整するしかないな」

それだー!苦肉の策ではありながら、時間内に出来ることはもうそれしか無い、むしろそれだけだったら十分すぎるほど時間に余裕はあります。当たり前の対策を的確なタイミングで言えるその凄さ。

懇親会で@kazeburoさんが講評前に「トップのチームはもっとフロントで捌くようにしてくると思ったけど、@fujiwara組はアプリに結構アクセスがあったのが意外だった」って言ってたって話を聞いた。

結局、上記のようにキャッシュ戦略に穴があったので、定期的にアプリに回してキャッシュを更新させるようにせざるを得なかったってのが理由です。ここはかなり出題者に負けた感があります。


秒数調整 17:00-

とりあえず、POSTのインターバルは1秒だからキャッシュの生存を1秒にしておけばほぼ安全。しかし、それだとキャッシュする意味が少なくなってしまう。他のチームのスコアを考えるともう少し冒険をしないとつらいところ。しかし、本番審査のベンチ時間は1分ではなく3分なので、その分は安全策を取らないといけない。

てことで、キャッシュの寿命を5秒に設定。ここでのベンチスコアは86,000/min! しかし、この時点のトップスコアが88,000/min程度だったので、それは上回れず。

とりあえず、100,000/minの初突破チームの特別賞狙いで、スケベ心を出してキャッシュの寿命を10秒に設定、nginxでのgzip圧縮転送等を試みるも、大して効果は出ず、96,000止まり。計測誤差範囲内。(この辺りの時間帯は各チームがベンチマークを回しまくっていたので、ベンチマークサーバーの負荷の関係か、ベンチマークのばらつきが大きかった。)

10秒でも大して効果なかったので、安全のためキャッシュ秒数を5秒に戻し。ここで、修正は凍結。あとは審査準備。

しかし実はここで僕がgit resetで "--hard"してなかったのでローカルのソースは巻き戻ってなかったというポカミスをしていた...。


願いを込めて再起動 17:30-

OS再起動後の審査スタートだったので、再起動後もちゃんとベンチが通るかどうかの確認。

ここで@fujiwaraの何気ない神の一手が発動。

おもむろに以下のようなテーブルを追加。

CREATE TABLE article_bh (
...
) Engine=blackhole;
CREATE TABLE comment_bh (
...
) Engine=blackhole;

そして、以下のSQLがOS再起動後に実行されるように設定。

INSERT INTO article_bh FROM (SELECT * FROM artcile);
INSERT INTO comment_bh FROM (SELECT * FROM comment);

うおお、なんてお手軽ウォームアップ。これでDBの内容をOSのメモリキャシュに載せるわけですね。

「memoryストレージ」みたいなことも話には出てたんだけど、まずは正攻法という哲学。

何度かベンチ回してスコア出るので大丈夫そうかな、と一安心

17:53 (songmu) 1位奪還中。後は本番勝負。

しかし間際でまさかのベンチFail。


最後の修正 17:57-

やっぱ5秒でも厳しいか、ってことで3秒に変更しようとする。しかし実は先程の記述のとおり、git上は5秒に戻してたけど、ソース上は10秒のままだったというオチ。なので、5秒に変更。

ソースを一行というか一文字変更するだけなんだけど、めちゃくちゃ焦って緊張した。ここでsyntax errorとか出したら死刑ものなので。


審査中 18:00-

周りの中間スコアを見ると、完走さえ出来れば上位には入れそうな感じだったので、なんとかベンチを完走して欲しいと願っておりました。1分完走率が8割だと、3分完走率は5分5分になってしまう。もっと成功率は高かったけど100%ではなかったので、やはり心配でした。

あとはプチ反省会。

  • "/"はPOSTされるタイミングで更新されるわけだからキャッシュに乗せておけばよかった
  • @sugyanのサイドバーのキャッシュはフェールオーバーをやっていれば、使えたかも
  • そもそも、サイドバーの更新タイミングの違いの罠に気付くのが遅すぎた。それに早く気づいていたら違う手も打てた

審査結果発表 18:30-

先に発表された準優勝のスコアが70,000万/3minとそこまで高くないスコアだったので、内心「これはうちは審査完走できなかったのかも...」とドキドキでした。

無事に完走を遂げたらしく、270,000 over/min のスコアで優勝できました。

優勝トロフィー

振り返って

ホント素晴らしいイベントでした。@fujiwara組長の仕事ぶりを目の前で見られたのは本当に大きな経験になりました。

懇親会での会話もめちゃくちゃ盛り上がりました。トークイベントとはまた違って、全員が同じ事をやっているので、話が弾む弾む。

話を聞くと、言いだしっぺの @tagomorisさんが、やりたいなーみたいなことを言い出したら、どんどん話が進んで、トロフィーまで準備されるという。エンジニアドリブンであれだけのイベントをあれだけのリソースを使って開催できるのはマジすごいと思いました。見習いたい。

あと、@tagomorisさんと自転車の話ができてよかったです。今度走りに行きましょう。

投稿者 Songmu : 16:15

2011年3月27日

悪いけど正しいかもしれないPHPerになるための10個のTips

流行っているみたいなので書いてみた。かなり独断と偏見に満ちたエントリになっています。決定的な間違いがあったらブクマコメ等で指摘願います。

さて、そもそもPHPとはなんのための言語か。HTMLの延長線上で使える学習コストの低いテンプレート言語であり、多少汚くても良いから、Webアプリケーションを手っ取り早く作るための言語です。

色々なユーザーの声をやたらめったら取り込んでしまったせいで、日本の家電みたいに無駄かつ一貫性のない機能が満載で醜悪なことになっていますが、その辺は気にしないことにしましょう。

ただ、変に多方面の声を取り込んでしまったせいで、妙にお行儀よくなりたがっている部分も多く、使いづらくなっている部分も多々あったりして困りものですが。

まあ、つまりPHPにおいて「良い」ってのはありえないんですよ。とか言ってみたりして。

閑話休題。

エラーレベルは最大にしろ

色々コードが書きづらくなる部分もありますが、逆にお行儀がよくなり分かりやすくなる部分も出てきます。また、前方互換も考えると、最大限有効にしておくのが賢明でしょう。

PHP.iniに以下のように書くのが理想です。

error_reporting = E_ALL | E_STRICT

PHP.iniを触れない場合、スクリプト内に以下のように書くこともできます。

error_reporting( E_ALL | E_STRICT )

ただ、この場合、コンパイルレベルでのエラーを一部出力してくれなくなるので残念です。

.htaccessに書くこともできますが、その場合は定数を使えず、即値を使わないといけないので、一長一短ですね。

あと、PHP4と互換性のあるモジュール(MDB2とか)なんかを使うときにエラーがたくさん出て困ることになりますね。このあたりどうすれば良いんでしょうね。

エラーレベルを動的に変更できないところがPHPの辛いところ。


文字コードはUTF-8一択

理由は色々ありますが、大きな理由としてはマルチバイト文字を扱うときにUTF-8じゃないとpreg系の関数が正しく動かないことです。

mb_regex_encodingを適正に設定して、mb_ereg系を使うという手もありますが、mb_ereg系では、各種正規表現修飾子が使えないのが痛い。特にx修飾子が使えないのが致命的。


正規表現はpreg系を使い、x修飾子を積極的に使いましょう

x修飾子超便利。


変数名には「意味」を持たせる。型は持たせない

型は意味ではない。変数の型付けに拘るのは静的型付け言語の考え方であり、動的型付け言語は無意味。

例えば、my_ageだったらintegerに決まっている。それをiMyAgeなんて変数にするのはナンセンス。

それに、追加開発時にmy_ageはintegerではなくて、ageクラスのインスタンスに仕様変更されるかもしれない。そういう自由さを動的型付け言語は持っている。そうなったときに、変数名がiMyAgeのままだったら目も当てられない。

ただ、同じ変数の型がプログラムの中でコロコロ変わるなんてのは分かりづらいのでやってはいけません。これは、次の「真理値を返すのは真理値を返すメソッドのみにする」でも触れます。

それと、キャメルケースは案外読みづらい。変数名はアンスコ区切りが良いんじゃないかと思う。


真理値を返すのは真理値を返すメソッドのみにする

PHPは動的型付けなので、メソッドの途中で失敗したらfalseを返すみたいなこともやってしまいがち。

しかし、正しくはメソッドの戻り値の型は固定にして、メソッドの途中で失敗したら例外を投げるべき。falseを返すような実装にしてはいけない。呼び出し元でイチイチ戻り値をチェックしないといけなくなり、コードの見通しが悪くなります。

メソッドが真理値を返すのは、そもそも、is*とかcan*とかtrueかfalseを判定するメソッドに限るべきです。


var_dumpとかアドホックな出力に頼るな

たしかにvar_dumpは便利だ。ただ、デバッグ値を画面に出力するだなんてのはあまりにもダサい。そんなことだから、PHPerがバカにされるのだ。

var_dumpの内容はデバッグログに吐くべきだ。それには多少工夫が必要になる。以下のような感じだ。

function d(){
    ob_start();
    ob_implicit_flush(0);
    $args = func_get_args();
    call_user_func_array('var_dump', $args);
    $str = ob_get_clean();
    return $str;
}

出力ストリームをトラップして、戻り値として返すようになっている。var_dumpは可変長引数をとるのでそれも受け付けるようにしてある。

上記関数を以下のようにロガーに渡して、ログファイルをtail -f で見ろ。そうすれば変数の変化なんかも追うことができる。

$logger->debug(d($obj));


三項演算子はネストしない

三項演算子は便利だがPHPだと連結順がおかしいのでネストしない。括弧で囲んで頑張ってネストさせる手もあるが、そこまで頑張らなくてもよいでしょう。

switch文が便利なこともありますが、例によって「緩やかな比較」なので注意。

ちなみに、PHP5.3以降は?:演算子も使えるのでちょっと便利。


$_GET$_POSTを使え

$_REQUESTを使うのはもちろん論外だが、$_GET$_POSTをイチイチちょっとしたクラスでラップする必要性も感じない。ユーザーの入力値を使いやすい形で提供してくれているのだから使うべきだ。

もし、オブジェクト化したら、キーをなめるような処理が欲しくなった時にkeysみたいなメソッドを生やさなくてはいけなくなるような不自由さが発生するし、そもそもアプリケーションがWebからの入力を前提とした作りになってしまう。

上手くクラスを利用するとしたら、バリデーターオブジェクトをつくってそれに$_POSTを喰わせるとか、フォームオブジェクトを準備しておいてリクエストに対して自動で$_POSTの中身をバリデーションするとか、そんな時でしょう。その場合も、$_GET, $_POST自体をラップしておく必要はありません。

そして、ちょっとしたアプリケーションであれば、生の$_GET, $_POSTで困ることは少ないのです。

ただ、$_GET, $_POST, $_COOKIEあたりを事前にmb_check_encodingを通して、不正な入力値が与えられていないかはフレームワーク側で担保しておいたほうが良いでしょう。


設定ファイルはアプリケーション設定ファイルと環境設定ファイルの2種類持て

最近は、アプリケーションの設定をする設定ファイルと、環境情報を記載した設定ファイルの2種類を準備したほうが良いんじゃないかと思い始めている。

そして、環境情報ファイルは本番と開発用で分けておくが、アプリケーション設定ファイルは本番と開発用で共通して使えるものにしておく。

アプリケーション設定ファイルが肥大化してきたら、一部の設定値や定数群をモデルクラスにアサインした方がよくなってくるでしょう。もちろんモデルだからといって、ストレージはDBとは限りません。


short_open_tagを有効にし、テンプレート内では<? ?>を使え

最後に超独断の爆弾。

個人的にはコントローラやモデルは<?php で書き始め ?>で閉じないように書いていますが、テンプレートでは<? ?>を使うのが好きです。

short_open_tagをoffにして、テンプレート言語としてのメリットを捨ててまで、PHPみたいな(censored)な言語を使う理由を全く感じません。

よく言われるのが、XML宣言云々ですが、そこだけechoで書けばよいだけの話です。なんでそこでechoを使わないためだけに、他のところでechoを使わないといけないのか意味がわかりません。

あと「他の環境に持って行っても動くように」なんて話もありますが、それも.htaccessに書けば良いだけなんでないの、とか思ったり。

理想を言えば、最近のトレンドからして、<?= ?>で囲まれた部分はオートエスケープされるようにPHP側で良きに計らってくれるようになってくれれば良いな、と思う。もちろん後方互換を考えてPHP側でなんらかの環境設定フラグを準備してもらう必要はあるでしょう。またPHPにフラグが増えることになりますが。

投稿者 Songmu : 23:22

2011年2月 3日

Kamakura.pm Tech Talk #1でSpiritual Talk(?)をしてきました

先週の金曜日にKamakura.pmで話してきました。Tech Talkというよりかは思想的な話でした。まあ、Tech Talkは他の方におまかせという感じで。

yusukebeにスピリチュアルとかやたら言われましたが、割と反応をいただけたようでよかったです。モダンPerlの裏側で有名なkoba04さんも丁度いらしていて、僕も割とモダンPerlの裏側に居た人間なので、お話ができて良かったです。

スライドは以下。

Perlの地位を上げる方法

基本的には、Perlって必須スキルだよね、誤解されてるよね、どうすればユーザーを増やせるんだろうとか、前の会社での経験も踏まえて話した感じです。

そういやスライドにちょろっと書いているように、今年から面白法人カヤックで楽しく働いています。その辺の話はまたそのうち。

PerlがロードレーサーでPHPがクロスバイクって話は個人的にはナイス例えだったんだけど、一部にしか伝わらなくてやや残念。

エクササイズ目的で自転車買う人って、ロードバイクには抵抗があるから、まずクロスバイクからって人が多いんだけど、そこでロードバイクをゴリ押しで薦めてしまうと、自転車自体に乗ってもらえなかったし、しぶしぶロードを買ったとしても、あまりハマってもらえなかったりする。

逆にクロスバイク買ってしまった人がたくさん乗るようになると、物足りなくなってきて、結局ロードを買ってしまう人が多々いますというお話でした。

実際、プログラミングとロードレーサーって似てる部分があると思っていて、割と簡単に「俺スゲー感」を味わえるんだけど(40km/hを自力で簡単に捻り出せる快感!)、よくよく見てみるとその「俺スゲー感」のレベルって大したことなくて、上を見たらキリがない所とか。まだまだイケると思ってしまい終わりがないところとか。

二次会でも指摘されたんだけど、丁度、プログラミング言語の比較ってのがホッテントリ入りしていて、奇しくもタイムリーな話題でありました。まあ、あのエントリーは良エントリーですよね。公平に書いてあると思う。Perlはもう少し評価して欲しかったけど。

僕以外のTalkはTech Talkに相応しい内容で、yusukebeのBlog Hacks 2011は流石の内容で、nekokakuさんのTengの話を聞けたのは非常に良かったし、fujiwaraさんのSys::Vertの話はVM使っているのでかなり参考になりました。

二次会では、yusukebeと

  • tokuhiromのコードは面白いし参考になる
  • 海外のPerlモジュールはマッチョでなんか違うよね
  • だから日本から発信していかないといけないね

みたいな話をした。

投稿者 Songmu : 00:53

2010年12月31日

今年のJPerl Advent Calendarとか

少し前の話になりますが、去年も一記事書いたのですが、今年は調子に乗って3記事書きました。

ブログは全然更新してないのにね。

ところでAdventと言えばシュトーレンですが、Twitterで@neotagと絡んでいたら、今更急にシュトーレン作りたい欲求が高まっています。それだけ。

投稿者 Songmu : 21:32

2010年12月27日

YapafiっていうPHPフレームワーク書いた

ここのところPHPのフレームワークを書いていて、ひと段落ついたので公開します。名前は完全にYacafiインスパイアです、ごめんなさい。

社内フレームワークとして使われることを期待して作ったものです。

「社内フレームワークとかダサッ」

とか言う声が聞こえてきそうなのですが、まあ、WAF作りはWebプログラマーのはしかの一つといわれるくらいですから。

実際のところ、社内でそこそこ実績のある社内フレームワークがいくつか有り、ただ、それらがいい加減古い設計になっていたり、今からするといけていない点があったりしつつ、なかなか移行が進まないと言う問題があったので、その辺りの刷新を狙って作りました。

まあ何で作ったかとかは、公開ページに書いてあります。

基本的にはワンファイルで動き、WAF自体が提供するのはディスパッチ機能くらいな感じの薄いフレームワークとなっています。コードジェネレータとか難しいこともやらない感じです。

あと、単独でFormValidator.phpってのを作ったのですが、これが結構いけてるんじゃないかと思っています。ただ、まだドキュメンテーションできていません...。

チュートリアルとサンプルを見れば大体どんな感じかは分かると思います。

モジュールなんかの作りはかなりCPANモジュールからパクらせてもらっています。以下のモジュールはそんな感じですね。

  • Mail_Address_MobileJp
  • Devel_BackTraceAsHTML
  • DataValidator
  • FormValidator

PHPはPEARがイマイチ使いづらいので、集合知の部分はPerlに劣るなぁとか思いました。PEAR2に期待。

投稿者 Songmu : 23:41

2010年9月27日

モダンなPerlを「読む」上で覚えておくとよい構文 第2回「リストを理解すれば配列とハッシュをより活用できる」

第1回から大分時間が空きましたが、なんと続きます。「次回は無名関数について書く」とか書いていましたが、先にリストについて言及することにします。

混同されがちですがこのエントリーでは「リスト」と「配列」を厳密に違うものとして扱います。結論を先に簡単に言ってしまうと、リストを配列に代入すれば配列になるし、リストをハッシュに代入すればハッシュになるということです。

Perlの式は値を返す

サブルーチンに限らずPerlのあらゆる式は評価された値を返します。返された値は代入先があれば代入され、代入先がなければ捨てられます。

値を返さないケース

ブロックは値を返しません(doを使えばブロックに値を返させることが出来ます)。例外的にuse文やpackage文は値を返しません。この二つはコンパイル時にコードを実行する前に最初に評価されるので値の返しようがありません。

さて、本題です。Perlの式の値の返し方には2種類あります。スカラーとリストです。スカラーを返すかリストを返すかはコンテキストに応じて変化することもあります。

リストコンテキストで返されるものがリスト(当たり前!)です。また、以下のようにすればリストを直に記述できます。

(1, 2, 3, 'hoge');
qw/1 2 3 hoge/;

「なんだ、配列じゃないか。」

いいえ、違います。そう思う人は以下のコードを実行してみて下さい。驚きの結果が得られることでしょう。

use Data::Dumper;
my $hoge = \(1, 2, 3, 'hoge'); #配列をリファレンス化している...?
print Dumper $hoge;

リストを配列リファレンスに代入したい場合は、リストをブラケットで囲めば配列リファレンスを返します。

my $hoge = [1, 2, 3, 'hoge'];

リストはハッシュキーにもなれる(けど使う機会はまずない)

以下のようなことも可能です。

my %hash;
$hash{qw/1 2 3/} = 'hoge';
print $hash{qw/1 2 3/}; # hoge

これはどういう事かというと、以下のコードを実行すれば分かります。

my %hash;
$hash{qw/1 2 3/} = 'hoge';
my ($key) = keys %hash; #キーを取り出す。
$key =~ s/(.)/'\x'.unpack('H2', $1)/eg; #バイトごとに16進にエンコーディング
print $key; # \x31\x1c\x32\x1c\x33

値が'\x1c'という文字で区切られていることが分かります。これは印字されない制御文字(FS)です。つまり印字されない文字を区切り文字に使った文字列(バイト列)がキーになっているという単純な仕掛けです。

なのでバイナリデータをハッシュキーにしたりすると上手くいかない可能性があります。

また、この区切り文字には特殊変数$;を使ってアクセスすることができます。

ややマニアックだけどかなりどうでも良いネタでした。

冒頭に書いたとおり、リストを配列に渡せば配列になり、ハッシュに渡せばハッシュになります。

前の記事でも書きましたが、ハッシュへの代入で使われる、"=>"(ファットコンマ)ってのは単なるカンマの代用であり、コードの可読性を上げるために使われています。ハッシュに渡されるのは単なるリストです。
my @arr = (1, 2, 3, 'hoge');
print $arr[1]; # 2
my %hash = (1, 2, 3, 'hoge'); # (1 => 2, 3 => 'hoge') と同じ
print $hash{3}; # hoge

配列はリストコンテキストで評価された場合リストを返します。ハッシュも同様にリストを返します。なので以下のようなことも可能です。

my @arr = (1, 2, 3, 'hoge');
my %hash = @arr;
print $hash{3}; # hoge
@arr = %hash; # こんなことも可能。ハッシュの順番が保証されないので、普通はやらない

これを利用して、名前付き引数的な関数を実現可能です。

#カッコの中はリスト。ファットコンマは単に可読性のため。
func(
    hoge => 'fuga',
    piyo => 11,
);
sub func {
    #配列をハッシュに代入していて一見意味不明だが、配列がリストを
    #返し、それがハッシュにわたっていると考える。
    %hash = @_;
    if ($hash{hoge} ){ ... }
}

また、以下のようにmapを組み合わせて、配列の各要素をキーとして、ハッシュを作成することが可能です。

my @arr =  qw/hoge fuga piyo/;
%hash = map { $_ => 1 } @arr; #各要素を1で初期化
if($hash{hoge}){# @arr内に'hoge'が存在するかをチェックできる
...
}

mapやgrepは難解に思えますが、リスト操作には欠かせません。トリッキーに思えることも多いかと思いますが、そのうち慣れてくるでしょう。ただ、やりすぎはいけません。

リファレンス

[]や{}を使って、配列/ハッシュリファレンスを作成することが出来ますが、内部に単なるリストではなく、リストを返す式を書くこともできます。以下のような感じです。

$arr_ref = [1,2,3]; # 普通の書き方
$arr_ref = [qw/hoge fuga piyo/]; # こんな書き方も
$arr_ref = [@arr]; # \@arr と実質同じだけど、こう書かれることも多い
$arr_ref = [split //, $str]; #文字列を一文字づつ切り出した結果を配列リファレンスに

最後の式は少しびっくりするかもしれません。人によって多寡はありますが、これくらいだったら良く使われているように思います。mapやgrepがこの中で使われることもあります。例に因って自分で書くときはやりすぎは厳禁です。

また、オブジェクトのコンストラクタに引数を渡すときに、名前付き引数的な渡し方とハッシュリファレンスを渡すやりかたが両方可能になっている場合も結構あったりします。以下のような感じです。

my $obj1 = Hoge->new( #名前付き引数的な渡し方
    hoge => 'fuga',
);
my $obj2 = Hoge->new({ #ハッシュリファレンスを渡す渡し方
    hoge => 'piyo',
});
package Hoge;
sub new{
    my $cls = shift;
    #渡されたのが、リスト(名前付き引数)か、ハッシュリファレンスか判別
    my $self =
        ref $_[0] eq 'HASH' ? shift : {@_};
    bless $self, cls;
}

{@_}という書き方が最初慣れないかも知れませんが「配列がリストとして展開されて、それがハッシュリファレンスになる」と考えれば理解可能でしょう。

まとめ

「何でここでは配列なのに、こっちではハッシュなんだ?」とか思ってしまうこともあるかもしれません。

全てリストを介してつながっている

と考えれば話は簡単です。この辺りのリストの扱いを理解してくると「PerlがLISPの影響を受けている」と言われる所以も分かってくるでしょう。

投稿者 Songmu : 03:54

2010年9月20日

Perlでフィボナッチ数列の高速化とか無名関数の再帰とか

簡単にfibを高速化する方法を読み、おおっと思って、Perlでやってみた。

#!/usr/bin/perl
use strict;
use warnings;
use feature qw/state/;
use Benchmark qw/timethese cmpthese/;
 
sub _fib_ret2 {
   my $n = shift;
   if ( $n == 1 ){
       (1,1);
   }
   else {
       my ( $aa, $bb ) = _fib_ret2($n-1);
       ($aa+$bb, $aa);
   }
}
sub fib_ret2 {
   (_fib_ret2(shift))[0];
}
 
sub fib_memo {
   state @cache;
   my $n = shift;
   $cache[$n] ||= $n <= 1 ? 1 : fib_memo($n-2) + fib_memo($n-1);
}
 
sub fib_normal {
   my $n = shift;
   return 1 if $n <= 1;
   return fib_normal($n-2) + fib_normal($n-1);
}
 
sub fib_no_recv { #まあ、これが一番速いのは分かってるんですよ。
   my $n = shift;
   return 1 if $n <= 1;
   my ( $fib, $prev ) = (1,1);
   ( $fib, $prev ) = ( $fib+$prev, $fib ) for 2..$n;
   $fib;
}
 
my $fib_arg = 30;
cmpthese timethese 0, {
   fib_ret2    => sub { fib_ret2($fib_arg) },
   fib_memo    => sub { fib_memo($fib_arg) },
   fib_normal  => sub { fib_normal($fib_arg) },
   fib_no_recv => sub { fib_no_recv($fib_arg) },
};
fib_memo:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @ 1742548.96/s (n=5551761)
fib_no_recv:  3 wallclock secs ( 3.17 usr +  0.00 sys =  3.17 CPU) @ 66800.76/s (n=211892)
fib_normal:  3 wallclock secs ( 3.61 usr +  0.00 sys =  3.61 CPU) @  0.55/s (n=2)
fib_ret2:  3 wallclock secs ( 3.20 usr +  0.00 sys =  3.20 CPU) @ 28944.44/s (n=92738)
                 Rate  fib_normal    fib_ret2 fib_no_recv    fib_memo
fib_normal    0.554/s          --       -100%       -100%       -100%
fib_ret2      28944/s    5224372%          --        -57%        -98%
fib_no_recv   66801/s   12057437%        131%          --        -96%
fib_memo    1742549/s  314529988%       5920%       2509%          --

確かに速い。しかし、メモ化するよりかは遅い?いや、再帰なしのパターンよりか速いのはおかしくね?

違ぁう!そりゃそうだ。メモ化したやつは2回目の試行以降は、単なる配列のインデックスアクセスになっているので速いに決まっているのだ。つまり、実装としては正しいが、ベンチマークとしてはフェアじゃない。

てことで、ベンチマークの試行毎にメモの内容が初期化されて欲しい。しかし、stateが初期化された無名関数を返すにしても、無名関数を再帰する方法はPerlにはデフォルトで無いので、ダサいけど外部にメモを持たせるしかないかなぁと。

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw/timethese cmpthese/;
 
sub _fib_ret2 {
   my $n = shift;
   if ( $n == 1 ){
       (1,1);
   }
   else {
       my ( $aa, $bb ) = _fib_ret2($n-1);
       ($aa+$bb, $aa);
   }
}
sub fib_ret2 {
   (_fib_ret2(shift))[0];
}
 
my @memo;
sub fib_memo2 {
   my $n = shift;
   $memo[$n] ||= $n <= 1 ? 1 : fib_memo2($n-2) + fib_memo2($n-1);
}
 
sub fib_no_recv {
   my $n = shift;
   return 1 if $n <= 1;
   my ( $fib, $prev ) = (1,1);
   ( $fib, $prev ) = ( $fib+$prev, $fib ) for 2..$n;
   $fib;
}
 
my $arg = 50;
cmpthese timethese 0, {
   fib_ret2    => sub { fib_ret2($arg) },
   fib_memo    => sub { @memo=();fib_memo2($arg) },
   fib_no_recv => sub { fib_no_recv($arg) },
};
fib_memo:  3 wallclock secs ( 3.22 usr +  0.02 sys =  3.23 CPU) @ 12827.77/s (n=41485)
fib_no_recv:  3 wallclock secs ( 3.14 usr +  0.02 sys =  3.16 CPU) @ 34344.42/s (n=108391)
fib_ret2:  4 wallclock secs ( 3.30 usr +  0.00 sys =  3.30 CPU) @ 17243.33/s (n=56834)
               Rate    fib_memo    fib_ret2 fib_no_recv
fib_memo    12828/s          --        -26%        -63%
fib_ret2    17243/s         34%          --        -50%
fib_no_recv 34344/s        168%         99%          --

確かに一回だけの計算だったら、二つ返すほうがメモ化よりも速いことが分かる。

理由を考えてみると、値を二つ返すパターンだと、単に実行コンテキストをスタックに詰んでいって戻ってくるのが一本道だと言うことが分かる。

メモ化のパターンだと関数内で関数が2回呼ばれるので、その分関数の呼び出し回数が指数的に増えていってしまうので、そこがネックになるのでしょう。

なるほど。考えた人すごい。

おまけ

無名関数の再帰が出来なくてスマートに記述できなかったのが悔しかったので、Sub::Recursiveを使って書き直してみた。Sub::Recursiveを使ったのは、「Perlで無名関数再帰のベンチ」で一番速いって書いてあったし、そこにあったベンチマークスクリプトを走らせても圧倒的にSub::Recursiveが速かったので。

#!/usr/bin/perl
use strict;
use warnings;
use feature qw/state/;
use Benchmark qw/timethese cmpthese/;
use Sub::Recursive qw/$REC recursive/;
 
sub _fib_ret2 {
   my $n = shift;
   if ( $n == 1 ){
       (1,1);
   }
   else {
       my ( $aa, $bb ) = _fib_ret2($n-1);
       ($aa+$bb, $aa);
   }
}
sub fib_ret2 {
   (_fib_ret2(shift))[0];
}
 
sub fib_ret2_lambda{
   ((recursive {
       my $n = shift;
       if ( $n == 1 ){
           (1,1);
       }
       else {
           my ( $aa, $bb ) = $REC->($n-1);
           ($aa+$bb, $aa);
       }
   })->(shift))[0];
}
 
my @memo;
sub fib_memo2 {
   my $n = shift;
   $memo[$n] ||= $n <= 1 ? 1 : fib_memo2($n-2) + fib_memo2($n-1);
}
 
sub fib_memo_lambda {
   recursive {
       state @cache;
       my $n = shift;
       $cache[$n] ||= $n <= 1 ? 1 : $REC->($n-2) + $REC->($n-1);
   };
}
 
my $fib_arg = 50;
cmpthese timethese 0, {
   fib_ret2        => sub { fib_ret2($fib_arg) },
   fib_ret2_lambda => sub { fib_ret2_lambda($fib_arg) },
   fib_memo        => sub { @memo=();fib_memo2($fib_arg) },
   fib_memo_lambda => sub { fib_memo_lambda()->($fib_arg) },
};
fib_memo:  4 wallclock secs ( 3.17 usr +  0.00 sys =  3.17 CPU) @ 13341.11/s (n=42318)
fib_memo_lambda:  3 wallclock secs ( 3.20 usr +  0.00 sys =  3.20 CPU) @ 6907.90/s (n=22126)
fib_ret2:  3 wallclock secs ( 3.22 usr +  0.00 sys =  3.22 CPU) @ 16680.96/s (n=53696)
fib_ret2_lambda:  3 wallclock secs ( 3.25 usr +  0.00 sys =  3.25 CPU) @ 15201.23/s (n=49404)
                   Rate fib_memo_lambda     fib_memo fib_ret2_lambda    fib_ret2
fib_memo_lambda  6908/s              --         -48%            -55%        -59%
fib_memo        13341/s             93%           --            -12%        -20%
fib_ret2_lambda 15201/s            120%          14%              --         -9%
fib_ret2        16681/s            141%          25%             10%          --

まあ、やっぱ余計なことしないほうが速いに決まってますよね。

投稿者 Songmu : 23:07

デイリーポータルViewerをバージョンアップ(べつやくれい・林雄司両氏結婚記念ではない)

まずはべつやくれいさん、林雄司さんご入籍おめでとうございます。面白人間同士ご結婚ということでどんなお子さんが産まれるか今から楽しみですね!

で、その昔デイリーポータルZを作者別に見たいと思って、デイリーポータルViewerというものをその昔作りっぱなしで放置しておりました。余りにもひどい酷い作りだったので直したいと常々思っていたのですが、この度改良を加えました。見た目は全然変わっていませんが、実質書き直しになりました。

やったことは以下。

  • ワンファイル内でprint文直書き(!!!)だったのでロジックとviewを分離。CGIフレームワークHyCycjkを適用。
  • データファイルをテキストファイルからSQLiteに。排他制御周りを見直し。
  • RSSのパースを正規表現(!!!)からXML::FeedPPに変更
  • クローリング頻度を見直し

本当はURLも変えたかったのですが、長年このURLで運用してしまったので、そこは変えないことにしました。daily2.cgiというファイルはもうありませんが、mod_rewriteで無理やり同じURLにしています。

HyCycjkはYacafiをベースにしてMentaにインスパイアされた拙作のCGI Application Frameworkです。Yacafiよりかは高機能、Mentaよりかは低機能だけどワンファイル配置するだけで動く。といった辺りを狙っています。多分mod_perlでも動きます。残念ながらPSGI対応はしていません。

しかし、元のプログラムは色々酷くて、よく動いていたなぁと逆の意味で関心してしまうというか。2年半前の自分はここまで酷かったのかとか。

そもそも、立ち上げのときも、バックナンバーのページからリンク先を辿ってデータを取得するようなクローラを書いたのですけど、勿論1アクセス毎にウェイトをかけるなんてこともしてなかったので、逮捕されなくてよかったなぁ(笑)、とか思ったり。

投稿者 Songmu : 22:10

2010年3月22日

モダンなPerlを「読む」上で覚えておくとよい構文 第1回(?)

Perl学習者がある程度Perlに慣れてくると、他の人の書いたコードを読む機会も増えてきます。そこでつまづく人は多いのではないでしょうか。かく言う私自身がその一人です(笑)

モダンなPerlはDSL(黒魔術?)的な書き方をしている部分も多く、雰囲気として処理内容をつかみやすいのですが、逆に文法的に構文を理解するのが難しいことも多いです。

「知っている人には当たり前、知らない人には黒魔術」

Perlにはそういうのが多いので、そういったところで悩んでいる人も多いのではないかと思い、このエントリーを書いてみることにしました。気が向けば続きも書きます。間違っている部分もあるかと思うので、ブクマコメ等でご指摘いただけると助かります。

本日の目標とサンプルコード

裸のワード(bareword)は怖くない

encode cp932 => $str;
sub PI(){3.1415926535}

てことで本題に入ります。

=>(ファットコンマ)は要は単なる","(カンマ)である

サブルーチンの括弧は大概省略出来る

Perlに少し慣れてきたかな、くらいの方は以下のようなコードを見るとぎょっとするかもしれません。

print encode cp932 => $str;

「あれ?"=>"ってハッシュを組み立てるときに使う記号じゃなかったの?でもこれってハッシュじゃないよね...?
「cp932って何?そんなキーワード(予約語)知らないけど...?」

実は"=>"(ファットコンマ)ってのはPerlの文法上、働きは単なるカンマと一緒です。

ハッシュを組み立てるときに使われているのは、ファットコンマにしかない

「ファットコンマの直前に置かれた文字列はクオートしなくても良い」

という特徴があり、またペアであることも示しやすいので使われているだけという話なのです。(ただしクオートを省略できるのは、半角英字・アンダーバーから始まり、半角英数字・アンダーバーのみが続く場合のみ。変数命名と同じ)

つまり、以下の2行は同じ意味になります。

my %hash = ( hoge => 'fuga');
my %hash = ('hoge', 'fuga');

また、既に定義が読み込まれているサブルーチンの括弧が省略出来るのは皆さんご存知かと思います。Perlの場合、コード中に予約語ではない裸のワードがあれば、それはサブルーチン呼び出しであることが明らかなので、最近は可読性を損なわない限り括弧なしで書かれることが多くなってきています。同様に、サブルーチンに&(アンパサンド)をつけるのも最近は推奨されていません。

それらを踏まえて最初のコードを初心者に分かりやすい形に書き直すと、以下のようになります。

print encode( 'cp932', $str );

これなら意味は分かるかと思います。Perl文字列をcp932でエンコードして出力しようとしているのです。

cp932について

WindowsではShift_JISを拡張したcp932という文字コードが使われています。Encode.pmでの文字コード指定文字列の'shiftjis'(sjis)と'cp932'はそれぞれ(微妙に)違います。多くの場合cp932を指定しておくと間違いはありません。

また、'utf8'と'utf-8'も違います。脱線しすぎるので説明は省きます。

カンマが使われている箇所はすべてファットコンマで置き換えることが可能ですが、もちろん濫用するものではありません。使いどころとしては、

  • ファットコンマの左側に来る文字列が、単なる文字列以上の意味合いを持つ(何らかのキーワードであるとか)
  • 変数(文字列)が無名関数に渡っているように見せる

といった時に使われています。

ファットコンマの直前の文字列をクオートしない場合の注意点

use utf8;している時に、ファットコンマの前に裸の文字列を置くと、その文字列にutf8フラグが立ってしまうというバグがあります。Perl5.10.2で修正予定らしいです。

ハッシュのキーのクォーテーションは省略出来る

これは個人的には最近まで気持ち悪かったのですが、やっている人が多いので開き直って書き始めました。使ってみると確かに余計な記号が減るのでコードの可読性も上がる気がします。

ハッシュキー指定に裸のワードを使う上での注意点

レアケースですが、同名の定数とバッティングしてしまう可能性があります。その場合は文字列をクオートする、または定数を括弧付きで呼び出す等すればコードの可読性が上がるでしょう。(そもそもそのようなことが起こらないように命名に気をつけるべきですが)

use constant CONST => 4;
my %hash;
$hash{'CONST'} = 5;
$hash{4} = 4;
print $hash{CONST}; # どっち? 正解は5
print $hash{'CONST'}; # 5 
print $hash{CONST()}; # 4

Perlの定数ってのは単なるサブルーチンである

前項目の最後にさりげなく(?)触れましたが、Perlの定数ってのは実は単に引数をとらない関数です。下記2行は(ほとんど)同じ意味です。

use constant PI => 3.1415926535;
sub PI(){3.1415926535}

上の書き方が正当ですが、少しでもコードの実行速度を上げたい場合、constant.pmを呼び出すことのオーバーヘッドを嫌って、下のように定数を定義するコードが書かれていることもよく見かけます。(各種プラグマも結局のところ単なるPerl Moduleです)

PIの後の括弧はサブルーチンプロトタイプ宣言です。PIが引数をとらないサブルーチンだということを明示的にあらわしています。

プロトタイプについて

プロトタイプはあまり使われませんが、

  • サブルーチンを定数として使うとき
  • コードブロックをサブルーチンに渡すとき

なんかに使われるみたいです。つまり黒魔術っぽい書き方をしたいときに使うということです(笑)

ちなみに、引数をとらないことをプロトタイプで明示している場合、多くの場合、コンパイル時にそのサブルーチンの中身がインライン展開されます。つまり高速です。該当箇所にサブルーチンの中身がベタっと貼り付けられるイメージです。

まとめ

今回説明した記述方法の共通点として

「裸のワード」がコード上に増える

ということがあります。

長らく裸のワード(bareword)を嫌ってきたPerlですが、近年は「裸のワードをうまく使う」という傾向が見られるようになってきたと思います。自然な英語っぽく見えて、余計な記号も少ない方が分かりやすい。Rubyなんかの影響もあるのかも知れません。

次回は、無名関数について書こうと思います。

投稿者 Songmu : 00:35

2010年2月 7日

どうやらCPAN Authorになったようです

念願のCPAN Authorになったらしい。今年の目標の一つだったのですが、宣言する前になってしまいました。

たいしたモジュールじゃないんですが、Math::CheckDigitsというモジュールをあげてあります。名前のとおり、チェックディジットを計算したり、判定したりするモジュールです。

Algorithm::CheckDigitsというCPANモジュールが既にあります。ただ、これはフォーマット名(JANとかISBNとか)を指定しないと使えなかったりして、いちいちそんなに覚えていられません。単純にModulusとWeightを指定するだけで使えるモジュールが欲しかったので作りました。

フォーマット名を指定して判定したい場合も、このモジュールを基底クラスにしてサブクラスを書けば簡単に作れると思うので、ゆくゆくはそういったモジュールも作成しようと考えています。ちなみにAlgorithm::CheckDigitsはサブモジュールにいちいち似たような処理が書いてあるので、ちょっと好みじゃありません。

企業様向けの社内システム等の受託開発なんてやってると、要件にチェックディジットが出てきたり、テストバーコード打ち出したりとかで、チェックディジットを使う機会が多かったりします。その辺りがこのモジュールを作ろうと思ったきっかけでしょうか。

モジュールはModule::Setupを使って作成しました。tar.gzがパーミッションの関係でPAUSEアップロードに撥ねられたりしてWindowsでCPANモジュールを作るのには苦労しました。

幸い、アップロード時に自動送信されてくるレポートメールの中に失敗の詳細が書かれていました。しかもtar.gz内のファイルパーミッションを書き換えてくれる修正スクリプトへのリンクまで書かれており、それを使って問題を解決出来ました。

集合知を使うところまで自動化されているんだからCPAN恐るべし。ただ、Windowsで開発するのも色々鬼門でめんどくさいなぁとか感じつつある今日この頃です。

CPANはありそうなモジュールが案外無かったりするので、そういうニッチな部分で勝負できるのではないかと思い始めています。

今回はWebには全然関係ないモジュールだったので、次回はWeb関係のものをあげます。

投稿者 Songmu : 23:44

2009年12月22日

JPerl Advent Calendar Casual Trackに記事を書いたら長年悩んでいた問題が解決したでござるの巻

最近全然Blog更新しておりませんが、今回も単なる告知です。内容はタイトルのとおりです。EmEditorのPerlマクロに関する話です。周りが凄い人ばかりなので、ビビりながら書きました。

http://perl-users.jp/articles/advent-calendar/2009/casual/15.html

ちなみにユニコードを扱う方法が分からなかったのですが、id:xaicronさんがTwitterで話しかけてくださって、見事に解決してくれました。こんな感じ。

use utf8;
use Win32::OLE;
Win32::OLE->Option( CP=>Win32::OLE::CP_UTF8 ); #ここで指定
my $nihao = '你好!统一码';
$Window->OutputBar->writeln($nihao); #flagged utf8を直接渡す

flagged utf8を直接出力に渡すってのはちょっと気持ち悪い感じがしますが、EmEditorマクロの場合はそうしないと文字化けしてしまいます。

まあ、これでutf8が使えるようになり、アウトプットバーに中国語も表示されるようになりました。これでEmEditor上でのTwitterライフがさらに充実します。数日前に、Twitterがクラックされた際に、みんな面白がって、アラビア語をPostしてましたが、それもばっちり読むことが出来ました。

Win32::OLE->Option( CP=>Win32::OLE::CP_UTF8 );はPerlでExcel等を扱うときなんかによく使うみたいで、いやー勉強になりました。

情報を提供するよりもむしろ情報を提供してもらっちゃいました。Perl Mongersの文化は素晴らしい。てーかAdvent Calendarの方も追記して書き換えておかないといけませんね。

そのxaicronさんが、hacker Trackに寄稿した「Windows環境でUnicodeファイルを扱う」はPerlでUnicodeファイル名を扱うためのモジュールの話で、これも非常に勉強になった。前職で同僚が中国語ファイル名とか作ることが多かったから、これを知っていれば少し楽になった部分もあるなぁとか。

私もPAUSEアカウント申請して、申請も通ったので、来年はPerlモジュールを書いて念願のCPAN Authorになろうと思います。ネタは色々あるので今年中でも良いんですけど。

投稿者 Songmu : 23:19

2009年10月27日

ブログ上に数式を

とりあえずBlog上に数式を貼り付けたくなったので、ちょっと作ってみた。

gmath.js

Google Chart APIを利用しています。使い方は以下。

  1. jquery.jsとgmath.jsを読み込ませます。
  2. 数式を表示させたい部分にimgタグを置き、altにtex書式を書きます。また、class="formula"を指定します。
  3. onload時に$.gmath()関数を呼び出します。

ゼータ関数を表示させるにはこんな感じ。

<img alt="\zeta (s) = \sum^{\infty}_{n=1} { 1 \over {n^s}}" class="formula" />

\zeta (s) = \sum^{\infty}_{n=1} { 1 \over {n^s}}

KuaiWikiに組み込めば面白い感じですが、Google APIを使っているのでそれに依存するのはちょっと不安な感じ。Media Wikiは標準でそういう機能があるみたいですね。

てーか普通にこんなブログ記事も見つけてしまって、なんだか車輪の発明にもほどがある感じ。まあいいか。

投稿者 Songmu : 01:14

2009年10月11日

ロリコン判定一覧表出力ワンライナ

参考( http://twitter.com/Hamachiya2/statuses/703220972)

perl -e "printf qq{| %2d | %5.2f |\n}, $_, (3.1415926535 * sqrt($_)) for 0..99"

出力結果(左が年齢。右がロリコン認定年齢)

|  0 |  0.00 |
|  1 |  3.14 |
|  2 |  4.44 |
|  3 |  5.44 |
|  4 |  6.28 |
|  5 |  7.02 |
|  6 |  7.70 |
|  7 |  8.31 |
|  8 |  8.89 |
|  9 |  9.42 |
| 10 |  9.93 |
| 11 | 10.42 |
| 12 | 10.88 |
| 13 | 11.33 |
| 14 | 11.75 |
| 15 | 12.17 |
| 16 | 12.57 |
| 17 | 12.95 |
| 18 | 13.33 |
| 19 | 13.69 |
| 20 | 14.05 |
| 21 | 14.40 |
| 22 | 14.74 |
| 23 | 15.07 |
| 24 | 15.39 |
| 25 | 15.71 |
| 26 | 16.02 |
| 27 | 16.32 |
| 28 | 16.62 |
| 29 | 16.92 |
| 30 | 17.21 |
| 31 | 17.49 |
| 32 | 17.77 |
| 33 | 18.05 |
| 34 | 18.32 |
| 35 | 18.59 |
| 36 | 18.85 |
| 37 | 19.11 |
| 38 | 19.37 |
| 39 | 19.62 |
| 40 | 19.87 |
| 41 | 20.12 |
| 42 | 20.36 |
| 43 | 20.60 |
| 44 | 20.84 |
| 45 | 21.07 |
| 46 | 21.31 |
| 47 | 21.54 |
| 48 | 21.77 |
| 49 | 21.99 |
| 50 | 22.21 |
| 51 | 22.44 |
| 52 | 22.65 |
| 53 | 22.87 |
| 54 | 23.09 |
| 55 | 23.30 |
| 56 | 23.51 |
| 57 | 23.72 |
| 58 | 23.93 |
| 59 | 24.13 |
| 60 | 24.33 |
| 61 | 24.54 |
| 62 | 24.74 |
| 63 | 24.94 |
| 64 | 25.13 |
| 65 | 25.33 |
| 66 | 25.52 |
| 67 | 25.72 |
| 68 | 25.91 |
| 69 | 26.10 |
| 70 | 26.28 |
| 71 | 26.47 |
| 72 | 26.66 |
| 73 | 26.84 |
| 74 | 27.03 |
| 75 | 27.21 |
| 76 | 27.39 |
| 77 | 27.57 |
| 78 | 27.75 |
| 79 | 27.92 |
| 80 | 28.10 |
| 81 | 28.27 |
| 82 | 28.45 |
| 83 | 28.62 |
| 84 | 28.79 |
| 85 | 28.96 |
| 86 | 29.13 |
| 87 | 29.30 |
| 88 | 29.47 |
| 89 | 29.64 |
| 90 | 29.80 |
| 91 | 29.97 |
| 92 | 30.13 |
| 93 | 30.30 |
| 94 | 30.46 |
| 95 | 30.62 |
| 96 | 30.78 |
| 97 | 30.94 |
| 98 | 31.10 |
| 99 | 31.26 |

分かったこと。9歳までは年上が好きでもロリコンとなる可能性がある。

投稿者 Songmu : 11:46

2009年9月27日

Wiki作った

8月の夏期休暇中から作り始めていたWikiですが、一応一段落したので公開。

http://www.kuaiwiki.com/

記法の実装は2日くらいで終わったんだけど、それから記法の機能追加とか、細かい点の実装とかDBIx::Classの使い方を覚えるのとかで色々時間がかかってしまった感じ。完全にオリジナルと言えるコードは記法部分くらいなんですが。

作った経緯に関しては、この辺に書いてあります。

しかし、開発しながらBlog更新とかがんがん出来る人ってすごいな、と改めて思いました。自宅でパソコンに向かっている時間はほとんど開発に費やしてしまったから、全然Blog更新しなかったからね。YAPC::Asiaのレポートとかも書きたかったんだけど。まあ、これから書くか。

ソースコードも直に公開します。ただ、環境依存が強いんで、他の環境での設置は手間かもしれません。何せDBIx::Classが0.08100以降だと動きません。なんじゃそりゃって感じですね。

DBIx::Class::Schema::Loaderで読み込まれた設定に、手動でjoin設定とかを追加しようとすると上手くいかないみたいなのです。ちゃんとSchemaを生成する形にすれば良いと思うんだけど、とりあえずSchemaも固まってないし、保留。

投稿者 Songmu : 22:54

2009年7月25日

golf.shinh.orgの出題ミスの件

TAKESAKOさんの指摘にもあるように出題ミスみたいです。私も間違いに気づいて、強引に解答した感じ。で、正しい動きをするコードをどっかに載っけたかったのでここに書く。現状165B。

$c[0]=[];for$i(1..300){print"$i: ".(join" ",@{$c[$i]=(sort{o(@$a)<=>o(@$b)}map[sort{$b<=>$a}$_,@{$c[$i-$_**2]}],1..sqrt$i)[0]})."
"}sub o{$u=$#_*301;$u+=$_ for@_;$u}

ある数字に対する解答配列のサブセットが、必ず別の数字の解答配列になっているのでそれを利用して解いています。

でも、この問題だけど、63の時に解が二つ存在するみたいです。そうなる組み合わせがあるんじゃないかとは思っていたんだけど。その辺すぎゃーん氏のエントリに書かれています。

golf.shinh.orgは知ってはいたんだけど、@sugyan氏のTwitterを追いかけていて面白そうだったので、ちょっとはまっている。Twitterやってて最近では一番良かったことかも。次の問題もアップされたので解いてみようと思う。

ちなみに、ラングトンの蟻はどう書く.orgに投稿したんだけど、他の人の書いたコードを見られてかなり勉強になった。なでしこのコードとかもあって面白かった。

投稿者 Songmu : 01:49 | トラックバック

2009年7月10日

JavaScriptでラングトンの蟻

『単純な脳、複雑な「私」』を読んだのだが、その中に出てきた「ラングトンの蟻」が面白そうだったので実装してみた。

「run」を押すと動き出しますが、IEだと遅すぎて使い物にならないので押さないように注意。少し時間がかかりますが、カウントが10000を越えたあたりから急に動きが変わります。マシンスペックにも寄りますが終わるまで大体賞味1分くらいかな。ちなみに、スペックが貧弱なパソコンだとCPUをぶん回している状態になると思うので注意。

ソース

いやー、ちゃんと動いてますね。ちゃんと動いたときは我ながらちょっと感動しました。

ラングトンの蟻と言うのは、存在が環境に影響を与え、環境が存在に影響を与えるというモデルで、非常に単純な規則ながら面白い動きをします。最初はデタラメに動いていたものが、ある段階から急に規則的に動き出すというものです。

具体的な規則は、下記の繰り返しです。これだけです。

  1. 一マス動く
  2. 入ったマスが白だったら黒に、黒だったら白にマスの色を変える
  3. 入ったマスが白だったら右に、黒だったら左に方向転換

ちなみにこのプログラム、ビットマップ的な表現をするために、divボックスの中に3ピクセル幅のdivボックスをfloatで敷き詰めて、その背景色を変化させるってやり方をしてるんだけど、やっぱこれって効率悪いのかな?もっと良い方法があったら知りたい。

久し振りにスクラッチからJavaScriptを書いたので面白かった。そしてIEの遅さに改めて唖然とした。

投稿者 Songmu : 00:19

2009年6月21日

Sugamo.CSS#5

参加してきた。結論としては「あそこは自分の作業は進まん」と言うこと(笑) まあ、ちゃんと自分のお仕事をしてた人もいましたけどね。偉い。

考えてみると職業マークアップエンジニアがあれだけいるってのは感動的です。僕がCSSに一番はまっていたのって3~4年位前なんだけど、その頃は、マークアップエンジニアカッコワライの世界で、専業マークアップエンジニアなんて考えられない時代でした。「デザインも出来ないのにマークアップエンジニアって何なの?」っていう不遇の時代でした。

当時はCSS舐められてるなぁとか感じつつ、CSSくらいしかまともにできなかった私は、CSSだけじゃ喰えんよなぁと思って、デザインを勉強したりプログラムを勉強したりして今に至る訳です。結局デザインは身につかず、Perlが性に合ったので、その延長でプログラムを書く方に比重が寄って行った感じですね。

とは言え一定のデザインは出来るようになりたいです。相変わらず。


EmEditorネタが微妙にウケたのが良かった。EmEditorマクロネタ(ただしPerl限定)とかちょっとBlogに書いてみようかなと思ってみたり。

Yomotsuさんが相変わらずネタが豊富なのが素晴らしくて、今回持ってきたのは「svgのforeignObjectで外部のページを読み込んでsvgで反転させる」ってネタ。これがGoogleを反転させたデモページ。「これブックマークレットにしたら面白くネ!?」って感じで盛り上がった。

SigさんのVimネタも面白かった。僕はemacs使いたいなぁとか思いつつ、EmEditorです。EmEditorもカスタマイズしていくと機能的に限界を感じる事もしばしばあるんだよね。EmEditorマクロは機能を追加するだけで、エディタのコアな部分までカスタマイズ出来るわけじゃないので。

あと、話題になった出た本とか。

「ハッカーと画家」

Paul Grahamのコラム集。とにかく文が面白く、Lisp最強論が到る所で展開される。「もしかしてLisp最強なのかな?」と心から信じてしまいそうになるほどの文章の面白さ。

本書にも収録されている「ものつくりのセンス」は、本が出る前から各所で話題になった名文です。

他にもPaul Grahamのコラムは「Fine Software Writings」でいくつか読むことが出来る。そこで読んでみて、面白そうだなと思ったら、「ハッカーと画家」を買ってみると良いんじゃないでしょうか。

「JavaScript: The Good Parts」

JavaScriptがらみでちょっと話題に出た本。モダンなJavaScriptに関して非常に簡潔にまとまっていて、ちょっとJavaScriptに慣れてきたかなって人が読むと読み応えがあると思う。本の薄さに騙されて、JavaScriptを始めたばかりの人が買ってしまうと返り討ちに遭うと思われる。

Functionオブジェクトのprototypeにメソッドを生やしていたり、"new"は良くないPartだと言っているあたり、ちょっと好みが分かれる部分もありそうですが、確かにそうなっているのは一理あるなと頷ける内容になっています。

ただ、ビルトインオブジェクトのprototypeにメソッドを生やすのはお行儀が悪い行為だと言うのは割と最近主流になっている考え方かと思いますが、そこに制限がかかるとprototype型言語としてのJavaScriptの魅力が損なわれてしまう部分もあるのではないかなぁと個人的には感じています。

for inが使えないと言うのであれば、イテレーション用のeachメソッドとかをprototype側に持たせれば良いだけの話。もしくはfor inに引っかからないようにするプロパティがJavaScriptの言語使用側に加われば良いと思う。メソッドがバッティングすると困るのは確かなので、やりすぎは良くないと思うけど。

そもそも、JavaScriptではビルトイン型の継承が難しいのも問題があって、

MyDate.prototype = new Date();
MyDate.prototype.constructor = MyDate;

とかやっても、ジェネリックじゃない関数(Dateの場合ほぼ全ての関数)がMyDateに引き継がれないといった現象がある。そうなると、頑張ってapplyしてprototypeにメソッドを生やしなおすより、Dateのprototypeを拡張したほうが楽じゃん、とか思うんですよね。

話が横道にそれた。「JavaScript: The Good Parts」は好みが分かれると思うけど、だからこそJavaScriptをそこそこ学んだ人は読んでおいた方が良い本だと思う。

「複雑系入門」

話題にはならなかったけど、複雑系の本が少し話題になっていたので、個人的にオススメの本を一冊。

その名の通り複雑系を大まかに知るためには非常に良い本。複数のテーマ毎に具体的事例が取り上げられていて複雑系に馴染みが無い人にも読みやすい。

個人的に面白かったのは、いろんなものがべき乗分布で捉えられるという項目。都市の人口ランキングや英文の単語の出現頻度を、対数のスケールでグラフにプロットしてみると見事に一直線に並ぶのです。そういう何気ない部分にも隠れた法則を見つけられると言うところに驚いたことを覚えています。

しかし、この本を読んだのももう10年前だ。


Sigさんが自転車で来ていたので、私も次回は自転車で行こうと思う。雨が降らなければ。

しかし、Sugamo.CSSめちゃくちゃ居心地良いんですけど。主催者のSigさんには超感謝。

投稿者 Songmu : 23:26

2009年6月17日

凝りもせずAkamai勉強会第2回

凝りもせず参加してきた。yasuyukiさんとgeekpageのあきみちさんから「次回もまた是非参加してください」とありがたいお言葉をいただき、素直に信じて参加してきた。

会場提供のDeNAさんには本当に感謝です。ただでさえDeNA社内に入れるってだけで大興奮モノでした。新宿のオフィスビルに複数フロアに跨って入っていて、しかも内装がおしゃれ。非常に勢いを感じさせました。

勉強会の内容的には改めて驚きの連続でした。技術的な側面はともかく、印象に残ったのは、Akamaiの社是として

「インターネットを予測可能で、信頼のできる、予測可能なものにする」

というものがあるというものでした。単なる理念だけじゃなくて、社是になっているって言うのが驚きで、Akamaiの国谷さんも「社是があるってのはアメリカのしかもベンチャー企業としては非常に珍しい」とおっしゃってました。

Googleの「don't be evil」とかもそうだけど、そういう技術馬鹿的な側面(?)を貫いて成功しているって言うのは、日本人からしても好ましいな、と思った。


懇親会も盛況で楽しかった。どこ言ってもいろんな話で盛り上がっていた。あっと言う間に11時半になった。

サイボウズの奥さんもいらっしゃっていて「クラウド的な手法でハッシュはダメだよ(笑)」とか言いながらMySQLと最近作り始めたと言うPacificの話をしていたのが、スゲー面白かった。

他の人の話を聞いても思ったけど、コンテンツとしての自分はまだまだ貧弱だなぁと痛感しました。そういうレベルで語れる内容が無いんだもんよ。

投稿者 Songmu : 00:00

2009年5月16日

Sugamo.cssに行ってきた

週末プログラミングをするには良い機会だと思い参加。Web製作会社の人と話をする機会って実はあまり無いので有意義だった。私が普段関わっているようなプログラマーの人たちとは大分ノリが違ったのが意外でもあり面白くもあり。

ネタとして今作っているJavaScriptベースのAIRアプリを持っていった。話を始めたらみんなが続々僕の後ろに集まってきて、説明する心の準備ができていなかったんでちょっとキョドってしまった。もっと丁寧に説明出来れば良かったんだけど。

お互いのノウハウ公開では、クリップボード拡張とか複数台のパソコン環境をdropboxを使ったりして共有するとか、その辺が興味深かった。

個人的に最近エディタマクロを書き散らしてるんだけど、パソコンによって入っている入っていないがばらばらで結構困っているのでなんとかしようとは考えてはいたのです。

あと、多くの人がローカルでの作業で上手くPerlやRuby等のスクリプト言語を活用しているようでした。こういうのって案外平均的なプログラマーはやらないと思うので、特定の局面では下手なプログラマーよりコード書けるんだろうな、とも感じた。

話が弾んでしまって、思ったより自分の作業は進まなかったけど、それもまた好し。

投稿者 Songmu : 23:32

2009年4月24日

美味しいソースの作り方

Cookpad&カヤック主催の技術者交流会に行ってきた。Cookpadにしても、カヤックにしても、この時期に採用を拡大していて元気だよなぁ。結構名刺交換した。最近勉強会に結構参加してるから手持ちの名刺が少なくなってきた。ヤバイ。個人の名刺作ろうかな。ずっと考えてはいるんだけど。

料理美味しかったです。どんぶりが余っていたので、3杯食べました。以下、話した事や聞いた事など。

PerlからFlash

カヤックはPerlをかなり使っているみたいでした。Flash Media Serverのサーバーサイドの実装を通常のActionScriptではなくて、Perlで書いたフレームワークKamaitachiはおおっと思った。

それを使って、ユーザーがActionScriptのコードを動かせるWonderflというサイトを作っているみたいです。これはActionScript書く人にとっては堪らないサイトですね。

先日のShibuya.pmでもSandBoxの話出たけど、これもセキュリティ対策とか大変そうだな。サイト閲覧者を攻撃出来るようなコードも書けそうだし。

カヤックが会社としてオープンソースに関わっていることのメリット

  • 社内にCPANモジュールのコミッタがCatalyst関係一人、DBIx関係一人、Plagger関係一人といる。
  • Catalystを使っている会社だと認知してもらえれば、Catalyst関係の技術者の応募を期待できる。
  • 採用者に対しても、勤務開始前にオープンソースとして公開しているモジュールを勉強してもらえる

カヤックでJavaScriptメインで書いている技術者の方と話した事

  • もともとPerlが好きでPHP書くのがイヤだから、JavaScriptメインになった
  • やっぱjQuery。jQueryはjQueryという言語の中でDSLとしてJavascriptを使うようなもんだ(笑)
  • 社内の技術者の中でJavaScriptを書くかActionScriptを書くかは意外にもすっぱり分かれている
  • 年間100以上のサービスが生まれるから、サービス管理自体が一仕事

投稿者 Songmu : 23:11

2009年4月22日

低レベルだけど高レベル Shibuya.pm#11

行ってきた。リクルートの大きな会場でした。

tokuhirom氏が言っていたようにレベル高すぎ(笑)で全然わかりませんでした。機械語とかCとか低レベルな話が多かったんだよね。

最初が小飼弾氏のPerlを動かすSandBoxの話で、「この人の話はレベル高くて理解出来ないのは仕方ないかな」とか思っていたら、後から思うとPurePerl以外の話で一番理解出来たのはこの話だったかも、と言う。

clkao氏の発表が個人的には一番役立った。Devel::NYTProfを使うとLine levelでのプロファイルができて、しかも、eval実行文字列の中でもLine levelでのプロファイルできるよ! というお話でした。

最近ちょっとPerlに自信を持ってきたところにその自信をへし折られた感じなのでちょうど良かったかも。

初めてたかだフレンドのクラブランにささやかな自信を秘めて行った時に、見事にぶっちぎられて引きずりまわされた事を思い出しました。そのあと、たかださん(店長に)「(初めてにしては)結構速いらしいじゃん」とかお褒めに預かって、「くそーちきしょー」とか思ったのを覚えています。

今の自分がどんなにやってもがんばっても越えられないように思える壁を見せ付けられるってのは良い経験。「やれば出来る」とか思うこと自体が無駄なんだと言うことを思い知らされます。そう思う前にやれ!ってことですよ。

投稿者 Songmu : 23:06

Akamai勉強会の記事を修正した理由、勉強会へ参加する際の意識付けとか

勘ぐられても困るので書いておくと、別に書いちゃいけない内容があったというわけではありません。

  • せっかく機会を設けてくださったAkamaiさん、企画した方々にあまりにも失礼な書き方があった
  • 誤解(特にAkamaiさんへのマイナスイメージ)を与えかねない表現・間違った記述があった

というところに反省して書き直した次第です。

勉強会では「こんなことBlogとかに書いちゃって良いんですか?」とたじろぐ参加者の面々をに対して「これくらいだったら平気ですよ」とAkamaiの方はおっしゃっていて、そこにもAkamaiの底知れなさを感じました。

勉強会はオンレコ、その後の懇親会はオフレコという切り分けはしていたつもりですし、勉強会の中で出たきわどい質問に対してサービスで答えてくれた分に関しては書いていません。というより、そのあたりは技術的に込み入った話なので、あまり理解していません。

それに大げさに書きすぎた部分もありますが、こんな誰でも行ける勉強会でそこまでクリティカルな内容なんて出てません。

今回、どうしてこういうことをしてしまったか

2chや個人のBlogに「イ○ローテラ鬼畜ww」、「任○堂がマジ○ンをフルボッコww」等(あくまで例えです)の記述がされることは少なくないと思います。

その言葉遣い自体も問題ですが、それらとは違い今回それ以外に大きな問題だったのは、勉強会を企画した方々を侮辱するような行動になってしまった点です。

それはどうしてかと振り返ってみると、結局自分の当事者意識が足りなかったというところに尽きるのかな、と思いました。

私にはどうしても傍観者、観察者になりたがる部分てのがあります。でも、テレビ等を見ているのとは違って、勉強会への参加ってのは当事者になることなんだってことに気が付きました。

そういう当事者意識をしっかり持っていれば、今回みたいな行動は起こさなかったのではないかと反省しています。

コアになって企画する人たちとは違って、私みたいな勉強会をつまみ食いしている人間はその辺りの意識が希薄になりがちなので、注意が必要だと痛感した次第です。

投稿者 Songmu : 12:50

2009年4月21日

Akamai勉強会の追記というかお詫び

完全に予想外の反響に驚くとともにビビッています。これまでまともにブクマを受けたこともないので、まさか半年分のアクセス数を一日で稼ぐことになるとは思いませんでした。いつもの感覚で、勢い重視で面白おかしく書いたところが、あおってしまった部分もあるのでしょう。反省しています。フィード購読者も増え、こうなると書く内容に責任も発生してしまうな、と多少途方にくれています。

プライベートセミナーなのにレポートのページにこれだけアクセスが集まってしまったのは申し訳なく思っています。geekpageさんも書くと言っていたので、私のBlogなんてたいした影響力が無いとタカを括っていました。すみません。


タイトルに当初「鬼畜」という言葉を使っていました。親しい仲で「おまえ鬼畜過ぎ」というのとは違って、初対面に近い方に向けて使うのはあまりにも非常識だと反省しタイトルを変更した次第です。

せっかくお話してくださったAkamaiさんには本当に失礼な書き方をしてしまって申し訳ありませんでした。

そして、せっかくセッティングして下さったyasuyukiさんその他関係者各位に不快な思いをさせてしまったことを深くお詫びいたします。


Akamaiはそもそも、ティム・バーナーズ・リーが

「インターネットの負荷を均衡させ、インターネットの信頼性を向上させる技術」

が無いかと提案していた背景があり、その理念に応える形でAkamaiがMITの研究室で生まれたいうことでした。

そういう理念のもの生まれた企業なので、決して悪の存在ではありませんし、むしろ間逆です。

どんなに企業が自前でシステムを冗長化しても、信頼率は99.999...にしかならないし、レイテンシの問題があるので、距離的な問題を解消できない。

そこでAkamai化すれば100%だし、レイテンシの問題を解決できる。顧客企業が信頼できるコンテンツの配信が出来るようにお手伝いします、ってのがAkamaiのやっていることです。


指摘を受けているように記述には誤りもあると思います。「ルーティングはしていない」という指摘もありました。

実際やっていることは、Edgeサーバー同士のピアリング(キャッシュのやり取り等)と、DSNを動的に書き換えてユーザーから近いキャッシュサーバーを割り当てているってことですね。

詳しくは識者のフォロー等を待ちたいところです。

無秩序なP2Pは困るけど、AkamaiのネットワークはP2P的でありながら管理されているので理想的なのかもと言う話も出ました。


IPv6対応は「正直かなり大変です」と言っていました。ISPレベル・国レベルでの思惑、利害が絡み合っており、上のレベルで号令を取れる存在もないので。

ただ、こういう時こそAkamaiやGoogleみたいなところの存在意義が問われるんじゃないか、とも思います。(悪い意味でなく)独占的であるところのメリットと言うか。もちろん、両者ともそれに備えて動きはしてるんでしょうけど。


以上です。色々すみませんでした。好感を持っていた人に、悪く思われてしまったなぁと感じるのは...、堪える。

投稿者 Songmu : 12:49 | トラックバック

2009年4月20日

ThunderBirdのアドオンをいくつか

職場のメーラーはThunderBirdを使っている。ThunderBirdはSpamフィルタが標準状態でも優秀なのが嬉しい。Gmailとかちょこちょこ判定ミスるけど、ThunderBirdはしばらく使うと殆どミスらない。てことでオススメのアドオンをいくつか。

Lightning

カレンダー&Todo管理ツール。ThunderBirdを使うならこれが無いと始まらないくらいの感覚。これを使えば仕事関係の情報をThunderBirdに集約できる。

ただ、ちょっと開発が活発じゃなくなってるようで残念。機能的に物足りない点も結構ある。

iCal形式を(イン|エクス)ポート出来るのも便利。勤務実績登録用のカレンダーを作成して、毎月末にiCalファイルをエクスポートしたのをPerlで解析して、その月のプロジェクト毎の稼動時間とかを集計するのにも利用している。

でも、エクスポート時は全部の予定が出力されるので、一月分だけエクスポートとかそういう柔軟さが欲しい。エクスポートしたデータを再インポートすると同じ予定が2個できたりするし。

あと、複数日に跨る予定をガントチャートっぽく表示できたりして欲しい。

Contacts Sidebar

これは標準でついててもおかしくない機能。Gmailなんかそうなってるけど、左のサイドバーにアドレス帳を表示させて、クリックしたらその人宛にメールを書く事が出来るというもの。F4キーで表示をトグルできるので、フォルダを見たいときはすぐに消せる。

Xnote

Becky!やNotesクライアントは送られてきたメールの本文を自分で編集できたりする。送られてきたメールに情報を書き加えたり出来たり、件名がいじれると記号を付けて強調できたりするのが便利です。

ThunderBirdはそれが出来ないんだよね。タグとかはあるけど。確かに他人のメールを変更出来るのは問題がある気もするし。

で、それを解決するのがXnote。これは、メールの本文に付箋みたいなのを貼り付けられて、そこに補足情報を書き込むことが可能です。本文に書き込むのと違って自分が捕捉した情報だってこともすぐに分かります。

ただ、ちょっと問題がある。まずは、その付箋部分は印刷されないこと。そして、付箋部分は検索出来ないということ。その辺が残念。

withAttach

何気に便利な添付忘れを警告するソフト。"attach"とか本文中に入っているのに、添付ファイルが無いと送信時に注意してくれる。デフォルトでは英語のキーワードしか入ってないけど日本語の追加も可能。「添付」とか「写真」とか。

メールの作成を始めるときに「添付付きで送付する」ってオプションも選べるようになり、これを選ぶと添付漏れを警告してくれる。

投稿者 Songmu : 23:40

2009年4月19日

EmEditorのススメ

EmEditorのマクロにPerlが本格的に使えることを最近知って、今まで何を無駄な事をやってきたんだろうと愕然としている今日この頃。

エディタは昔は秀丸だったんだけど2003年くらいにEmEditorに乗り換えた。当時秀丸だとgrepで中国語が引っ掛けられなかったのと、確かgrep置換がEmEditorが先に実装されていたからだった。

でも、機能的には大差ないはずなんだけど、EmEditorって秀丸に比べると大分知名度が落ちる。ネット上の情報も少ないし。職場だと秀丸は多いけど、EmEditorを使っている人どころか知っている人すら居ない。前の職場もそうだったな。

先に定番化してユーザーを獲得しちゃったから乗り換える人も少ないのでしょう。秀丸はシリアルが出回っちゃってるからとりあえず最初はそれで使うって人が多いのかも知れないし。あと、EmEditorは書籍が無いなぁ。執筆の話は出てるみたい。期待。

つまり後発で同等の機能の製品だと、どんどん差が開いていく一方ってことですかね。

でも以下のような点が優れているので、EmEditorは一押しです。

  • マクロがPerl(その他色々)で書ける
  • シンタックスハイライトが最初から色々揃ってる(VBScriptとかもある!)
  • 多言語対応がすごい。utf8で中国語検索が可能なだけじゃなくて、GB2310とかBig5とかも!
  • 正規表現がPerl互換で強力!(秀丸は"\b"(単語境界)とか対応してなかった気がする。変数名とかでプログラムコードを検索するときなんかに"\b"は便利)
  • 単語補完が強力
  • 外部ツールとの連携もしやすい
  • アウトラインとかプロジェクトツールバーが便利(らしい)

てな感じ。

投稿者 Songmu : 23:36

2009年4月18日

Twitter再開というか本格開始(かな?)

職場で調べ物とかしているときに気づいた事とか、メモっておきたいとか、ちょっと言いたくなる事がある。例えば以下のような感じ。

  • Windowsだと"con"とか"aux"とかのファイル名って付けられないんだ!今更知った。
  • SQL Serverに複文SQL投げるときにセミコロンで区切らなくて良いとかおかしくね?おせっかい機能がセキュリティホールの原因になっているというMSにはよくあること
  • オフィス用のサンダル買わなきゃ。ピュアウォーカーってやつが気になる

こういうのってTwitter使えば良いじゃんとか思って、職場のエディタマクロと「ファイル名を指定して実行」から投稿できるようにした。こういう仕組みを作ると使いやすくなるね。

ユーザー名は"songmu"です。気が向いたらフォローして下さい。

ついでに、このBlogの右にも最近のつぶやきが出るようにした。Flash版だと幅が足りなかったのでHTML版。デザインもあわせやすいしね。というか、そろそろデザインも全体的にいろいろ何とかしないととか思ってはいるんだけど...。

投稿者 Songmu : 23:01

2009年4月17日

Akamaiが想像以上に物凄かった件 in Akamai勉強会

続きというか、お詫びを書きました。

文章を多少修正しました。技術的な点は色々誤りがあると思いますので、あまり信用しないでください。詳しくはgeekpageさんがじきに書いてくださるはずです。


入口にあった、Akamaiサーバーがリアルタイムに捌いているトラフィックを可視化した地球儀が映ったモニター。アメリカが早朝なのでトラフィックは850Gbpsと少な目(笑) それでもアメリカのバーの長さは凄い
やすゆきさんという方が、Blogでひっそりと告知していたのが、IT勉強会カレンダーに載っていて、それを目ざとく見つけて行ってきた次第。募集枠5人とかだったので、焦って申し込んだら、実際そんなに募集は来なかったみたいで意外。僕なんか「Akamai」って書いてあっただけで飛びついたのに。内輪に近いノリだったてのもあると思うけど、案外「Akamai」には訴求力が無いのかね。まあ、インターネットの裏の支配者って感じだからね。

参加者はgeekpageの人とか、生涯一プログラマの吉岡さんとか、SFCでネットワーク専門にやってる学士の人達とか少人数ながら錚々たる面子。

Akamaiの中の人が色々話してくれたんだけど、参加者からは矢継ぎ早に質問が投げかけられ、非常にホットな勉強会になった。私も質問するタイミングを図るのが大変でした。

参加者全員が「来て良かった」「想像以上だった」と大興奮な内容で、勉強会終わった後の懇親会でもAkamaiの方への質問は終始絶えなかった。

ここには書けないような話題もあったので、書ける範囲で書く。技術的な面は、他の人の方が詳しいだろうので、それ以外のところ。

Akamaiとは?

インターネット接続の不安定さを解消し、顧客企業のWebコンテンツ配信の信頼性を高めるサービスを展開している世界最強のCDN。

独自のコンテンツキャッシング技術、ピアリング技術、キャッシュへのDNS動的割り当て技術等によって、顧客企業のWebサイトを「Akamai化」することにより、コンテンツ配信の信頼性を100%(99.999%ではない!!)保証している。アメリカで100%を謳うとかありえない!

オライリーの「ハイパフォーマンスWebサイト」には、米国トップ10サイト中5サイト(amazon, aol, ebay, myspace, yahoo)でAkamaiを利用と書いてありますが、今やもっとすごい状況になっているみたいです。アメリカの国防総省も使ってるみたい。これはWikipediaに載ってるから書いてよいよね。

最近はゲーム業界も大手はほぼ全てがAkamaiを採用していて、Akamaiにとっては美味しい状況だとか。確かに、オンラインゲーム切れたらまずいもんな。

Googleと同い年!

Googleと同い年だそうです。インターネットの表と裏の支配者がほぼ同時にスタートしているってのは興味深いですね。

ちなみに、アート引越しセンター理論と同様に「A」から始まる名前にしたかったとかで、ハワイ語の「Akamai」にしたんだそうな。英単語でAから始まるものなんて当然ながら全て他の企業に押さえられていたわけです。ちなみに「Akamai」は、CleverとかInteligentとかいう意味なんだそうだ。

世界のWebトラフィックの15%程度をさばいている!

2009年3月現在、世界全体のインターネットトラフィックは、20Tbpsくらい。その中の10TがWebで使われていて、有効活用されているのは7Tくらい。その中の1TbpsをAkamaiはさばいている。つまり世界のWebトラフィックの15%程度をさばいている。

去年の末で、トラフィック総量が15Tbpsくらいだったらしいので、今も指数関数的な勢いで世界のインターネットトラフィックは伸びている。また、Web関係じゃない残りの10Tbpsのトラフィックの中で、利用が目立つのはP2P。

オバマ大統領の就任演説ストリーミングにもAkamaiが利用されたようで、そのときは世界同時700万アクセス、2Tbpsのトラフィックをさばいたそうな。

ちなみに日本の国会中継のストリーミングは同時接続500でダウンするらしく、そんなのに何億円もかけててアホかと。

個人的にはもっとさばいているのかなと思っていたのだけど、Akamaiとは関係のない個人のWebサイトとかそういうロングテールの部分がWebでは大きいんだなぁと改めて認識。

独自のデータセンターやネットワークを持っている訳ではない!

これは皆驚いていました。ISPにAkamaiのEdgeサーバーを置いて、それらを連携させることによってサービスを実現している。今や世界の半数以上のISPに総計4万台のサーバーを置いているのだそうだ。でもたった4万台。これも驚き。

つまりAkamaiはISPに間借りしているわけだけど、ISPからしてみても、Akamaiのサーバーを置く事にはかなりのメリットがあって置きたがる。Akamaiサーバーが外部コンテンツのキャッシュしたりキャッシュされてない情報もピアリングしてきてくれることによって、外部とのトラフィック(=通信費)を抑えることができるから。ISPは隣接しているISPとの通信状況しか分からないわけだけど、Akamaiサーバーは全世界のネットワークの状況が分かる訳なので。

各Akamaiサーバーの状況は、20秒毎に更新され把握出来るようになっていて、冗長化も遠隔管理体制もばっちり。多少落ちても痛くも痒くも無い。リモートでOSをインストール(!)出来るようになっていて、必要なときは一部Windows機に切り替えたりもするみたい。仮想化は検討中だがまだやっていないとのこと。

ビジネス特許も強い!

Akamaiが強い理由として、そのデファクト的な強さのほかに、パテント的な観点もある。技術的な特許のほかに、そのビジネスモデル自体にビジネス特許がかかっていて、競合の参入が難しい部分があるようです。

「秘密結社Akamai」とかそういうジョークも飛び出していました。

動的コンテンツもキャッシュ出来る!

これもすごい話。CDNというと、静的コンテンツのキャッシュのみという印象がありますが、Akamaiは顧客企業から情報をもらうことによって、Akamaiサーバーで一部の情報を処理することも可能みたいです。

ショッピングサイトなんかが混み合っているときに、これまでの行動履歴から購入意欲の少なそうだと判断した人はAkamaiサーバーのエラーメッセージで止めてしまって、購入意欲の有りそうな人に優先的に実サーバーへのアクセスを割り振るなんてこともやっているとのことでした。

もちろん上に書いたようなことは何れもサーバー側の自動処理なので、社員はそういう情報を見たりは出来ない。Akamai社員がAkamaiサーバーに実際に触る事自体に社内的な規制がかなりかかっているみたい。

その他

ユーザー毎にDNSを動的に書きかえる技術なんかも驚いたけど、これについてはもっと正確に解説出来る人がいると思うのでここで多くは書かない。

中国にも現地法人があって、Akamaiサーバーは置いてあるけど、デフォルトでは機能はオフになっている。中国政府にコンテンツの審査を申請して、一ヶ月位したら許可が下りてやっと公開できるという流れになるらしい。

ただ、共産圏には基本的にはAkamaiサーバーは置かせてもらえないらしく、例えばロシアには置かれていない。中国は実はどちらかというと寛容で特殊な例。

Akamaiのサーバーが攻撃されても、もともとISPにAkamaiサーバーを置く際に、そのISP自体のトラフィック許容量よりも高い許容力をサーバーに持たせるので、Akamaiサーバーが落ちるよりも早くISPが落ちる(笑) もちろんそんなことになる前に攻撃を弾いたり他のサーバーに流したりとかやりようはいくらでもある。いわば、全世界に40,000台のファイアウォールがあるようなもの。

数年前にAkamaiが落ちた事があったけど、その原因を聞いてしまった。リンク先にあるようにDoS攻撃が原因ではないみたいです。流石にこれ以上はここには書けません。

修正点について 2009/04/22 12:25

  • タイトルがあまりにもひどかったので修正しました。
  • 「ルーティング」の記述誤りを「ピアリング」等適宜修正しました。また、ルーティングをしているように思われてしまう箇所を削除しました。
  • 「Akamaiはインターネットの動向、ひいては業界の動向が丸分かり」というようななことを書きましたが、Akamaiサーバーがキャッシュしているのは顧客サイトの情報だけに過ぎず、また、内部統制や仕組み上、Akamai社員がそういう生の情報にアクセスすることは不可能なので、誤解を招くような文章(株を買っちゃ駄目、等)を削除しました。
  • ビジネス特許の話は、私自身がビジネス特許への理解があいまいだったのと、それも原因となり余計誤解を招く文章になっていたこと、文章があまりにもひどかったこともあり、全面的に書き直しました。
  • SSLキーを預けているかは定かではなかったので、削除し、書き直しました。単にSSLを含めた動的コンテンツの一部もキャッシュ出来るということが驚きだったということです。

投稿者 Songmu : 22:48 | トラックバック

2009年4月10日

コードブロック引数をオプションにできたら嬉しいんだけど

Perlに標準バンドルの配列操作のモジュールList::Utilにmax関数てのがある。List::Utilは便利なモジュールでPerlベストプラクティスでは積極利用を推奨していて、その辺の事はこの辺でも紹介されている。

で、なんとなくこんな使い方出来ないかなとか思ったけど無理でした。

use List::Util qw/max/;
...
my @lines = <$fh>;
#my $max = max {length} @lines; #こう書けたら超美しいと思うんだけど!
my $max = max map {length} @lines; #こう書くしかないのが残念

つまり、sortみたいにコードブロックを引数で持つ事もできて、渡さないときはデフォルトの動きをする、みたいな感じだったら良かったなぁ。

でも、考えてみると、Pure Perlでそれを実装する方法って無いのか。プロトタイプで&を指定するとコードブロックが省略できなくなっちゃうしな。ちょっと残念な感じ。XS使えば出来たりするのかなぁ。

投稿者 Songmu : 23:45 | トラックバック

2009年4月 9日

真か偽かは状況次第ってのは真理ではあるんだけど

Perlの真理値関連で若干はまったので書き留めておく。

my $hoge, $fuga;
$hoge =  $fuga  = 0; # $hoge: 0, $fuga: 0
$hoge = ($fuga) = 0; # $hoge: 1, $fuga: 0

下の代入では、リストがスカラーコンテキストで評価されているので、要素数の1が入る。少し考えるとなんでこうなるかはわかるんだけど、Perl的な考え方が自分に浸透してないと戸惑うね。

この関連でサブルーチンから値を返すときに、return undef;とかやるとハマるってのがある。

sub hoge{
    return undef;
}
my $hoge = hoge();
my @hoge = hoge();
 
print 'scalar' if $hoge;
print 'array'  if @hoge; #こっちは表示される!

@hogeは要素数が1の配列なので、ifに渡されると評価が真になってしまう。

こういった挙動を解決するための、Perlベストプラクティスでは、「裸のreturnを使う」ってのが推奨されている。でも、return;だとなんだかサブルーチンが正常終了したように見えてしまう。なので、return ();と書いたほうが、空の値を返していることが明確なのでこっちが個人的ベストプラクティス。return $hoge || ();みたいな書き方も出来るしね。

sub hoge{
    return ();
}
my $hoge = hoge();
my @hoge = hoge();
 
print 'scalar' if $hoge;
print 'array'  if @hoge; #どちらも出力されない

ただ、この場合にもちょっとしたはまりパターンがある。mapを使って配列の要素を一括変換かけるときなんかは、判定で偽になっても、場合によってはundefを結果セットに突っ込んで欲しいことも有り得るが、それがうまくいかない。

sub removeNaN{ #数字以外を削除する
    my $num = shift;
    return () unless $num =~ /\d/;
    $num =~ s/\D//g;
    return $num;
}
my @array = qw/10g 33 66m p151 hoge 9/;
my @nums = map {removeNaN($_)} @array;
print join ' ', @nums;#10 33 66 151 9 #要素数が減ってしまう!

こういうときは、明示的にreturn undef;と書かないといけないんだろうな。

最近はPerl5に真理値型がないってのはちょっと不便な気もしてきた。「世の中に絶対的な真とか偽とかはない、それはコンテキストで判断されるのだ」っていうPerlの考え方は好きなんだけど。

投稿者 Songmu : 22:20

2009年4月 2日

イントラ上で印刷禁止のページを印刷させない方法

社内のイントラ内で公開されているドキュメントで「印刷禁止」とかなってるものがあるじゃないですか。

そういうページにはCSS内でこんな指定をしておいて、印刷されたくないhtmlに<body class="unprintable">とか書いておけば、そこそこ印刷を防げると思う。勿論ちょっと細工すれば印刷は可能なんだけど、こうしておくだけでもハードルはあげられる。

@media print{
  body.unprintable{display:none;}
}

でも、そしたら「印刷禁止のページも印刷できるようにするbookmarklet」とかが出回ったりするのかも知れないなぁ(笑) 技術者って必要がなくても制約があったら破ってみたくなるもんだし。

本当に印刷されたくなかったら印刷不可PDFを使いましょうってことで。

ちなみに"unprintable"って英単語は適当に考えたんだけどちゃんとあるんだね。でもちょっと意味合いが違うみたい。イヤーン。

投稿者 Songmu : 23:59

2009年3月19日

お前どれだけPerl好きなんだと自分でも引くわ

マスタリングPerl」を発売日に買った。同僚に「何の本買ったの?」と聞かれて、

「今日発売のPerlの本」

と答えてる自分に引いた。ちなみに「モダンPerl入門」も発売日に買ったと思う。「モダン Perl」で検索で来る人が結構いるのでちゃんと書評を書こうとか思ってたり思っていなかったり、思っているうちに時期を逃したり。

最近正規表現とPHPで祭りになってるけど、多くのPHPプログラマはコピペ好きだからね。と言うか初心者が多いからコピペ使用率が高いのか。

未だにsession_cache_limiter('private must-revalidate');だなんて間違ったおまじないがまかり通っていたりするし。

コピペするより自分で書いた方が速いってことに早く気づけば良いと思う。正規表現なんてぱっと見難解だけど、実はたいして難しく無い。

ただ、正規表現はちゃんとわかって無いと「一見正しく動いているように見える正規表現」が簡単に出来てしまうので、そこが本当に危険。以下正しそうだけど全然正しくない正規表現の例。

#英数字8~16文字のIDチェック(のつもり)
/[a-zA-Z0-9]{8,16}/               #先頭と末尾のチェックを入れていない!
#簡易IPアドレスチェック(のつもり)
/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/ #ドットをエスケープしていない!

Web系のエンジニアにとっても、今や正規表現なんて必須なんだから、先ずは「ふくろう本」を一回しっかり読めば良いと思う。この本はオライリーのこの厚さの本にしてはかなり読みやすいし。

あとは普段のエディタ編集で、正規表現を常用していれば自然と身につくんじゃないかなぁと思う。

投稿者 Songmu : 22:50

2009年3月15日

Perlのサブルーチンプロトタイプについて

プログラミングPerlとPerlベストプラクティスを読み返して勉強しなおした。概要としてはこんな感じ。

  • サブルーチンの引数の型を指定出来るようになる
  • 暗黙的にリファレンス渡しができるようになる

例えば、組み込み関数のpushは第一引数に配列を取るが、暗黙的にリファレンス渡しになっている。(引数リストとして展開されない)

このような挙動は通常のPerlのサブルーチンの仕組みでは実現できないが、プロトタイプを使うと実現できる。

sub my_push(\@@){
  my ($arr_ref, @arr) = @_;
  for(@arr){
    $$arr_ref[$#$arr_ref+1] = $_;
  }
}
my @test_arr = (1,2,3,4,4);
my_push(@test_arr, 1,2,3);
print join ',',@test_arr; #1,2,3,4,4,1,2,3

ただし、サブルーチンを呼び出す時に&(アンパサンド)をつけるとプロトタイプは無視され、引数指定を無視してもコンパイルエラーにならない。なので、アンパサンドをつけた関数呼び出しは一切しない方が良い。

昔は、自分で定義したサブルーチンは組み込み関数と混同しないように、アンパサンドを付けるのが流儀だったが、今はアンパサンドをつけないのが主流。

その代わり、組み込み関数は括弧無しで呼び出して、ユーザー定義サブルーチンは括弧付きで呼び出すと言うのが流儀。

join ',', @array;           #組み込み関数
my_subroutine($hoge, $fuga); #ユーザー定義サブルーチン

そもそも、ファイルハンドルも$付きが推奨されている昨今、コード内に裸のワードは組み込み関数とサブルーチンくらいしか出てこないのである。

open my $fh,'<','hoge.txt';

勿論、自分が定義したサブルーチンを裸のワードで使っていると、将来的に定義された予約語、組み込み関数とバッティングする可能性があるが、そんなサブルーチン名を定義しない or ちゃんとオブジェクト志向モジュールにする、という対策をしておけば問題は起こらない。

しかし、プロトタイプは意図しない挙動をして混乱を招きやすいので使わない方が良い。例えば以下。

sub max($$){
  my ($arg1, $arg2) = @_;
  return $arg1 > $arg2 ? $arg1 : $arg2;
}
print max(3,5);   #5が出力
my @hoge = (3,5);
print max(@hoge); #エラー:Not enough arguments!

no strict 'refs';と感覚的には同じで、上級者向けって感じかな。例えば、&を使ってサブルーチンリファレンスを引数として持たせると新しい構文を作り出すことが出来て面白い。以下、プログラミングPerl p263より引用。

sub try(&$){
  my ($try, $catch) = @_;
  eval { &$try };
  if ($@) {
    local $_ = $@;
    &$catch;
  }
}
sub catch(&){ $_[0] }
#実行
try{
  die "phooey";
}
catch{
  /phooey/ and print "unphooey\n";
};

Perl6では他の言語同様サブルーチンの引数付き宣言も出来るようになるみたいだけど、個人的には従来の引数の指定方法は好き。Perl覚えたての頃は奇妙に思えるけど、そっちの方が引数がその関数ブロックの中のスコープにあると言うことが分かりやすいから。

sub my_sub{
  my ($arg1, $arg2) = @_; #$arg1と$arg2が関数内ブロックのスコープにあることが明らか
...
}

投稿者 Songmu : 23:06

先月はPHPで今月はPerl

今月はPerlの改修案件の仕事をやっている。スクラッチから書くのではないのでもともとのコードの書き方に悩まされている。「use strict」されていないコードがあって、こんな感じのコードが書かれていた。複数のコードが共有する変数がまとめてある。

package MyApp_GLOBALS;
use base 'Exporter';
@EXPORT = qw($HOST_IP $APP_PATH);
  
$HOST_IP = '192.168.0.1';
$APP_PATH = '/home/songmu/myapp/';
 
1;

変数宣言されていない変数が大量にあったのだが、その場合変数のスコープがどうなるか分からなかったので調べてみた。

  • 基本的にはourでの宣言と同じでグローバル変数になる
  • ただし、親ブロックや同一スコープ内で既に同名の変数が宣言されている場合は、警告無しに上書きしてしまう

と言うところのようだ。まあ、素直にour宣言しておきましょうってことですね。そうしないと意図とは違う動きをする可能性があって危険。ourはPerl5.6で追加されたものらしいので、書いた人は知らなかったようだ。正しくはこんな感じかな。

package MyApp_GLOBALS;
use strict;
use warnings;
use Readonly;
use base 'Exporter';
our @EXPORT = qw($HOST_IP $APP_PATH);
 
Readonly our $HOST_IP => '192.168.0.1';
Readonly our $APP_PATH => '/home/songmu/myapp/';
 
1;

あとはプロトタイプとか使われているところとかあって、それで何故かサブルーチン呼び出しがアンパサンド付きになったりしているのが謎。プロトタイプとかPerlベストプラクティスで非推奨になってたから全然使おうとか考えた事もなかったが、いまいち理解していなかったので、プログラミングPerlを引っ張り出して勉強しなおして、Perlベストプラクティスを読み返してなぜ非推奨なのかも理解しなおした。

投稿者 Songmu : 00:46

2009年2月20日

PHPの正規表現と文字列

PHPで正規表現を扱う上で、正規表現パターンの記述で迷ってしまっている人が多い気がする。

  1. PHPが文字列を生成する
  2. その文字列を正規表現エンジンに渡す

と言う2段階の手順があり、そこがやや複雑なので混乱を招く部分があるのだと思う。

混乱を防ぐためには、その手順をしっかり追って、正規表現リテラルとして指定している文字列をechoしたらPHPがどのように出力するかを考えてみると良い。

例えば以下のようなコードがあったとする。

preg_match('/\\d/','3d');

まず、preg_match()の第一引数になっている正規表現パターンをechoで出力するとどうなるかを考える。

echo '/\\d/'; #/\d/

なので、/\d/が正規表現エンジンに渡されると分かる。なので、上記のパターンはマッチする。

さらに混乱を招きやすくしているのが、PHPの文字列の仕様で、特にバックスラッシュのエスケープに関する仕様だ。

PHPマニュアルの文字列の項より抜粋。

引用符をリテラルとして指定するには、多くの他の言語と同様にバックスラッシュ (\) でエスケープする必要があります。 バックスラッシュを引用符の前または文字列の最後に置きたい場合は、 二重にする必要があります。この他の文字をエスケープする場合には、 バックスラッシュも出力されることに注意してください! このため、 通常はバックスラッシュ自体をエスケープする必要はありません。

つまり、エスケープが必要な文字が後に続かない場合、バックスラッシュはそのまま出力される。ただし、バックスラッシュをエスケープしても構わない(エスケープしないと正しく表示されないケースもある)。このエスケープするときのみバックスラッシュを意識すればよいという一見親切な設計が、混乱を招いている。実にPHPらしい。以下実例。

echo '\a'   ; # \a  そのまま出力される
echo '\\a'  ; # \a エスケープされて出力
echo '\\'   ; # \
echo '\'    ; # !Parse Error 「'」がエスケープされ、文字列が閉じてないとみなされる。
echo '\\\a' ; # \\a 一方のみエスケープされるので2つ出力
echo '\\\'  ; # !Parse Error 文字列が閉じていない
echo '\\\'' ; # \'
echo '\\\\' ; # \\
echo '\\\\a'; # \\a

解決策としては、バックスラッシュを書くときは、問答無用でエスケープしてしまうのが正解だと思う。1つ書きたいなら2つ重ねて。2つ書きたいなら4つ重ねて。

1つだけでもちゃんと出力してくれるときがあるので、逆に良く分からなくなっているのだと思う。3つ重ねると、2つ出力とか分かりづらい。そんなありがた迷惑な挙動はお断りしてしまいましょう。

また、ダブルクオート文字列内でエスケープ文字を記述する際にも混乱が起きやすい。PHPの文字列としてマッチさせようとしているのか、正規表現エンジンにマッチさせようとしているのかで混乱してしまうからだ。以下は、何れもタブ文字を削除するコードになる。

$str = str_replace("\t",'',$str);
$str = preg_replace("/\\t/",'',$str);

正規表現を使ったpreg_replaceだと、バックスラッシュを重ねる必要がある。さっきも述べたように、"/\\t/"をechoすると、/\t/になるので、それが正規表現エンジンに渡っているからだ。

このように、PHPで正規表現を扱う際には、一種のメタプログラミング状態になってしまっているので理解が難しい。

投稿者 Songmu : 01:20

2009年2月19日

PHPオンラインマニュアルが充実しているのは確かに素晴らしい、が

PHPは日本語のオンラインマニュアルが充実しているのが何気にすごい。多くの人が迷っている結構重要な事に対する答えが実はしれっと書いてあったりする。

ただ、それ以外の個人のBlogレベルになると、なかなか信用が置ける情報が少ない。純粋にPHP4時代のものもあるし、そもそも間違っているものも少なくない。この人が書いているなら間違いないっていうBlogが無い気がする。

投稿者 Songmu : 23:00

2009年2月17日

PHPの書籍をまとめてみる

一応PHPも業務で使えるレベルになったと思うので、これまで学習がてら入社前、入社後に読んだPHPに関する書籍をちょっとまとめてみる。

初めてのPHP&MySQL

PHP言語とPHPでのWebアプリケーションについてイメージを掴みたく、ざっくり網羅している本が読みたかったので最初に買った本。大体狙い通りの内容が書いてあった。他の言語である程度開発経験がある人が、PHPでのWebアプリケーションの開発となった際にこれを読めばコーディングは始められるかなという感じ。古い情報もあるけどね。

PHPサイバーテロの技法 攻撃と防御の実際

これはめちゃくちゃ良い本。PHPに限らずWebアプリケーション製作者必読書だと思う。様々な攻撃方法と、それに対する防御方法を事細かに書いてある。それでいて単なるケースワークに留まらず、攻撃方法が分類されてまとめられているので、Webアプリケーションのセキュリティに対する知識がしっかりと身につくと思う。恥ずかしながらヌルバイト攻撃の具体的な内容はこの本を読んで初めて知った。

それと驚いたのは画像ファイルのExif情報もXSSのターゲットに成り得ると言うもの。画像共有サイト等で撮影カメラの情報等のExif情報を読み出す処理を行っているWebアプリケーションでは、Exif情報にjavascriptを埋め込まれて攻撃される可能性があるので、ちゃんとExif情報のチェックを行わないといけないという。

確かにそうだけどすごく盲点。そういうことを考え付くヤツがいるってのが恐ろしい。


上記2冊が入社前に読んだ本。以下2冊が入社後に読み足した本。

プログラミングPHP

結局言語仕様とかちゃんと知りたくなって買ってしまうんですよ。馬鹿だよね。分量も少なくさくっと読めた。PHPは良くも悪くも関数依存で複雑な機能は無いので本の中で別段難しいところは無かった。

PHP5系が対象の本だけど、既に古くなってしまっている情報もあって、クラスのメンバ変数の宣言がvarだったり、DB連携のモジュールでPEAR::DBを取り上げてたりする(PDOの項目も少しあるけど)。その辺少し注意かな。

まるごとPHP! vol2

PHPの最新動向を知りたくて、実践的なコードを読みたくて買った本。

再学習PHP5の項目では、php.iniファイルついての解説や、オブジェクト指向、例外処理、PDOなどへの解説がしっかり書いてあって、かなり有用でした。「プログラミングPHP」よりも知りたい情報が書いてあったかも。

フレームワークの比較や、テスト駆動開発などについての記事も面白かった。期待していた以上に役に立った本。

投稿者 Songmu : 23:26

2009年2月16日

怖さを知らないルーキー的な

コードを書くのが楽しくて仕方が無い状態。予定よりも早く実装も進んでいるので、周りにも驚かれてます。

プロ野球で言えば、投げるのが楽しくて仕方が無いルーキー状態。そのうち手痛い洗礼を浴びて、プロの怖さを知ったりするのでしょう。

PHPもそんなに悪くないかなとか思ってると、ASPとかJSPとかのapplication変数(オブジェクト)的なものが標準で無かったり、private staticなメンバ変数を宣言できなかったり、連想配列にarray_shift関数を使うと大変な事になったりと、ちょっと油断するとひどい目にあわされるもんだから油断できない(笑)

HTML+CSS、正規表現とかなら社内でも出来るほうなんじゃないかとか思い始めた今日この頃。あんま自慢にならないけど。

投稿者 Songmu : 23:15

2009年2月11日

iPod touchをテキストリーダーにしたいの巻

前職に比べると通勤時間帯が普通なんで、通勤電車で座れない事が増えてきた。座れなくても混んでなきゃ良いけど、混雑してるとまともに本も読めない。サイズの大きいオライリーの本とか読んだり出来ない。

立ったまま無為に過ごすのも勿体無いなぁと言うことで考えたんだけど、私はiPod touchという便利なものを持っているわけです。これをテキストリーダーにして、なんか自動で取り込んで通勤電車で読めば良いじゃんとか思ったのが始まり。

新聞記事とかPlaggerで整形して、自分用にRSSとPDF作って、iPodでPodcastすれば良いんじゃね? とか思っていたら、おま、iPodってPDFをPodcast出来ないのかよ! そんな気はしてたけどさ。PDFそのままで読めそうにないし。

これまたそんな気はしてたけど、そもそもリーダーアプリを入れないといけないみたいなので、テキストリーダーアプリケーションを物色した。やっぱり似たようなことを考える人は多いらしく、iPod touch用のブックリーダー、テキストリーダーは豊富でした。そんな中、青空文庫用のSkyBookStanzaをインストール。

SkyBookはスゲー快適。新しいアプリで意欲的に新機能を盛り込もまれている段階ってところが良い。青空文庫のルビに対応しているのも大きい。

タップしてページ送り、シークバーを使えばページをぱらぱら送る事が出来たりと、ああ、これが出来ればブックリーダーとして文句は無いなという出来。

とりあえず、小栗虫太郎の黒死館殺人事件をダウンロードして読んでます。いやー、これが無料だなんて改めて青空文庫素晴らしいね。

ただ、SkyBookは縦書きオンリーなので読書する分には良いんだけど、WEBからの記事なんかを読む分には横書きの方が良いかなぁとか思って、Stanzaもインストール。こちらもSkyBookと同様の機能を備えてます。もともと英語圏のソフトなんで、ルビ表示とかは出来ないけどね。

何れも自分で作ったファイルも取り込むことが出来るんだけど、SkyBookは青空文庫形式のテキストファイルで、Stanzaはepub形式。

青空文庫形式は独自の日本語マークアップランゲージって感じで、なかなか面白い。例えばこんな感じ。

霜月|酉《とり》の日
[#改丁]
[#ここから4字下げ]
・・・
[#ここで字下げ終わり]
[#地付き](この日記終り)

記号も全部全角でマークアップされているのが面白い。一番上はルビの設定で、縦棒以降がルビ対象になって「《》」内ににルビを降ると言う仕様になっている。青空文庫のボランティアはみんなこのルールに従って打ち込みをしているみたい。

epub形式はまだまだ日本語の情報は少ないけど国際的に電子書籍の標準形式になろうとしている規格のようです。

拡張子が、epubでバイナリ形式のファイルかと思いきや、実は単なるzipファイルで中身はxmlファイルでした。レイアウトもxhtml+CSSが使えるみたいなので汎用性があって良いですね。

ただ、いかんせん日本語の情報が少ないので、デスクトップ版のStanzaが生成したepubファイルを解凍して解析したり、idpfのサイト(http://www.idpf.org/)を見たりして勉強中。

日本語の情報が少ないから、逆にちょっと頑張って上記サイトの翻訳でもしようかなとも考え中。

てことで、テキストデータをファイル形式に応じて整形してやってiPod touchに取り込めばよいのです。

ただ、取り込むのも問題があって、iFunBoxってプログラムを使えば、iPod touchにファイルを転送出来てそれはすごく便利なんだけど、最終的に自動的に同期とか精々ワンボタンで同期とかそういうレベルに持って行きたいよなぁとか悩みは尽きません。

というか実際に最初に書いた事が簡単に実行できるようになるのがいつになるのだか見当も付かないのだが、とりあえず、SkyBookで黒死館殺人事件が読めているので当初の目的とは違いますがそれはそれで満足だったりします。

投稿者 Songmu : 23:59

2009年2月 8日

EASEUS Partition Managerが便利

自宅で使ってるパソコンがデュアルブートになっていて、WindowsとLinuxを共存させていたのだが、Windowsの空き領域が残り3GBと少なくなったので、Linux領域を潰すことにした。

再インストールもメンドイのでパーティション弄るツール探してたら、EASEUS Partition Managerてのがあって、それを試した。別にデータ飛んだら再インストールすればよいだけの話だし。

Windowsにインストールして、パーティション変更内容を決めて再起動。後は勝手にやってくれて、1時間くらいで問題なく正常起動。あまりの簡単さと素晴らしさに感動したね。

これで容量は60GBになったので、OSとプログラムだけでそうそう使い切ることはあるまい。

メインをLinuxにする事を考えてた時期もあったけど、なんだかんだでWindowsのまま。Adobe製品が使えないのが大きいな。Windows7がクソで、XPのサポートが切れるようだったらLinuxに乗り換えると思う。

投稿者 Songmu : 23:46

2009年1月29日

職業プログラマーは肩が凝る

本格的にプロジェクトにアサインされて、やっとこさ保守の仕事だけの状況から脱却し、開発もすることになった。言語はPHP。

PHP初めてなんで、色々調べながら書いてます。まあ、演算子はPerlチックだし、関数宣言はJavaScriptチックだしで、別にそんなに大変なところは無いね。

ただ、無駄な組み込み関数の多さにうんざり。split('',$hoge)とか出来なくて、str_splitとsplitとかに分かれてるのってアホかって感じ。そのうち、add_one()、add_two()とかそんな関数が組み込まれるんじゃないかとか心配になってしまう。

しかし、連想配列の順序が崩れないのは何気に便利だね。色々出来るし、適切なフレームワークで覆ってやれば便利な言語なんだろうなとか思います。file_put_contents()なんかも便利。

ちなみに本を何冊か読んだくらいなので、PHPのソースってあんま読んだことが無いことに気が付いた。実践的なエラーハンドリングとかがまだ良く分かってない。なんかソースが載っている本を買おう。Web DB PressとかでもPHPの記事読み飛ばしてきたけど、これからはちゃんと読も。

しかし、一日中コード書いてると肩が凝るね。仕事で肩が凝ったのは初めてだよ。初めてノートパソコンのキーボード以外で作業してるから、ポジションとかに慣れてないせいなのかもしれないけど。

投稿者 Songmu : 23:34

2009年1月 9日

tableの森を抜けて

今週はずっとhtml修正と画像加工。10年前からあるサイトなのでいろいろ大変な事になってます。当然、激しくテーブルレイアウトなのです。

DOCTYPEもhtml4.01のURL無しの互換モードなのです。共通テンプレートになっているので、安易に変更できないのです。

てことでCSS書こうにもいろいろ苦労した。互換モードでのCSSコーディングに関する局所的なバッドノウハウが溜まっていくよ。これからかなり役に立つのかもね。

てことで、さっさとhtmlの修正を終えて、システム内で使われてるPerlのコードを読んだんだけど

&jcode'convert

とか書かれていて、一瞬何の事だか分かりませんでした。ああ、そういや、シングルクオートでモジュールの関数呼び出しでこういう書き方もあったんだっけ。変数宣言も全部「local」で「my」とかどこにも見当たりません。

ああ、これはPerl4の書き方なのですね、きっと。

なんだかオラワクワクしてきたぞ。

もちろんこういう自体は想定の範囲内です。COBOL触ったりするよりかはよっぽどマシだよね。

なにぶん私がJavaやPHPでの開発経験が皆無なので、使いどころに困られている部分もあるようで、早めに社内での開発手法等を学んでいきたいところです。

投稿者 Songmu : 23:48

2008年12月12日

オライリーの書籍は新宿紀伊国屋で買うことに決めた

JavaScriptの第5版を買った。第3版を持っているので、なんとなく買いたくなかったのだが、色々必要に迫られて買うことに決めた。

javascriptの本

てことで、第3版と第5版。第5版になって200ページ以上厚くなっているのだが、お値段は据え置き4200円。

CJKVストラップ新宿紀伊国屋で買ったらノベルティー貰った。裏が液晶クリーナーになってる携帯ストラップ。CJKV日中韓越情報処理の本を模したヤツだったので嬉しくなってこれを選んだ。他にも小さい本の形になった付箋メモ帳とかも選べた。

前回オライリーの本買ったときは、Firefoxのシール貰ったし、新宿紀伊国屋でオライリー買うと色々もらえるので今後は新宿紀伊国屋でオライリーの書籍をなるべく買うことにしたい。

投稿者 Songmu : 21:45

2008年12月10日

理想のポータブルデバイスとは?

地図画像やOfficeのファイルなんかをデジタルファイルで持ち歩けて閲覧できるポータブルデバイスがあると便利。転職活動してるときに思った。いちいち念のため地図を印刷するのが勿体無いしメンドイしかさばるし。携帯だとイマイチで。

iPhone・iPod touchとかPSPとかDSとかスマートフォンとかポメラ(?)とかいろいろ候補はあるんだけど、どれもまだまだ発展途上だよね。

用件は以下。

  1. 各種ファイル(PDF、Office、画像)が読める
  2. 画面が比較的大きく文字の可読性が高い
  3. PCからデバイスへの各種ファイル転送・同期が簡単
  4. できればネットが繋がる。gmail・GoogleMap使えると嬉しいなぁ
  5. カメラ。30万画素とかで十分。メモ代わりに
  6. キーボード外付け出来たりすると良いなぁ

てな感じ。

シャープのタッチケータイ、931SHがかなり条件を満たすので、機種変しようか迷った。店頭で触ってみたけど、タッチの反応もよく、欲しい機能も満たされていて、流石は日本メーカーだと思った。

で、色々迷った末、とりあえずiPod touchを購入した。

理由としては今更ながらiPod文化に触れておくかって思ったのと、LDR touchが素晴らしかったってのが大きい

しかしWiFiじゃないと、ファイルのやり取りなんかが出来ないのがメンドクせ。音楽や動画は同期できるけどね。クラックするとやりたい放題みたいなんだけど、とりあえず保留。

ちなみにネットワーク接続の共有(ICS)を使えば、無線ルーター無くてもWiFi接続できる事が判明して狂喜乱舞中。でもヨドバシのポイントでfonのルーター買っちゃったんだけどね。

ちなみに、今年流行りのネットブックは私に言わせれば

「それは私が5年前に通った道だ」

というところです。まだネットブックだなんて言葉が無い頃、VictorがInterLinkっていうA5ノートを出していて、大学の頃はこのPCをメインで使ってました。

小さい割にはスペックも十分で、XP Proが載っていたりして、かなり活躍してくれました。今でもたまに持ち歩いたりします。

ただ、やっぱキーボードが打ちづらいんだよね。使っていた頃は慣れていたつもりだったんだけど、ふと普通のA4ノートを使ってみたら、そのキーボードの打ちやすさに驚愕した覚えがあります。

なので、主に情報のインプットをするだけなら良いんだけど、アウトプットもしたい人にとっては、ネットブックは中途半端。

考えてみると、iPod touch等ポータブルデバイスは、情報のインプットに特化されてて、アウトプットをしたい人向けにはフィーチャーされていない。

そういう人が割合的には少ないからからかもしれないけど、持ち歩けるアウトプットデバイスってのがもう少し注目されると嬉しいなぁ。

ネットブックってのは一つの選択肢だけど中途半端。ポメラは面白い試みだと思う。

ちなみに、ネットブックのポインティングデバイスは、ポインティングスティックがベストだと思うんだけど、なんでどこもかしこもタッチパッドなんでしょうか。ポインティングスティックだと、パームレストを狭く出来てその分キーボードを広くとれる。InterLinkのポインティングスティックはかなり使いやすかった。

投稿者 Songmu : 21:18

2008年11月27日

Shibuya.pmの日に仕事を入れてしまった大馬鹿者の話

半日かからず定員が埋まる中、せっかく定員に漏れずに申し込んだのに、その日に仕事を入れてしまう馬鹿。行けなかった人には大変申し訳ない。

6時半から7時半までの第1・2部のみ聞いて、8時過ぎから出勤。どういう勤務だよ、という。

てことで、Shibuya.pmテクニカルトーク#10に行ってきました。Perlの初心者向け軽量フレームワークの話が多くて私のレベルに丁度良く、面白かった。

Yacafiをちょっと使ってみようと思う。普通に掲示板とか作ろうかな。某所で掲示板を作れとか言われていたような、いなかったような。

追記:

ニコ動にアップされているのを見た。最近はこういう風に行かなくても見られるから素晴らしいね。

mala氏の話が分かりやすくて面白かった。ネタかと思いきやちゃんとした話でした。ネットでは色々話題になっている人だけど、やっぱ賢い人なんだろうなと感じた。

LDRのトップページを読んでる間に、先回りしてキャッシュされてないフィードをパースしてmemcachedに突っ込んどくってのはなるほどなぁと。

やっぱWeb開発でも、新しい考え方を発見して実装するのって大事だよなぁ。そういうことが出来るようになりたい。

mala氏のいる(出戻った・笑)ライブドアは結構行きたかったんだけど、流石に世間的なイメージが悪すぎるかなぁとか思って躊躇してしまって、結局受けなかった。開発がPerlメインで技術力も高いってところはかなり魅力的だったんだけど。

行けるかどうかとは別の問題ですよ?

投稿者 Songmu : 23:16

2008年11月12日

三国志とプログラミング言語

孔明
Ruby
龐統
Perl
周瑜
Python
魯粛
JavaScript
曹操
Java

レッドクリフみてなんとなく思った。

孔明は何でも出来、お行儀が良くて完璧。龐統もほぼ同等のレベルで何でも出来るけど、お行儀が悪くフリーダム。魯粛は不当な扱いを受けていながら実はすごい人。

投稿者 Songmu : 03:18

2008年10月16日

JJUG Cross Community Conferenceに行ってきた

有意義でした。とりあえず、聞いたことをまとめたのを途中まで書いた。順次更新予定。

DOMパフォーマンスチューニング入門

amachangによるJavaScript講座。面白かった。私がテーブルをソートするスクリプトを自分で書いたのを使っていて、これを高速化したかったので、聞きにいった。

議題
  • JavaScriptが遅いんじゃなくてDOMが遅いんだよ
  • DOMが遅いのは、ブラウザのレンダラ側の問題だよ
DOM要素へのプロパティアクセスを意識する

style等でDOM要素のプロパティを見に行く場合、いちいちブラウザ側と通信が発生する。

elm.style.background = "#FFF";
elm.style.width      = "500px";

よりも、

var elmstyle        = elm.style;
elmstyle.background = "#FFF";
elmstyle.width      = "500px";

の方が速い。ドットシンタックスの数を数えると分かりやすい。(上だと4つ、下だと3つ)

ただし、これは無視できるほどのオーバーヘッドに過ぎない。特にFirefoxの場合。IEだと少しは高速化できる。

スタイルの再計算を意識する

JavaScriptでは、変更可能性のあるDOM要素に変更フラグを立てておいて、JavaScript側の処理が終わってから、ブラウザ側でスタイルの再計算、レイアウトの再計算を行う。JavaScriptの処理時間を計るだけじゃベンチマークが取れない!

スタイルの再計算は基本的にはJavaScript側の処理が終わってから行われる。ただし、変更フラグを立てた後、要素のスタイルを再取得しにいった場合は、その場で再計算が行われる。(そうしないとその時点での要素の幅等が出てこないから当たり前っちゃあ当たり前)

なので、どっかの要素に変更フラグを立てた後に、offsetWidthかなんかで要素のスタイルを取得しにいき、また、その要素に変更をかけたりすると、スタイルの再計算が2度走る事になるので、効率が悪い。JavaScript側の処理が終わってから一括してスタイルの再計算がされるようにコードの順番を意識する。

また、変更フラグは、「スタイルを変更したDOM要素」「そのDOM要素のCSSスタイルを継承することによって変更されうる要素」に立つ。

なので、なるべくDOMを掘ってから、スタイルの変更を当てた方が、高速化できる。

レイアウトの再計算

ここが大きなボトルネック。あまり高速化手法は無いが、新たな要素をposition:absoluteで置いてしまうってのは有り。

質疑応答

Q.DOMを高速化する上で、シンプルでクリーンなCSSを書いておくのは有効?そのためのノウハウみたいなものはあるか?(ちなみに私がした質問)
A.そのあたりは出来れば良いのかもしれないけど、分業の問題なので、CSSを書く人側でそういうことまで意識しておく必要は無いんじゃないか。CSS書く人と一緒に仕事をすることが少ない(自分で書く)のでよく分からない。

Q.どのブラウザのJavaScriptが高速だと感じるか
A.圧倒的にWebKit。JavaScriptの処理だけじゃなく、レンダリングも速い。

Q.どうやって技術を学習しているか
A.ソースを読んでいる。WebKitのソースとか別にそんなに難しくない(!!?)。WebKitのソースは拡張子が[idl]のファイルだけを読むだけでも勉強になる。

ギークなお姉さんができるまで

べにぢょさんが「ギーク」をフラットに発音していたのが、気になった。ああ、この界隈では一般名詞化しているんだなぁと思いました。私は後ろを下げて読んでた。

*参考 平板読みは間違い!? 「B'z」の正しい呼び方って?

べにぢょさんはポジティブ100%な人で全然他人の否定をしなさそう。その辺が安心感とか、人気につながってるんだろうなぁとか思いました。

最初は、purpurinが話しすぎかなぁとか思いましたが、最後の方は、purpurinさんの話をもう少し聞きたいなぁとか思った。マークアップエンジニアとしてちゃんとお金を稼げてる人みたいだったから。

purpurinさんが言ってた、

「最初はホームページ作りたかったんだけど、CSSという手段に惚れた」

って言葉はよく分かるなぁと同意。

それと、ひがやすを氏が突っ込んでた

「Webプログラマは(CSSの)スペックは分かるけどデザインは出来ない人が多い」

て言葉も全くだと思いました。なんか、Webプログラマーとデザイナーが交流できるイベントみたいなものの企画みたいな話にもなっていて、期待。

「JavaからRubyへ」アンド・ナウ

面白かった。よくまとまっているエントリーは多くありそうなので、個人的に以下面白いと思った発言を羅列。

  • Webで使われているPHPの代替手段としてのRubyと言う本は多く出ていたが、エンタープライズ目的のJavaからRubyへの移行というニッチが残っていたので「From Java to Ruby」を翻訳した。
  • JavaはCOBOL化している。良い意味で
  • DHHはOO厨(賛辞)
  • 「達人プログラマー」を読め

てことで、3つのセッションのみ参加したが、その次のセッションもペアプロとかしたみたいで、残れば良かったとか思いました。

投稿者 Songmu : 23:34

2008年9月15日

MT4.2にアップグレード

大苦戦した。てことでやったこと。

  • Berkeley DB → SQLiteにDB移行
  • MT3.31 → MT4.21へアップグレード
  • モジュール作ってテンプレートまとめたり
  • 多少CSSいじった

DB移行はすんなりいかないわ、アップグレードしたらテンプレートふっとばすわで、一部MTタグ読まないわで散々でした。

なんとか復旧出来てよかったよ。ホントはコードハイライトするJSを入れようと思っていたのだが、そこまでいかず。トラックバックとコメントも開放しようかとも思ってたりもする。

苦労した点やらはまたいつか。MT4になっていろいろ変わっているみたいだし、結構便利そうな機能もあって、ちょっとしっかり学んでみようかなとか思ってたり。

投稿者 Songmu : 16:59

2008年9月 9日

Template::Declareが便利すぎて、もう二度とタグ打ちしないかもしれない件

こういうモジュールを待っていた。もっと早く出会えていれば良かった。やっぱxmlって手で打つのめんどいから、別のデータ構造をhtmlに反映させる事が出来るツールが最強だとは思ってはいたんだけど、こんな便利なものがあったとは。

こんな感じで書けばhtmlが生成できます。

my @fruit = qw{apple orange banana};
template sample => sub html{
	attr{ lang => ja }
	head{
		title{'test'}
	}
	body{
		p{ 'hoge' }
		ul{
			for(@fruit){
				li{ $_ }
			}
		}
	}
};

テンプレートとして使うことが目的なんだろうけど、単一のhtmlを出力する目的としてもかなり優れています。もう私は、手打ちするときでもこれでしかhtml書かないよ。今後じかに書くことはまず無い気がする。

何せプログラムがコードを出力してくれるわけだから、タグの開閉、ネスティング含め完璧。閉じタグのスラッシュ打ち忘れてレイアウト崩れるとかがなくなるし、他人に渡しても恥ずかしくありません。

ただ、行数がかさむので視認性が劣るときがある。特に属性値を羅列するときに何行にもなってしまうのが問題

それと、テキストノードと他のタグを混在させるのが面倒なのが痛いなあ。

p{#OK
	'this is hoge.'
}
p{#これもOK
	attr{id => "hoge"}
	'this is hoge.'
}
p{#これはNG。エラーになる。
	'this is hoge.'
	br{}
	'this is fuga.'
}
p{#テキストノードに別のタグを続けたい場合は、outs関数を使う。
	outs 'this is hoge.';
	br{}
	outs 'this is fuga.';
}
p{#文字列の中にタグを入れてもバカ丁寧に全部文字実体参照に変換されてしまう
	'this is <strong>hoge</strong>.<br />'
  ."this is <em>fuga</em>."
}

ダブルコーテーションだと文字実体参照に変換で、シングルコーテーションの中だとPerlの文字列らしくそのまま出力されるのでタグを直打ちできる、とかいう仕様だったら嬉しかった。

投稿者 Songmu : 02:38

2008年9月 6日

Google Chromeが@font-faceに対応してないってどういうこと!?

WebKitは飾りですか!? Safariだとちゃんと表示されるのに。CSS3の目玉なんだから(個人的に)、他のどうでも良いプロパティに対応するくらいだったら、真っ先に対応して欲しかったんですけど…。ガッカリだよ!

実際問題、Google Chromeはまだまだって感じですね。マウスジェスチャーが使えるようになってから考える。表示も結構不具合が出る。

投稿者 Songmu : 23:30

2008年9月 4日

Google ChromeがCSSを読み込まなかった件について

休みだったので、タイムリーにGoogle Chromeを触ってみました。自分のサイトを見たら、いきなりCSS読みこまないでレイアウト崩れ。ビビった。

コンソールのResourcesを眺めたら、CSSファイルは読みに行っているのだが、そこから@importしているファイルを読みにいってくれてなかった。

どこか記述がおかしいのかなぁとファイルを調整。コメントを全部消したらちゃんと表示された。

どうやら、@chasetの記述がある場合、それがファイルの1行目にないとそのCSS全体を解釈しないみたいだ。スペースや改行があっても、ダメ。もちろんコメントがあってもダメ。BOMはあっても大丈夫みたい。

つまり以下の書き方はNG。

/* comment */
@charset "utf-8";
...

以下の書き方だとOK。

@charset "utf-8";
/* comment */
@import "hoge.css";
...

コメントの後の@importはちゃんと読み込んでくれるようです。

てことで、@charsetが前!コメントが後! 注意です。

ちなみに、私の日記のトップもChromeだと背景画像を完全には読み込まなかったりする。まだまだベータ版て感じですね。

投稿者 Songmu : 23:12

2008年8月 8日

コマンドプロンプトのdirが使えないからlsを作ったよ!

よくあるネタ。でも、ls.batを作ってどうのって話ではございません。そもそも、コマンドプロンプトのdirって、出力が過保護かつ冗長すぎてむかつくわけですよ。なので、dirの出力結果を受け取って、整形しなおしてプリントするperlスクリプトを書いた。やっつけですが。

#!/usr/bin/perl
use strict;
use warnings;
	
my $CHARS_PER_LINE = 75;
my $options = "";
my $dir = "";
	
for(@ARGV){
	if(/^-/){
		$options .= $_;
	}else{
		$dir = " \"".$_."\"";
	}
}
$options =~ s/-//g;
	
my $str = `dir$dir`;
my @files = split("\n",$str);
@files = @files[5..$#files-2];
unless(@files){ exit; }
	
if($options =~ "l"){
	print join "\n",@files;
}else{
	my @fileNames;
	my $maxlen = 1;
	for(@files){
		unless(/\.\.?$/){
			my @tmp;
			@tmp = split(/ +/,$_);
			$tmp[3] = join " ",@tmp[3..$#tmp];
			if($tmp[2] eq "<DIR>"){
				$tmp[3] = $tmp[3]."/";
			}
			$maxlen = length($tmp[3]) > $maxlen ? length($tmp[3]) : $maxlen;
			push @fileNames,$tmp[3];
		}
	}
	$maxlen += 2;
	if($maxlen > $CHARS_PER_LINE){
		print join "\n",@fileNames;
	}else{
		my $colums = int($CHARS_PER_LINE / $maxlen);
		my $i = 0;
		for(@fileNames){
			printf("%-${maxlen}s",$_);
			if(++$i % $colums == 0){
				print "\n";
			}
		}
	}
}

ダウンロード:ls.pl

PATHの通ったフォルダにこのファイルを突っ込んで、PATHEXTに.plを追加すれば、コマンドでlsが使えるようになる。出力結果はこんな感じ。

C:\Perl>ls
bin/   cpan/  eg/    etc/   html/  lib/   man/   site/

これで、適当にカラム数を設定して、整列してくれるようになりました。フォルダだったら最後に「/」を付けてくれる。

引数は、ハイフンで始まっているかどうかで、オプションか否かを判断していますが、もしハイフン始まりのフォルダ名が引数に指定されたら、うまく動きません。渡された引数がクオートされてるかどうかを判断する方法がわからんので。まあ、そんなフォルダ名は付けるなってことですよ。

あとは、複数フォルダを引数に指定した場合も全てのフォルダ内のファイルがうまく表示されませんが、別にそんな機能いらなくね、という。

オプションの対応はとりあえず「-l」だけ。まあ、個人で使う分には十分です。

投稿者 Songmu : 23:42

2008年7月25日

システム管理者の日

そういや、システム管理者の日でした。今週は結構システム管理者っぽい事をしてました。VBScript, Javascript, Perlをフルに使った気がする。

フォームの、バリデート関連とか、サニタイズ関連とかを見直したり、フォームの一つ一つの項目をVBScriptでオブジェクト指向的に実装したりとか、質問項目をCSVとかデータベースとかから引っ張ってこれるようにしたりとかその辺りの汎用モジュールを書いてた。

どれもこれまでやってきたようなことなんだけど、どうもその場しのぎで汎用性が足りなかったんで今後のために書き直した。

とか言っても、自分の昔書いたコードって、いつ見ても稚拙だから、今書いたコードを見てそのうち書き直したくなったりするんだろうな。その辺りキリが無いね。

投稿者 Songmu : 23:44

2008年7月23日

VBScriptの糞仕様

VBScriptってオブジェクトの中に格納した配列を変更する事が出来ないことに気づいて愕然。いったん格納してしまったら、長さ変更どころか、要素の値変更すら出来ないと言う。

Dim hoge : Set hoge = CreateObject("Scripting.Dictionary")
hoge("fuga") = Array(1,2,3,4,5)
WScript.Echo(hoge("fuga")(0))	'1
hoge("fuga")(0) = 10 			'代入してるのに
WScript.Echo(hoge("fuga")(0))	'1

orz

てことで、いったん配列を一時配列に格納しておいて、オブジェクト内配列を破棄してから、一時配列の値を変更して格納しなおせば一応値変更は可能。以下のような感じ。

Dim tmpArr : tmpArr = hoge("fuga")
Set hoge("fuga") = Nothing
tmpArr(0) = 10
hoge("fuga") = tmpArr
WScript.Echo(hoge("fuga")(0))	'10

うーん、これは明らかに無駄なコード過ぎ。せっかく、クラス自分で定義してオブジェクト指向とか楽しんでたのに、どっちらけ。

投稿者 Songmu : 01:28

2008年7月12日

Inspiron2200のキーボード交換…の予定だったが

職場のInspiron2200のキーボードの調子が突然悪くなり、一部が効かなくなったり、「k」を押すと「jk」、「,」を押すと「,m」とか出ちゃうようになってしまった。Dellに修理の見積もりとったら、2週間入院で4万円とか言われ、却下。補修部品のキーボードユニットを買って自分で修理することにした。ノートのキーボード交換とか初めてだけど、なんとかなるだろうと。実際簡単でした。

残念ながら英語キーボードしか入手出来なかった。日本語配列のままでも使えるだろうとか油断してたら、一部キーの過不足があり英語レイアウトに変更せざるを得なくなるという罠。記号の位置がぜんぜん違うのですげー泣きそうになった。覚えなおしと使い分けが面倒だなぁとか思っておりました。

しかも、キーボードユニットが初期不良でカーソルキーがセンシティブすぎて、キートップに触れただけで認識してしまうという泣きっ面に蜂状態。

もちろん交換してもらうことにして、店に送り返しました。その後、ひとまず元のキーボードユニットを付けてみて使ってみたんですよ。

そしたらちゃんと動くじゃありませんか。単にフィルムケーブルの接続がすこしずれてただけとかそんなことだったようだ。何が幸いするかわからないね。もし、キーボードユニットが初期不良じゃなかったら、泣く泣く英語キーボードを使い続けていたでしょうから。無駄にキーボードユニットは購入してしまったが。

教訓としては、
「調子が悪くなったら一度分解して組み付け直してみよう。ただし出来る範囲で」
ってことですね。

投稿者 Songmu : 16:50

DVD → Windowsメディアサーバー

Windowsメディアエンコーダーで、VOBファイルを直接WMVストリーミング形式にエンコードできることを知った。これでDVD→ストリーミング配信とかが楽すぎる。手順は以下。

  • DVD ShrinkでDVDからVOBファイルを抜き出し
  • WindowsメディアエンコーダでWMVにエンコード
  • ストリーミングサーバーにアップロードして配信

決して違法行為に手を染めているわけではありません。提携企業の紹介DVDをストリーミング配信して欲しい等の要望があったりするので。DVD内のVOBファイルそのままだと細切れだったりするんで、DVD Shrinkで一本の動画ファイルとして抽出するのが楽。

htmlの記述方法とかはそのうち。ググると色々説明が乱立しているが、これも個人的決定版があったりする。

投稿者 Songmu : 16:29

VBScriptにおけるpushの決定版

VBScriptの配列は扱いづらいことで有名(?)ですが、pushを定義したらだいぶましになりました。以前から使っていたのだけど、改良を重ねてこれが決定版。

Sub push(arr,elm)
  Dim i,tmp : i = 0
    If IsArray(arr) Then
      For Each tmp In arr
        i = 1
        Exit For
      Next
      If i=1 Then
        Redim Preserve arr(Ubound(arr)+1)
      Else
        Redim arr(0)
      End If
    Else
      arr = Array(0)
    End If
    If IsObject(elm) Then
      Set arr(Ubound(arr)) = elm
    Else
      arr(Ubound(arr)) = elm
    End If
End Sub

実行コードサンプル

Dim hoge()
push hoge,"test"
push hoge,Array(1,2,"fuga",44)
Dim fuga : Set fuga = CreateObject("Scripting.Dictionary")
fuga("item1") = "testitem"
push hoge,fuga
WScript.Echo(hoge(0))
WScript.Echo(hoge(1)(3))
WScript.Echo(hoge(2)("item1"))

これで、配列にオブジェクトやら配列やらを突っ込めてフリーダムな感じ。ひゃっほー。配列にはオブジェクト格納できないのかと思ってたら、「Set」を使えばできるんだね。実はVBScriptでもかなり複雑なデータ構造が実現可能。Classも定義できるし。ちなみに、こうやって配列にオブジェクトを突っ込むと参照渡しになるようだ。配列だと値渡し。

配列関係の条件分岐が複雑になっているが、空の配列の定義方法によって挙動が異なるのが理由。

  1. Dim hoge : hoge = Array() →IsArray()はTrue。UBound()を使うと、-1が返る
  2. Dim hoge() →IsArray()はTrue。UBound()を使うと、即エラー(!)
  3. Dim hoge(-1) →こういう宣言は不可能(即エラー)

2の変数宣言の方法がシンプルで好きなのだが、こうすると型が形だけ配列扱いになるだけで、Uboundで配列の長さも取得できないというクソ仕様。なんで、コレクションを見に行って、ひとつでも要素があれば配列を伸ばすという形にした。

かなり無理やりなので、メモリはすげー無駄遣いしてるんだろうなぁ。Perlみたいに、無名ハッシュみたいなのを直接入れたり、深いデータ構造の自動生成とかは流石にさせられないのが残念。

それと、配列を走査して書き出したりしようと、オブジェクトを書き出そうとしたときにエラー吐いちゃうんだよね。オブジェクトにtoStringみたいなのを定義できない(多分)のが困る。

投稿者 Songmu : 16:11

お前何年VBScript書いてんだって話なので

VBScriptでg.vbsを書いてみた。これなら拡張子無しでいけるだろうとか思ったらいけなかった。なんだよ。exeとlnkとbatは大丈夫なんだがなぁ。vbsからexeにするツール使おうとしたらウィルス扱いされたので見送り。

Option Explicit
Dim srchStr : srchStr = ""
Dim str
for each str In Wscript.ARguments
	srchStr = srchStr & " " & str
Next
srchStr = Mid(srchStr,2)
Dim sc : Set sc = CreateObject("ScriptControl")
sc.Language = "JScript"
Dim js : Set js = sc.CodeObject
srchStr = "http://www.google.co.jp/search?q=" & js.encodeURI(srchStr)
Dim shell : Set shell = WScript.CreateObject("WScript.Shell")
shell.Run(srchStr)

まあ、VBScriptとか言いつつScriptControlとか使ってしまってるわけですが、気にしない。

投稿者 Songmu : 01:10

2008年7月11日

ファイル名を指定して実行をランチャー化しさらに検索までも

Windowsキー+Rで「ファイル名を指定して実行」を呼び出せるので、これをランチャーとして使っている。C:\mycommand\にユーザ環境変数でPATHを通して、そこにショートカットやらスクリプトやらを置いている。putty.lnk置いておけば、Windowsキー+R+"putty"でターミナル呼び出せたりして便利。これを使い始めてから、デスクトップはTODOのファイルを置くだけになって大分すっきりした。

調べたら当然ながら似たようなことを考える人はたくさんいるようで、検索するのもファイル名を指定して実行なんて人がいた。「ファイル名を指定して実行」フェチのツール

素晴らしいアイデアなのでパクってYSTでも出来るようにした。上記ページのGoogle版も「複数引数を読まない」「URLエンコードがshift_jis」ってのが気に食わなかったので、Google版も別のを作った。

Perlで書いて、PARでexe化した。Encodeモジュール使ってるせいかサイズがクソでかくなり、動作も遅くなった。残念。PARで作ったexeファイルって単なるZIPのようだし。手動でいらないファイル削ったりしたらもうちょっと軽くなったりするのかも。

生のPerlはこちら。ActivePerl入ってたらこっちの方が断然早い。

ソースはこんな感じ(y.exe)。

#!/usr/bin/perl
use strict;
use warnings;
use Encode;
my $srchStr = join " ",@ARGV;
{
	use utf8;
	$srchStr = decode("sjis",$srchStr);
	$srchStr =~ s/ / /g;
}
$srchStr = encode("utf8",$srchStr);
$srchStr =~ s/([^\w ])/'%'.unpack('H2', $1)/ego;
$srchStr =~ tr/ /+/;
system 'start','http://search.yahoo.co.jp/search?p='.$srchStr;

最終行を何とかすれば、どんな環境でも動くはず。引数がShift_jisなのが前提だけど。本当は中国語も検索できるようにしたいんだよね…。「ファイル名を指定して実行」がsjis動作なのがきつい。

それと、環境変数PATHEXTに.PLを追加しても、「ファイル名を指定して実行」からは拡張子plを補完してくれない。コマンドラインからはいけるんだけど。何故?

投稿者 Songmu : 03:16

2008年6月24日

最近知ったすげー当たり前のこと

Perlのヒアドキュメントって、ダブルクオート文字列と同じで、変数埋め込んだらちゃんと文字列展開されるのね。なんだ、だったら、テンプレート使わなくても簡単なhtmlだったらさくっと書けるわけだ。いままで変数絡めないといけないところは、いちいちprint文書いてた。アホくさい。

流石に制御構造は埋め込めないみたいだけど、それが出来たら、テンプレートモジュール要らないじゃんて感じだからねぇ。

なんで気づいたかと言うと、ここのところ、「UNIXプログラミング環境」読んでたら、「シェルスクリプトのヒアドキュメントには変数が埋め込める」とか書いてあって、シェルで出来るんなら、Perlで出来ないわけが無いだろうとか思ってやってみたら出来ました。

なんで出来ないと思ってたんだろう。ラクダ本調べたら最初の方にちゃんと書いてあったよ。読んだ覚えもあったし。

UNIXプログラミング環境はすげー面白くて、絶版前に駆け込みで買っておいて良かったと思った。cd,ls,pwd,cp,mv,cat,more,chmod,chownあたりのコマンドやviとemacsを少しくらいは使えるけど、unixな環境の便利さがイマイチよく分からないと言う人(つまり私レベルね)がunix的考え方を理解するには最適の本だと思った。勿論古い表現も多いけどね。

ただ、どんな本読んでても最近Cにぶつかるんだよね。やっぱCも勉強せんとあかんかなぁと言う気になってきた。てことでいきなり「K&R」買っちゃった。

今月は本を買い控えたが、それでも1万近く行ってる…。

投稿者 Songmu : 23:43

2008年6月19日

Firefox3快適です

機能に加えて速度も手に入れたから最強だね。早速、自宅の3台と職場のパソコンにインストールしました。

各国のダウンロード数が見られて面白い。チャドが1(6月18日 23:50JST時点)なのが妙に気になっていて、これが2に増えたりしたらちょっと残念かも(6月19日01:50現在。2に増えてます…、残念?)北朝鮮は0だ。

てことで、アップデート絡みでやった事など。

Firebug

自動でアップデートされなかったが、Add-onsのページに行ったら最新版置いてあった。bって書いてあるからベータなのかもしれないけど。

Web Developer 日本語版

そもそも別のところが更新してたのね。通りで最近更新されないと思った。

All in One Gestures

FireGesturesを使いましょう

Tab Mix Plus

http://tmp.garyr.net/dev-builds/から最新のxpiを使えばインストール可能。

Portable Firefox

PortableFirefoxも早くも3.0になっててDL可能です。パッチ当てなくても単独での日本語版も準備されてます。

投稿者 Songmu : 01:58

2008年6月17日

Perlを使える至福

これまで静的なWEBページしかおいてなかった職場唯一のLinuxサーバーにスクリプトをおかざるを得なくなった。というか、むしろそう仕向けた。やったー、これでPerlが書けます。とりあえず簡単なフォームとかなんだけどね。テキスト処理でローカルで使うことはあっても、サーバーサイドで業務で使うのは初めて。

入ってたPerlが5.6だったので、5.10にバージョンアップしたら、ブラウザ上で動くサーバーコントロールパネルが一部動かなくなり、焦って元に戻した。結局サーバー上では、5.6と5.10を併用することにした。5.6だと日本語と中国語を同時に使いたいときに困る。

慣れないことするもんだから、いろいろ設定に戸惑った。sshで入ってユーザーの権限とかいじっていたら、いつの間にかユーザーをwheelグループから外してしまっていて、suできなくなってすげー焦った。最初はpasswdファイル壊してしまったかと思い、詰んだ?とか思って顔面蒼白でした。

何食わぬ顔して、サーバールームに入っていって、rootでログインして、権限設定しなおして事無きを得ました。

サーバーにSSL設定したりと、これまでやったことないことをしているので楽しい。

そういや、CGI.pmとutf8、Encodeを併用するときに

use CGI;
use utf8;
use Encode;
binmode STDIN ":bytes";
my $cgi = new CGI;
my $name = Encode::decode($cgi->param('name'));

てなかんじで動くことはわかったんだけど、最後の行を

my $name = decode($cgi->param('name'));

にすると動かない。なんでだろう。utf8::decodeとバッティングしてるのかな? 不明。

そういやグループ親会社含めても、全社でPerl書けるのって私だけな気が。こうやって、自分しか理解できないノウハウを貯めるのは、まずい気がしてきた…。転職できなくなっちゃう。

投稿者 Songmu : 23:55

2008年6月16日

県別に分離可能なベクター形式の日本地図

Flashで地図サービスみたいなものを作ろうかなと考えている。とりあえず、県別に分離できるベクター形式のファイルが無いものかなぁと思って探したが、フリーのものが見つからなかったので、自分で加工して作った。

日本地図白地図、世界地図、日本地図が無料」というサイトから、日本全体のベクターデータと県別のベクターデータを拾ってきて、ちまちまサイズあわせした。

特に加工再配布禁止とかでは無いようなので、ここに公開するものである。
japanmap47.zip(1.9MB Illustrator10形式aiファイル)

これにFlash内で座標系組み込んで、どっかのAPI叩いて、住所から緯度経度情報を取ってきて、ピンなんかを立てられるようになったらとりあえずの目標は完了。Yahooの天気情報みたいに、地域別・県別でズームアップみたいに出来るようになればよいなぁとか思っている。

投稿者 Songmu : 01:03

2008年5月28日

プレゼン楽しいよプレゼン:準備編

いかん、かなり舞い上がり気味です。またプレゼンするために新しい技術を学びたいくらい。調子に乗ってやった事をまとめてみる。

資料準備編

今回は割と普通の事しか書いてません、多分次回の予行演習編はオリジナリティに溢れた内容になるはずです。

最初はこんな感じ。

  1. 大まかにテーマを決める
  2. 話したい事柄をざっと書き出す
  3. とりあえず話す順番を決めて並べてみる
  4. 見切り発車で資料を作り始める

見切り発車が大事。資料作り始めたら以下。

  1. 資料作っていると話してみたい事が増えてくるので付け足す
  2. 自分のわからない事や分かってないところが見えてくるので調べながら資料作りを続ける
  3. 調べてると話したい関連事項が増えてくる(良くも悪くも)
  4. 時折全体を見直して、話したいところを削る。上手く全体を繋げる

5~8を繰り返して、完成に近づけていきます。完成まで7割がたというあたりで、予行演習を開始します。予行演習をすると足りない点がよりよく見えてくるので、そのフィードバックもしながら資料を作成し続けます。まあ、よくあるスパイラルモデルですな。

ちなみに、見切り発車が大事って言うのは、「800字を書く力」にも書いてあって、結構力づけられたと言うか、目からウロコでした。あまりこういうハウトゥー本みたいなものは読まないんですが、読んでみたら面白かったと言う。

以下抜粋。

  • 文章は「書くと書ける」
  • 書くことは、すでにあるものを再現する作業ではない
  • 作文をとおして「考える」習慣

得てして、「最初から書くべきことが決まっていて、それを順序だてて書く」という理想論に陥りがちなのだけど、実際はプロでもそうではないと言う事を知り(人にもよるのでしょうが)、衝撃を受けました。オススメです。

次回、プレゼン予行演習編。多分。

投稿者 Songmu : 02:15

2008年5月27日

1000speakers:5と書いたほうがSEO対策になるのかも(笑)

なんか、かなり評価してくださっている方もいて、嬉しい限りです。結局のところグリフウィキ作った上地さんのふんどしで相撲を取った感じですけれどもね。

てことで、準備で活躍したもの。

CJKV日中韓越情報処理

CJKV日中韓越情報処理

買って以来書棚の肥しとなっていたが、背に腹は代えられず通勤時に持ち歩いて読んでました。1100ページ超でオライリーサイズと、京極夏彦も真っ青のボリュームですが、案外持ち歩けるもんだなぁとか思いました。

ThinkPad X61 7675-A63(XP Proモデル)

thinkpadx61 thinkpadx61

すげー良い。買ったばかりだったが準備に大活躍してくれました。

なにせ。キーボードがかっちりしてて打ち易い。今まで使ってきた中で一番。Let's Noteはキータッチがぐにょぐにょしてるのが気に食わず、購入を見送っていたがThink Padにして正解でした。

ポインターのアキュポイントも素晴らしい。ホームポジションから指を大きく動かさずマウスカーソルを移動可能なのが良いね。

ただ、ファンクションキーの場所が微妙で、しかも、「レジストリ弄って入れ替えれば余裕でしょ」とか思ってたら、ファンクションキーって入れ替えられないのね…。Let's NoteはBIOSで設定できるみたいだね。

それと無線LANが搭載されてなかったのがちょっと誤算。別に要らないけど。E-mobileあるし。

それとこれ、Core2 Duoって言うの? 噂には聞いていたがすげー処理早すぎワラタ。複数ウィンドウ開いて一つで重い処理してても、他のウィンドウには影響が出ない、スゲェ。

買って速攻メモリ2GBに増設したが、もう一生これでよいんじゃないかってくらい快適。少なくともVISTAを使うことは無いな。

投稿者 Songmu : 02:51

2008年5月25日

1000speakersが一晩明けて

ボーっとしています。多少は部屋を片付けたり。プレゼン準備優先でたまっていたことを片付けたり。

改めて雑感

参加者の学習意欲には圧倒された。自分の知らない分野でもどんどん吸収しようとする姿勢が良い刺激になった。

Hackathonも楽しかった。完走せずに終電で帰ったが。特にニコニコ動画の中の人のオフレコ話を聞けたのが良かったなぁ。ジャスラックとの絡みとか。

運営側の負担の関係で今回でひとまず一区切りと言う感じで、次回からはまた、やり方を変えていくようなので、そういうときに参加できて良かった。

運営に関わった人たちは本当にお疲れ様でした&ありがとうございました。

ニコニコ動画で復習中

ニコニコ動画を自分の発表を見返している。すぐに見返すことが出来ると、色々改善点も見つかるから良いね。

プレゼン中IRCで色々話題にしてくださっていたらしいのですが、どう言われていたのか気になります。自分の出番のときもIRCクライアント立ち上げておけば後で見返すことが出来ると言う初歩的な事を知らんかった。

誰かその辺りのIRCログ送ってくれんかね。

5/27追記:ちゃんと過去ログあった。しかもニコニコ動画の方もIRCのチャットを流すようなかたちになってる。すげー。

動画を見返しながらの反省点としては

  • 笑い方がキモイ
  • 「えー」とか「あのー」とかが多い
  • 「と言う感じ」てな言い方が多い。もっと適切な言葉があったはず
  • プレゼン時間が長い
  • 結構いい加減な事を言っている

等。やっぱ場数かな。良かった点は

  • 息切れせずに話しきれた
  • htmlと漢字というとっつきやすい話題だったので、話したことを大体理解はしてもらえた(多分)

等。でもプレゼン経験皆無にしては上出来だったと思います。

みんなのノートパソコン

Mac多すぎ。半数強Macだった気がする。残りの半分弱がLet's Noteで、それを追う形でThinkPadという3大勢力だったかな。

私のThinkPad X61 7675-A63(XP Pro搭載Ver.)ですが、無線LAN搭載だと思っていたら、非搭載でした。スイッチ付いてるのに~。会場で無線に繋ごうとして初めて知りました。プレゼンのときは有線使わせてもらった。ありがとうございます。

Mac使うならLinuxとか思ってたけど、Macだったら中国語入力も標準で搭載されているようなので(重要)、少なくとも乗り換えの問題点の一つは解消されるなぁ。

そういや、Linuxデスクトップな人はいなかったかな。(定かではない)

終わりました

緊張の日々も終わり。ノートパソコンを持ち歩く生活もやめられます。本読まなきゃ。それと、先週は1回しかロードに乗れなかったけど、今週は乗り込む予定。もうツールド美ヶ原まで1ヶ月しかない。

追記:そういや、twitterのフォローワーになってくださった人が何人かいて、これまで全然twitterやってなかったけど、今更やってみようかとか思ってたり。

投稿者 Songmu : 15:35

2008年5月24日

家に帰って、ブログにアップするまでが1000speakersって話なので

てことで参加してきた。まずはプレゼン資料を公開します。もう動画もアップされてるようだ。早い。

楽しかった。プレゼンも時間がおしてしまったが話したい事は話せたので良かった。しかし23分も話してた。すみません…。

勢い余って最初に申し込んだ関係で、基調講演の後のトップバッターだったが、さっさと自分の出番が終わらせられて良かったよ。後のほうだったらどんどん緊張するばかりだし、他の人の話がまともに聴けなかったと思う。

すげー緊張した。話の最初に「実は職場がこのすぐそばで、休みの日にも職場の近くに来るのはゲンナリなんですけど」みたいな関係ない話をして、ちょっと笑ってくれた人がいたので結構楽になってその後はすんなり話せた感じ。

「プレゼン上手いっすね~」とかお世辞じゃない感じで何人か誉めてくださった。わーい。

プレゼンとか大学以来6年振りとか。しかもピンのプレゼンでスライドを作ったのは多分初めて。あまりプレゼンするような授業はとって無かったし、敢えてOHPばっか使ってたなぁ。

そこそこしっかり準備したり、密かに練習したりした甲斐がありました。意識したのは大きな声を出す事、抑揚をきかせることくらいかな。

プレゼンツールはやっぱWeb屋だったら、パワポじゃなくて、Html+JavaScriptベースでしょうってことで、Html Slidyにした。自分で書こうかとも思ったけど時間が無く諦めた(画面を暗転させる機能が欲しかった)。S6も考えたけど、とりあえずシンプルな機能だけで良かったし、S6使っている人多そうだったから敢えて。(そりゃS6のほうがホットだし高機能だしな)

パワポ使い慣れてない(=プレゼンでは使ったことが無い)けど、htmlだったらデザインし慣れてるし、CSSの制御してデザインを統一するのも楽。この選択は正解だったと思う。

しかし、メイリオってフォントに力があるね。ベタで大きく書いておくだけで様になるので助かった。なので、スライドにそこまでデザインは入れなかった。

他の人の話も面白かった。語学、自分専用プロキシ、Twitterなんかの話が多かった。理解できない話もあったのが悔しい。最近の若い人はすごいなぁとつくづく。

基調講演して下さってたiKnowxakyさんとは講演後に話させてもらった。名刺もらった。

zakyさんの漢字での名前は、「白雅威」なんだってさ。これ豆知識な。

"Do you have Chinese character's name?" とか訊いたら教えてくれた。

"Huh? This is like Chinese pronounciation...?"

と聞き返したら、

「我的老师给我汉字的名字」(先生が僕に漢字の名前をつけてくれたんだよ)

とか流暢な中国語で返されたので超ビビッた(本当に発音きれいだった!)。なんだよ、中国語結構話せるんじゃん。日本語もすげー上手いしな。すげえなぁ。

私もがんばってiKnowやろ。

投稿者 Songmu : 23:28

2008年5月22日

1000speakers準備中

準備に追われてます。なんとなくまとまってきた。もうこんな時間だ。今週は通勤電車内でも資料作ってる。X61買ってマジで良かった。キーボードもスゲー打ちやすいし、ポインターも使いやすい。バッテリーの持ち以外は最強。e-mobileも便利。

投稿者 Songmu : 04:16

2008年5月 4日

1000speakers出ます!

てことで、密かに参加意欲を燃やしていた1000speakersですが、今月は休みが取れたので参加することにしました。

どうせならってことで、話す人にまわる事にしました。超無謀。HTMLと多言語(主に漢字圏)とフォントみたいな話の予定。多分それくらいじゃないと話せるネタ無いし。場違いかもしれませんが変化球勝負です。

絶対、「Songmuって誰?」みたいな話になっていると思う。

投稿者 Songmu : 21:37

2008年4月14日

Windows2000サーバー管理日記

サーバーリプレイスしてから不安定で仕方が無い。本日は正規表現オブジェクトを宣言しているASPで、ことごとく以下のエラーメッセージ。

ライブラリは登録してされていません

ログインページとか入力チェックしている箇所が全部動かない。かなり致命的な状態。

焦って、ググってこのページをみつけて、この手順でVBScript.dllを再登録したらなんとか解決。あー、dll入れ替えたい。

そういや最近、VBScriptでコロンで区切れば、複数の文を一行に記述できることを今更知った。こんな感じ。

Dim i : i = 0

変数名を2回書かないといけないのはまだ冗長だけど大分マシ。これまで変数宣言、初期化処理を2行に分けて書いてたからな。

クラスもちゃんと定義できるし、実は結構VBScriptも悪くないなとか思い始めた。単項演算子とか代入演算子がないとか、妙にタイプの量が増えるのがやっぱイラつくけど。

最近、レガシーASPでCometっぽいことをやろうとしてたりと、方向性がおかしい。

投稿者 Songmu : 22:17

2008年4月 7日

vbscript.dllと正規表現

職場のWindows2000サーバーをリプレイスしたら一部のASPが動かなくなり、

文字の繰り返しを表す正規表現演算子が不正です

とかいうエラーメッセージが出るようになってしまった

正規表現の非欲張り量指定子を使っているところがことごとく上手く動かない。

調べてみると、どうやら、アップデートの時に、vbscript.dllのバージョンアップが何故かうまくいっておらず5.1のままになっていたのが原因。

5.6のdllで上書きしようと試みると、「使用中のため上書きできません」のエラー。サーバーを再起動するわけにもいかず、泣く泣くコードを全て非欲張り量指定子を使わない形に書き換えた。洗い出しきれているかどうかちょっと不安。

しかし、「正規表現演算子が不正です」とか言って、不正なのはお前の正規表現エンジンなんじゃねーかと。まあ、バージョンが古いものに文句言って立って仕方が無いけどさ。

しかし、非欲張り量指定子が使えないのは結構痛い。折を見て、dllを上書きしたい。

投稿者 Songmu : 23:56

2008年3月30日

Livedoorリーダーテラ便利

今更ネタ。やっと本格的にフィード登録をした。キーボードショートカット使ってゴリゴリ動かすと便利。ブラウザ自体もキーボードで操作したくなってFirefoxのキーボードショートカット調べたりもした。

登録フィードはIT系、スポーツニュース系、自転車系、ボウリング系、料理系、中国系、中国語系等々。欲張りすぎ無いのが肝要。

投稿者 Songmu : 00:36

2008年3月17日

Excelでチラシを作るなとは言わないが…

Excelでチラシを作るのはもはや仕方が無い。私もたまにやるし。表組みとか必要なとき便利だよね。下手にエクセルの表をワードの中に組み込んだりするとクラッシュしやすくなったりするし。

そもそもExcelは表計算ソフトだから、印刷を想定していない。それに本来WYSWYGって奇跡的なことで、ディスプレイと同じ出力が、プリンターで得られるのが当たり前だと思っていることは危険極まりなくて…(以下略)

つまり、ExcelのWYSWYGは馬鹿だということを意識しなきゃいけないんですよ。最悪なのが

  • スペースで改行位置をあわせる
  • 空白行を挿入して、改ページ位置をあわせる

この2点。正しい解決策は以下。

  • セル内で改行するときはALT+Enterで改行
  • 改行したいときは、メニューの「挿入→改ページ」(ワードでも同じ)

それと、

  • ちょくちょくプレビュー画面を確認
  • 最終前に印刷して確認
  • プリンタによって印刷結果が異なる場合があるので、最後にPDFで書き出す

この辺が超大事。あと、オブジェクト配置しまくったりとか、複雑な操作しちゃダメ!まず画面とプリンタ出力が食い違う。

PDF出力には、私はPrimoPDFとFlashPaper2を使ってます。

今知ったけど、FlashPaper2ってもう売ってないし、Adobeは今後提供する気も無いんだ! えぇ、FlashPaper超便利なのに! ページ内に埋め込めるし、動きも軽いし。買っておいて良かった。マジで。

あと、ワードとかエクセルが強制終了を連発する事があるけど、そういう時は一時ファイルを削除すれば解決する事もある。一時ファイルは隠しファイルになっているから表示させてない人のPCではいつまでもクラッシュの原因になっていたりする。

あまりワードエクセル使わないんだけど、上司に「どうしてこうなるんだろう」とか聞かれて、作ったチラシとかを修正、印刷する事が結構あったので妙にノウハウがあったりする。

ただ、最近ワードもエクセルもちゃんと勉強する必要もあるかなぁとか感じる事もある。特にワードなんか、実際すげー便利なソフトなんでしょうからね。見出し毎にスタイル定義したりもできるんでしょ?多分。使ってるのがHTMLばっかでわからん。

投稿者 Songmu : 22:20

2008年3月16日

自宅もデュアルに

デュアル!

ついに自宅もデュアルディスプレイにした!ノートだと最近は拡張デスクトップがあって、実はデュアルディスプレイ環境構築が実に簡単です。

買ったのは、Dellの19インチワイド。パソコン環境は、職場よりも自宅の方を少し上にしておくってのがポリシー。逆のような気もするけど。

安さにつられてDellにしたけど、Dellの箱が自宅に送られてきたときは、少しゲンナリ。職場のPCは全部Dellで揃えているので。まあ、気分の問題。そのうち慣れるでしょう。

これでニコニコ動画を見ながらサイト更新したり、プログラム書いたり出来るぜぇ。19インチワイドは流石に大きいのでむしろ映画とか見たほうが良いんじゃないかとか思ってみたり。

投稿者 Songmu : 17:13

2008年3月13日

自分の1行CSSのノウハウも多少公開してみる

http://coliss.com/articles/build-websites/operation/css/886.html
http://www.cssglobe.com/post/1392/8-premium-one-line-css-tips

ままあるが、自分が分かりきっている情報が、多くのブックマークを集めているとなんだか複雑な気分。くだらない感情だけど。そういった情報を整理して上手く見せる事に価値があるのだということは分かっちゃいる。

overflow:hidden;page-break-after:always;なんかは、印刷用のhtml+CSSを書きまくっている私としては常用テクニックだったりするので。

他に1行CSSとして便利なのは、

cursor:pointer;

とかが思い浮かぶ。マウスカーソルを手の形にしてくれる指定。リンクじゃないけど、クリックして何か効果を出す要素に指定しおくと効果的。

また、

white-space:nowrap;

は、かなり使えます。上のリンクでは、aタグに指定して紹介していますが、個人的に多用しているのが、labelタグへの指定。

<label for="fruit001"><input type="checkbox" value="りんご" id="fruit001" name="fruit">りんご</label>
<label for="fruit002"><input type="checkbox" value="バナナ" id="fruit002" name="fruit">バナナ</label>
<label for="fruit003"><input type="checkbox" value="パイナップル" id="fruit003" name="fruit">パイナップル</label>
label{white-space:nowrap;}

とか書いておくと、ちゃんとフォームコントロール直後に勝手に改行される事なく、まとまって次の行に移ってくれます。プログラムで配列からフォームアイテムを順次出力させたりする場合にすごく便利。なんで上記CSSは私のデフォルトCSSに入ってます。

そのうち詳しく書くかも。

投稿者 Songmu : 03:13

2008年3月 9日

その後のデイリーポータルViewer

思ったより上手く動いている。RSSちゃんと読みに行って、更新も出来ているようで安心。一回処理が混み合って、ファイルに重複書き込みが起こってしまっていたが。

個人的にすげー楽しんでます。これまであんま興味持ってなかったライターの記事を一気読みしてしまったりとかね。

なんか最初作者と記事を一斉に抜き出すスクリプトが一部上手く動いておらず、「林雄司」「梅田カズヒコ」「萩原雅紀」等かなりの重要人物たちの記事がごっそり抜け落ちており、ライターごとに記事一覧を抜き出して、手動で追加した。

またスペースの有無、全半角の揺らぎが大きいので、ライター名からスペースを消す事にした。

ライター名じゃなく、記事名も含めた検索で調べても良いんじゃないかとか感じ始めている。例えば、「ドラゴンボール」とかで検索させたりとかね。

投稿者 Songmu : 02:25

ネットワークドライブ変更batファイル

職場で全クライアントPCのネットワークドライブの割り当てを変更する必要があり、調べたらバッチファイルで変更できそうだったので、書いたバッチを以下に公開するものである。

echo Ⅰドライブの割り当てを変更します。
net use I: /delete
net use I: \\serverName\home
net use /persistent:yes
hostname >> i:\tmp\check.txt
echo Ⅰドライブの割り当てが終了しました。
pause

ドメイン管理してりゃログオンスクリプトで一括処理出来るんだろうけど、お金なくてクライアントが殆どXP HOMEなもんで、添付でファイル送って、各自にマニュアル処理してもらいましたよ。

なんで処理が終わったら、確認ファイルにコンピュータ名を書き込むような小細工も仕組んであるという。

投稿者 Songmu : 02:10

2008年3月 8日

IE7の良い点

IE7の印刷機能が結構使えます。「用紙にあわせて縮小」が出来るのが良い。印刷用CSSがいい加減でも出力を1ページに収めることが出来るのです。仕事でhtmlでドキュメント作成したり、レポート画面出力して印刷させたりする事が多いので、助かります。

そういう意味じゃ、紙が好きな企業やユーザーのニーズを満たしているのかもね。Firefoxは印刷機能がいけてないからなぁ。

IE8のベータ版が出ましたね。珍しく対応が早い。

投稿者 Songmu : 01:41

2008年3月 7日

暇な時間に遊びで開発

最近妙に時間がある。考えてみたら、前は自分で全部やってたDBへのデータ入力、修正、閲覧の類を、各拠点や庶務の子に出来るように業務アプリケーション作ったりしたりしたから、やる事が減ったんだな。

てことで時間があったので、イントラ上の管理画面に掲示板機能をつけてみたりした。イントラ内だから、セキュリティとか気にしないでいいのが楽。遊びで、jQuery使ってページの一部だけ書き換えるAjax掲示板にした。レガシーASPでAjaxとかなかなか無い発想(笑)

これで、誰か不在のときに掲示板に書き込んでおけば、電話がかかってきません。実際、今日は上司が不在だったら、掲示板にその旨書き込んでおいたので、「○○さんいますか?」とか全然電話来なくて楽でした。余計時間が出来ました。

簡単な機能だからプレーンテキストで良いやとか思ったら、逆に無駄に苦労した。DB使うほうが楽だった。VBScriptだとUnicodeを扱うとか言っても、基本UTF-16しか読み書き出来ないし。

ASP上でファイルを読み込めば、ASPの文字コードによって、適宜書き出してくれるんだけど、この辺、中途半端に自動で処理してくれるところが気持ち悪い。

完璧に処理してくれるならまだしも、拡張子非表示とか同じで、自動で色々やってくれるげで抜けが多いから全然上手く動かない事が多いと言う。お前それで気を利かせているつもりかよ、って感じですよ。それだったら明示的に処理させてくれれば良いのに。それがMicrosoftクオリティ。

投稿者 Songmu : 22:23

2008年2月26日

デイリーポータルViewerを作った(初めてのCGI)

https://songmu.jp/dailyviewer/daily2.cgi

最初は単にべつやくれいの記事を一気読み出来ないかなぁと思ったのが作成のきっかけ。それをPerlの練習もかねて書いてみた。個人的なものなので最初はすげーやっつけスクリプトでした。

バックナンバーのページから「\d\d?月」となっているリンク先(=月別一覧)に逐一アクセスして、ライター名で全文検索してリンクを拾い出してくるかなり乱暴かつ迷惑なスクリプトだったのです。

これをちょっと改変して公開してみようとか思ったのが、運の尽き(?) ライター名を入力したら、記事一覧を返すCGIを作ってみようと。

しかし、もともとの仕組みじゃ使い物になりません。毎回根こそぎ(80ページ強!)一気にアクセスして、ライター名で全文検索にいくので、実行にも時間がかかるし、何よりデイリーポータルZ側のサーバーへ迷惑この上ないわけです。

じゃあ、「アクセスのあったライターに関して、記事のURLをキャッシュしておこうかな?」とも考えましたが、結局、

「最初に一度だけ一気にアクセスして、バックナンバーを根こそぎ拾い出してきて、更新情報はRSS見に行けば良くね?」

という方針に落ち着きました。もう最初とは全然違うプログラムになってしまったわけです。

最初のプログラムは、先ずは、ライター名ありきだったので、ライター名で全文検索に行けば良かったのですが、ライター名、タイトル、URLのリストが対応したリストを全て抜き出してくるとなると、走らせる正規表現がまたちょっと変わってくるわけです。

月別一覧のページを見ると、ライター名はカッコでくくられているので、そこを起点にして、リンクとタイトルを拾ってくる形になりました。

しかし、さすが手打ちで更新しているだけあって、全角、半角カッコの統一が取れていなかったり、改行される場所のルールが統一されていなかったりで、結構マッチング泣かせな部分がありました。拾い切れていない記事も多々あることでしょう。

また、2005年7月以前の月別一覧のページにはライター名の記述が無いため、それ以前の記事を拾い出すのは泣く泣く諦めました。

ちなみに、記事の順番ですが、バックナンバーのページのリンク順に拾い出しているので、上から、2007年1月、2007年2月…、2007年12月、2006年1月、といったちょっと変な順番になってしまっていますが、気にしません。今後の記事はRSSを見て更新に行くので、時系列順に並ぶと思います。

ライター名一覧も出すようにしてしまったので、入力ボックスの意味があまりなくなってしまいましたが、前方一致であれば、記事を拾い出すことが可能なのが見逃せません。なので「べつやく」と入力すれば、べつやくれいの記事にアクセスできますし、「三土」と入力すれば、「三土たつお」と「三土 たつお」の両方の記事にアクセス可能です。ただ、スペース関係が入ると違うライター扱いになってしまうのは何とかしようと思っています。

初めてスクラッチからCGI書いたので、いろいろ初歩的な点でバカみたいに苦労した。

大学時代に少し触っていたので、改行コードでははまらなかったが、文字コードがらみではまったり、時代は流れて、今やjcodeじゃなくてEncodeだったり。URLエンコードできなくてはまった時間が一番長かったかも。最初のやっつけスクリプトは30分だったが、ここまで書き上げるのに、多分賞味10時間近くかかっている。遅すぎ…。

ちなみに、ローカルのXP ProのIISでPerlを動かせるのを知ってちょっと嬉しかった。どうせならApache入れろよって感じではありますが。

現状の課題としては、アクセスがあるたびに毎回RSSを見に行くところ。RSS見に行くくらいだったら良いでしょとか思っているが、よしんばアクセスが増えることがあったら、何とかしないとなぁ。

小心者なので、デイリーポータルZ宛にお伺いのメール出した。公開しちゃダメって言われたらどうしよう…。

投稿者 Songmu : 21:59

2008年2月23日

コードあぼーん

今週はもう、かなり馬鹿でベタでダメージの大きいミスをした。

サーバー上のプログラムを消してしまったのですな。作業が一段落ついた分をローカルにコピーしようとして、その逆をやるというまあ、よく聞く笑えない笑い話を自分でやってしまったわけです。

凍りついたね。即座に復旧を試みたが、全てアウト。

消したのが、テストサーバー上のデータだったので、実際のサービスには影響は無かったのだが、テストサーバーだったからこそ、あまりしっかりバックアップを取っておらず、数日前のチェックアウトに逆戻りですよ。

正に涙目になりながら、自分で書いたコードを覚えているうちに復旧を試みた。こんな勢いでコードを書いたのは生まれて初めてでした。

そうしたら、2時間で復旧に成功。6時間分位の作業分を取り返したことになる。これはこれで良い経験になりました。今週は結構プログラムを書く余裕があったのですが、よくよく考えてみると、問い合わせが全然ありませんでした。つまり営業成績がヤバイのです。

投稿者 Songmu : 22:08

2008年2月13日

結局、target="_blank"で良いんじゃ?

ここのところ、公私共にサイトを作っていた。特に何も参考にせず、コピペもせず、clearfixをぱぱっと書けたのがちょっと成長かな、と思ってみたり。

てことで、作ったサイト。まだ作りかけの感がぬぐえません。もうちょっと飾り気をつけないとね。

一部DreamWeaverを使っていたわけですが、案外DreamWeaver上のブラウザが役に立たなかったので、機能としてはテンプレート機能を活用したくらい。基本エディターモードだし。

最近作っていたWebアプリケーションの中で、印刷画面を別窓表示させたい部分があって、ちょっと別窓について調べてみた。最近ポップアップブロックとか結構鬱陶しいじゃないですか。

別に社内で使う分にならまだしも、お客様が使用中にブロックされたりしたら洒落にならないので。

別窓を開かずに、ページ遷移の中できっちりコンテンツを見せられるのが優れているってのは正しくも有り、理想論。

なんか以下のように書いて、javaScriptでイベントハンドラ設定しておいて、リンクがクリックされたら、別窓で表示されるようにして、javaScriptがオフ環境の人でもリンクが辿れるみたいなのが、良いのかなぁとか思っていたら、見事、Googleツールバーに弾かれました。

<a href="hoge.html" class="newwin">hoge</a>

Googleツールバーの初期状態はかなりヒステリックで、"window.open()"が絡んでいると、ほぼブロックしてくると言う徹底ぶり。使っているうちに、ホワイトリストが適正に設定されてきて、そんなにブロックはしなくなるみたいだが、ホワイトリストは自分で設定できないみたいだしね。

結局、target="_blank"が良いんじゃないかとか思いました。target属性が非推奨だからといって、javaScriptで無理やり実装しようとして、独自拡張が乱立して更に訳わかんない事になってたんじゃ本末転倒です。はてブなんかはtarget="_blank"を使ってますね。

実際、別窓で開かせたいと言う製作者側の思惑だけでなく、別窓で開いて欲しいと言うユーザーも居る訳ですよ。わざわざ右クリックでコンテキストメニューを表示して「新しいウィンドウで開く」だなんて自分で選ぶよりかは、自然に適正に別窓が開いてくれるほうがありがたかったりする訳ですよ。

ホイールクリックで別窓表示されるように設定すれば問題ない、とか言うかもしれない。しかし、それくらいの設定が出来るくらいのヘビーユーザーなのであればそっちが逆に、target="_blank"を別窓で表示しない設定にすれば良い。実際Firefoxは標準でそういう設定が出来るようになっている。

だから、別窓で表示させたい製作者側は、target="_blank"で表記を統一し、別窓が嫌いなユーザーはtarget="_blank"を別窓で開かないように設定すればよい。それで万事解決だと思う。

ちなみにHTML5では、iframeなんかで利用する関係で、target要素は非推奨じゃ無くなったようですね。

また、今回仕事で作ったWEBアプリケーションでは、印刷画面をCSSで綺麗に実装するのが肝だったのですが、各ブラウザの画面上での画像縮小表示が貧弱なのはどうにかならんのか、とか思いました。

印刷前提だと、画面上ではサイズが大きめの画像を縮小して表示することになり、そうすると画面上で見たときの汚いこと。PDFとかに書き出しちゃえば、問題ないんだけどね。

そういえば、imgタグのwidth,height属性が推奨なのも謎。ネットワーク負荷の観点からすれば、あったほうが良いのかもしれないけど、そのwidthやheightって、mediaがscreenなのを前提としたときのサイズに過ぎないじゃんと言う。しかもそれって、CSSで指定したほうが良いよねっていう。

HTML5ではimg要素のalt属性が必須じゃなくなっていて、議論になっているようです。それは私もどうかと思います。飾り画像なんてCSSで配置すれば良いのだから。ただ、そういうことから窺えるように、理想を追いすぎて発展性の無いxhtml1.1とは違って、HTML5は結構現実に即した仕様になっているようですね。

canvasタグとかかなり面白そうなのですが、更に書くと止まらなそうなので、ここでおしまい。

投稿者 Songmu : 02:32

2008年2月 6日

中途半端な中国語力の中途半端なエンジニア

IE8がacid2に合格してすげーけどなんかmetaタグ必要らしいねとか、今更だけどjQueryテラ便利、これまでgetElementByIdやらgetAttributeやら書いてたのが馬鹿らしくなるねとか、連想配列にはまりすぎて、あらゆるデータ構造を連想配列で書きたくなってしまうと言う、多分プログラマーにおける一種のはしかにかかっている状態だったり、百度が結構本気で日本進出してきたので中国語の出来るエンジニアである私としてはちょっと転職先として興味があったりするとか、デイリーポータルZの作者別記事リンク一覧を抽出するPerlプログラムを書いたのでこれをCGIとして公開しようかとか思っているとか、そんな状態。

結局1月は正月以降殆ど運動せずに終わり、食事も少なめだったので、体重も少し落ちた。2月以降ぼちぼち運動再開して、ここに肉付けしていく事にする。

仕事では、やっとプログラム一つ書き終わりそうだ。スクラッチから作ったものとしては、やっつけプログラムを除くと、初めてかも。本来なら年明けには出来ていないといけないものが、2月頭のリリースとなりそうです。

プログラムの大枠は12月中旬には出来ていたのだが、細かい機能を一つ一つ実装するのに時間がかかった。文字コードがらみとか、印刷用CSSの微調整とか結構こまごまあるもんだよね。その辺の工数見積もりがまだまだ甘いと思う。

一応Webアプリケーションなので、多少はセキュリティにも気を遣ってみた。なんか最近PHPはどうのとか、騒ぎになってますが、ASPは俎上にも上がりませんか。そりゃそうですよね。

投稿者 Songmu : 02:56

2007年12月13日

VBScriptの貧弱さ

片手間ながら仕事でプログラムも書いている。最近やってるのはもっぱらフォームのシステム化。私が今のポジションにつく前から、都度都度、質問項目が付け加えられたり、目的別に同じようなフォームが独立していくつもあったりと、かなり酷い状態なので、この際スクラッチから書き直す事にした。

共通部分は、共有するようにしたり、質問項目はデータベースから回してきたりと、まあ何で今までやってなかったのって感じの事なんですが。入力情報を上手くデータベースに貯めこんで後で分析できるようにもしたいと思っている。

あとは、今更ながらサニタイズ処理を見直してみたりとか、カレンダーからの日付入力や、郵便番号からの住所自動入力なんかも実装したいと思っている。

しかしVBScriptは貧弱で悲しくなるね。配列が使いづらいし、なにより、連想配列が使い物にならない。配列や連想配列の中にオブジェクトを格納出来ないんじゃ、複雑なデータ構造を表現できないから全然意味ないじゃん、と言う。そのあたりを型関係なく自由に使えないくせに、何がヴァリアント型なんだと問い詰めたい。

投稿者 Songmu : 03:12

2007年11月29日

Designer meets Designers 02 に行ってきた

Webに関してずっと一人で勉強しているのもなんなので、ちょっと刺激を受けにこういうセミナーに参加してきた。

当たり前だが、デザイナー向けって感じだったので、内容が物足りない部分もあった。ただ、実際に第一戦のプロがソフトを動かしているところを見られたのはかなり良かった。普段絶対そんな機会無いからね。女性も多くて、男女比は、5:5か、もしかしたら女性のほうが多かったかも。基本的に男は一人で来ていて、女性はグループが多かったし。

全部で5セッションあって、それぞれ1時間弱程度。それぞれの感想は以下。

SESSION1 今からFlashをつくりたい! 基礎から学ぶアクションスクリプト講座

正直イマイチでした。内容が簡単すぎるというのは当たり前で、それは減点対象にはならないけど、講師の話しかたのテンポや抑揚があまりよくなかったのが残念でした。

「ActionScriptプログラミングはJavaよりも楽しい」

とか言ってたのもちょっとなー、って感じでした。別に、意図としては、「ActionScriptは目に見える結果がすぐに出るから楽しい」てなことを言いたかったのだろうが、これに代表されるように、その辺ちょっと説明がうまくない部分が多かったように思う。

そういや、プレゼンで使ってたパソコンに入ってたウィルスソフトがAvastだった。あのパソコンが個人用なのか、それともProfessional Editionをちゃんと買っているのでしょうか?

このセッションで先が思いやられて、結構テンション落ちてしまったが、これ以降は結構良かったのでこの心配は杞憂に終わった。

SESSION2 Silverlightファーストステップ ~なにができるか、どうつくるか~

Silverlightってことで結構期待していたんだよね。まあ、Flashに対抗してむりやり作ったRIA技術で、ジリ貧のMicrosoft必死だな、って印象がぬぐえなかったのですが、実際はGyaoが採用したりと最近何かとホットです。職場でWindowsMediaServerで動画配信てなこともやっているので、今後サービスをSilverlightに移行することもありえるかもしれず、ちょっとどんな技術かは知っておきたいなと考えていたので。

技術的にはイメージ的に舐めていたのですが、ところがどっこい、デモを見る限りではなかなか面白そうです。Microsoftのクセになかなかやるものです(笑)

Silverlight Airlinesのデモなんかは、おおっと感じたね。Flashと遜色ありません。動画を使う場合は、画質はFLVよりもよく出来るらしいし。

開発自体も、簡単なことだけだったら、JSファイルとXamlファイルをテキストエディタでいじれば出来るみたいなんで、はなっから専用ソフトが必要なFlashよりも敷居が低そうなのも侮れないと思う。

ちなみに、このセッションの講演者が使っていたウィルスソフトはNod32でした。私の職場と同じ。

ExpressionWeb

ちなみに、このセッション参加者内の希望者に抽選で「Microsoft ExpressionWeb」がプレゼントされたのだが、それが当たった。信じがたい。まあ、40本も提供ってこともあったのだが、それでも数百人希望者はいただろうに、変なところで運が良い。

機能的に中途半端であまり使い道はないから、転売するかねぇ。買う人いるかな…。Blend2が出たときにアップグレード価格で安く買えたりするんだったら持っておきたい気もする。ちなみに、市価では4万近くするようですね。まあ、参加費のもとはとりました。

SESSION3 現場で使えるActionScript実用テクニック

いきなり、演者がごりごりコードの話を始めたので、ついていけなかった人が多かったように感じる。結構引いてた人が多かったんじゃないかな。

3次元座標を、2次元座標に変換し、奥行きは透視変換(まあ、つまりは遠近法だ)を使って、オブジェクトを縮小・拡大する事によって表す関数の実装なんかの説明が実用的で面白かった。

あとは、円運動させるところで、sinやcosが出てきて、数学アレルギーの人たちが固まっている様子が伺えました。実際は、演者が言っていたようにそんな難しい事はやってなかったんだけどね。

ActionScript3.0の話なんかも出てきて、ActionScript3.0を理解すると、AIRアプリケーションが作れるよ! てなことも言ってた。知ってはいたが、少しデモが生で見られたのが良かったね。

そのあたり、デスクトップアプリケーションに進出しようとするAdobeとSilverlightでWebアプリケーションに進出しようとするMicrosoftとのせめぎあいが見られて面白い。

私もがんばってActionScript3.0勉強しよ。

ちなみに、このセッションと次のセッションは演者はマック使ってました。

SESSION4 デザイナーのためのAjax動的Web制作術

講演者のテンポも良くて、タイピングが速かった。デモに失敗して詰まる場面もあったが、それもご愛嬌で、逆に笑いが取れていたりしたね。ただ、実際、そのデモ失敗のせいでかなり長い時間講演が進まなかったので、本人にしてみたら痛恨だったでしょう。レベルや内容は参加者に一番あっていたセッションだったと思う。

Gucciの日本語サイトがFlashのようでいて、実は全部Ajaxだったりするのが凄い。でも、あそこまで全部Ajaxでやる必要はないよねとか言い切っちゃったのが笑えた。

必要なところ、地味なところで使うのが理想、とか言っていたのが印象に残ったかな。

あとは、簡単なデモとか。DreamWeaverを実際に使っているところが見られて参考になった。Spryのデモもあって、「ソフトが書き出すコードも大分綺麗になりました」とか言っていたが、いや、あれじゃまだ汚いな、と思った。前は確かにもっと酷かったが。Spryは使っていなかったが、やっぱ使わないなと再認識。

SESSION5 RIAの開発の現場ってこんな感じです!!

講演者の阿部さんがカッコ良くて、声も渋かった。なかなかカリスマ的な雰囲気を醸し出していて、話しなれている感があったね。

スゴイ地図のサービス作成での実際の話をもとにしながら、大規模サービス作成のすすめ方の話なんかをしていた。

ペーパープロトタイピングの話や、二つの評価軸をもとに平面に縦軸と横軸を書いてその中に競合サービスを書き込みながら、サイトコンセプトの落とし所を決めるなんて話は、サイトディレクション以外にも応用がききそうで、参考になった。

ただ、やっている案件のスケールがでか過ぎて、違う世界の話をされている気にもなった。最後に少し時間が余ったので、質問の時間がとられたが、誰も質問しなかった。阿部さんも「勿体無いですよ」とおっしゃっていた。確かに勿体無いが、みんなあっけにとられていて、質問する余裕もなかった感がある。その後、私は質問したい事が思い浮かんで、勿体無い事をしたと思った。

総括

やっぱ突発的に質疑応答が発生したときもすぐに質問が投げかけられるように、もっと積極的に聞いて疑問を持つ姿勢が大事だなぁと思った。こういう機会に質問できないなんて勿体無いからね。

次回は、もっと技術寄りの人が技術寄りの話をする講演会に行ってみたい。

あと、こういうイベントの時は、クリップボード必須です。私は職場では活用しているのですが、今日は持っていかずに、会場についてからミスした事に気がつきました。こちらも次回以降の反省としたい。

投稿者 Songmu : 23:02

2007年11月24日

Larry Wallを心の師と仰ぐ事にした。何故かと言うと…

これまで他人のコードを一部書き換えるくらいしかしてこなかったが、Perlを本格的に勉強中。Perl楽しいよ。「初めてのPerl」を読み終わって、「続・初めてのPerl」を読んでいるところである。

先日、ついに「プログラミングPerl」(通称:ラクダ本)を手にとってしまい、前書きを立ち読みしたのだが、それにすっかりやられてしまって、いつの間にか本を持ってレジに立っている自分がいました。

前書きで面白いと思ったのは以下の部分。

私が、日本の文化について好ましく思うのは、cuteであることを恐れないという点だ。たぶん、それは弱さの表われだと考えるからだ。残念だが、この点に関してはアメリカ人は間違っていると思う。
  Perlはキュートである。キュートと言うにはいささか不格好なのだけど。そう、ちょうどラクダみたいにね。

ここのcuteは単なる「かわいい」以上の意味を持つようだ。ちなみに、私はもともとラクダが大好きです。滑稽そうなイメージとは裏腹に、パワフルな草食動物であるところが良いですね!

まあ、実は私が前書きのどこにやられたかと言うと、次の文なんですけどね。

これまでに見た最もお気に入りのアニメは「少女革命ウテナで、…

ウハ。まあ、日本的なものへの理解が深いのも素晴らしいと思います。

投稿者 Songmu : 23:33

2007年11月23日

前倒し忘年会だからコミケ出展者も参加出来たという

大学サークルのOB・OG忘年飲み。まあ、これから立て込むからこの時期に行うのは大正解。いつもはコミケの締め切りに追われて、年末の飲みだけは来られないY君も来ておりました。彼は今回は、エロは封印して一般で勝負するとか息巻いておりました。とは言え、いつもは2500部だが、今回は1200部だとか。

しかし同人だけで私の年収以上稼いでるって云うんだから恐れ入る。本業は更にそれより稼いでいるわけだからね。家賃48万/月マンションも維持しているようだ。

しかし、今回は技術寄りの人間の割合がいつもにも増して多く、すげーマニア話ばっかで、「ニコニコ動画面白れぇなぁ」とかそんな話ばっかでした。

日本有数の料理サイトのエンジニアをしている後輩と話したのが特に面白かった。充実しているようで、スーパーハカーになりてーとかそんな事を言っておりました。

Railsが楽しいとかそういう話をしてるんすよ。開発スピードが速いとは聞いていたが、どんだけ速いかと言うと、会議中に出た意見に対して、即座にプログラムを変更しプロジェクター内でアウトプットを見せられるとか、無茶な事を楽しそうに話しておりました。うおー楽しそうだ。

方や私はVBScriptでレガシーASP書いてデータベース繋いでとか悲しすぎます。いくらなんでも流石にそれは無いみたいな事を他の人にまで言われてしまったよ(笑)

てことで、私もPerlを勉強中。潰しのきく技術を学ぶ事が急務。自分でサーバー立ち上げてなんかやってやろうかとかも。実は一からパソコン自作したことないしね。

投稿者 Songmu : 23:29

2007年10月18日

技術を学ぶ上でのテーマの探し方

そういや、前のエントリーで書き忘れたことだが、ある技術を学ぶ上で、他の技術で実現していることを、学びたい技術で実現してみるってのは結構有効な手段だと思う。これまで個人的にやったことにWEB関係では、

  • TableレイアウトのサイトをCSSで書いてみる
  • Flashで出来ることをJavaScriptでやってみる

なんてのがあげられるかな。上はCSSを学ぶ上でかなり有効です。

ただ、こんなことを言っていますが、Flashは自腹で購入したくせに全然学んでいません。ここで書いている学習の法則からすると、クライアントソフトで出来ることをFlashでやってみるとかでしょうか。…敷居が高すぎるな。

そういや、今更言及しますが、mixiがやっとCSSレイアウトになりましたね。デザインどうこうはともかく、バナー広告や、検索窓なんかに場所をとりすぎて、メインコンテンツが下のほうに追いやられてしまうのはいけてないと思う。同じような問題を抱えているのがWindows Live Mail。あれもバナー広告がでかすぎて使う気にならんよ。

投稿者 Songmu : 03:12

2007年10月17日

JavaScriptでFlashライクにスライドショー

こんなのを作ってみた。

業者さんがあげてきたFlashで、こういう風に写真がフェードアウトしながら切り替わる形のスライドショーがあったのだが、写真を簡単に入れ替えられないのがムカついて作ってみた。おそらくこんなことが出来るライブラリはいくらでもあるんだろうが、勉強もかねて自作。

ソースはこちら → viewslide.js

使い方

htmlのhead部に以下の用に記述。

<script type="text/Javascript" src="viewslide.js"></script>
<script type="text/javascript">
window.onload = function(){
viewSlide("slide",249,187,["1.jpg","3.jpg","4.jpg","5.jpg","6.jpg","8.jpg","9.jpg","12.jpg"]);
}
</script>

body内でスライド描画したい位置に以下のように記述。

<div id="slide"></div>

説明

viewslide.js内の関数viewSlide()を呼び出しています。引数は左から

  • 描画するhtml内のid
  • 領域の幅
  • 領域の高さ
  • 画像ファイルの配列

となっています。関数の引数にidを指定して描画域を指定する方法は、Nifty Corners Cubeの影響を受けている。

また、これを作っているときに一行でIEのJavaScriptを高速化する方法なんて記事がタイムリーに話題になっていたので、私も使わせてもらった。

それと、次の新規サイト制作セットを一部使わせてもらった。

稚拙なコードなんで笑ってやってください。と言うかあんま見ないでください。

いろいろ課題があって、特に以下の問題に対応しないと致命的な問題になりかねない。

  • 画像が読み込み終わってからスライドを開始するようにする
  • 画像が無いときやレガシーブラウザに対するエラー処理をしっかりする

書きなぐった感じなので、その辺り細かい配慮が足りない。他にも以下のような辺りに対処したい。

  • スライド間の秒数や、フェードアウトのスピードを調整出来るようにする
  • id指定して配置できるくせに、現状ページ内に1箇所しかスライドを配置できない。複数個のスライドを配置できるようにしたい
  • グローバル空間汚しすぎ

1番上は、そんなに難しいことではない。そもそもviewslide.js内の定数をいじれば調整可能なのだが、もうちょっと簡単に実現出来るようにしたい。関数の引数で指定できるようにすればよいのかもしれないが、そんなにいくつも引数指定したら訳わかんなくならないかなとか思って躊躇中。オーバーロード出来るようにして引数省略出来るようにすりゃいいのかもしれないけど。

2番目の実現にはもうちょっと試行錯誤が必要そう。いまいち複数setTimeoutを走らせたときなんかにどうなるかが分かってない。

3番目は、もう、自分の未熟さを思い知る羽目になりました。setTimeoutを使うと、どうしても制御変数やら使いまわす変数やらをグローバル変数にしないといけないような気がするのだが、もう少しスマートに書く方法が絶対あると思う。

本当は、名前空間を上手く定義したり、window.onloadも他との競合を防ぐために使わない方が良いんだろうね。

投稿者 Songmu : 05:11

2007年10月 6日

マルチディスプレイが便利すぎる件について

職場でノートに余った17インチディスプレイ繋いでマルチディスプレイにしてみたら感動した。メインディスプレイでコードを編集して、サブディスプレイで動作確認とか、サブディスプレイのほうで画像編集とか便利過ぎ。これまでずっとノートでXGAまでしか使ったことなかったから、SXGAの便利さに気がついたってのもある(笑)

自宅に20インチくらいのワイドディスプレイを買おうかと考えていたが、自宅のノートに17インチ程度のサブディスプレイつなげた方が良さげ。

投稿者 Songmu : 01:28

2007年10月 4日

CSSとインデントとか

F氏のエントリーに反応してみた。

CSSだってインデントした方が可読性が高いのは当然。ただ、そういう意識が浸透してなかったりするんだよね。そもそもWebデザイナーにプログラムの心得がある人が少ないしさ。歴史が浅いんだよ。DreamWeaverもやっとCSS対応がまともになってきたしさ。

それに、エディタによってタブ設定が違ったり、そもそもブログのCSSをブラウザ上で直接編集しようとするとタブが使えなかったり(私はしないが)、他人のコードを適当にコピペすると、インデントのルールがばらばらで、いちいち修正するのがめんどくさかったり。

転送量を抑えるためにサーバーにアップする前にスペースを削除する妙な拘りを持った人もいたり、DreamWeaverにそういうモードがあったりで。

実際問題、現状のCSSって入れ子が無いから、インデントしなくても読めるっちゃあ読めるてのもある。

しかし、よく言われていることであるが、やっぱ入れ子に出来ないのは不便だよな。とりあえず、入れ子が出来て、あとはインターフェースの実装みたいなことが出来るようにならんもんかね。以下みたいな感じ。

.clearfix{//←実装したい機能
  ...
}
body{
  width: 40em;
  ...
  div#main{
    float: left;
    width: 70%;
    ...
    .section implements .clearfix{//←実装
      ...
    }
  }
}

とか考えていたら、入れ子をサーバーサイドで実装したなんてことが書いてある記事があった。

あとは、CSSの記法ってJSONに似てるよなぁ、JSONだったら入れ子に出来るのに、とか考えていたら、やはり同じことを既に考えて実装までしている人がいるわけですよ。しかもこれはちゃんと継承のルールだって考えられてるし。

やっぱ、「こうなれば良いのに」じゃなくて「こうしてみよう」と思えない、スキルが無いあたりが私の未熟さを物語ってますな。自分でホゲってみようとするハッカー精神が足りないよ。

投稿者 Songmu : 18:00

2007年8月25日

EmEditorでJavaScript

職場でこれまで各拠点がエクセルで管理していた売り上げ管理表をウェブアプリケーションにすることになり、社内開発することになった。

私はhtmlとJavaScript部分を担当。普段はテーブルで表示して、ボタンを押すと、フォームに切り替わるみたいな機能を作成。4時間でJavaScriptを200行程度しかかけない自分に絶望した。エラー出しまくりだし、まだまだ理解していないことが多いなぁと。

いつもEmEditorでコーディングしているのだが、EmEditor標準の設定だと、DOM関連のメソッド、プロパティを強調表示してくれないので、設定ファイルを作成した。たいしたものではないが、ここに公開するものである。

em_js_dom.csv

使い方:
ツール → 現在の設定のプロパティ → 強調(1) タブ → インポート

として、このファイルを指定すればOK。既存の設定を消すかどうか聞かれるが、標準の設定もこのファイルに含めてあるのでどちらでも構わない。良く書かれることであるが、自己責任でお使いください(使う人がいるならね…)

ちなみに今回のプログラムでは、なんとなく連想配列を上手く使えた感がある。というよりかはJavaScriptでは初めて使った。

htmlのselectタグ内のname属性名とそれに対するoptionのリストを連想配列にしておいて、JavaScriptでselect内部を書き出すというもの。

嬉しかったので、ちんけなコードながらここに貼り付けておくことにする。(勿論、このままのものを仕事で書いたわけではない。)

window.onload = insertOpts;
function insertOpts(){
  var selectLst = {//name属性とoptionリストの連想配列
    weather : ['晴れ','曇り','雨','雪'],
    editor : ['Vim','Emacs','EmEditor','秀丸','TeraPad'],
    browser : ['IE','Opera','Firefox','safari']
  }
  var i; var j;
  var nameAtt;
  var tmpLst;
  var optElm;
  var tmpTxt;
  var selectElms = document.getElementsByTagName("select");
  //各セレクトノードにオプションを追加
  for(i=0;i<selectElms.length;i++){
    nameAtt = selectElms.item(i).getAttribute("name");
    tmpLst = selectLst[nameAtt];
    for(j=0;j<tmpLst.length;j++){
      optElm = document.createElement("option");
      optElm.value = tmpLst[j];
      tmpTxt = document.createTextNode(tmpLst[j]);
      optElm.appendChild(tmpTxt);
      selectElms.item(i).appendChild(optElm);
    }
  }
}

投稿者 Songmu : 23:01

2007年8月24日

一家に一枚Accelerated-KNOPPIX

少し前の話だが、休みの間に新橋の事務所のパソコンが一台壊れていた。休み明け早々そんな報告を受け急行した。

結論から言ってしまうと、多分暑さのせいでHDDが死んだんだよね。当該のパソコンがあった場所は西日の当たる雑居ビル内だからさ。クーラーかけないで何日も放置してたからこうなったらしい。まったく酷い暑さですね、今年は。

パソコンはWindowsが起動したとたんに落ちて再起動がかかるというどうしようもない症状。セーフモードでも立ち上がらないし、修復かけても改善せず。

こりゃ、初期化だなとか思ったら、同僚は「データはどうなるんですか?」と。「そりゃ消えちゃうよ。ファイルサーバーにバックアップとってなかったの?」 …全然取ってなかったらしい。信じられない。

仕方なく、データをサルベージすることにした。やったことはなかったが、KNOPPIXでCDブートすればデータを見ることが出来るなんてことを小耳に挟んだことがあったので実行に移してみることに。

最初は、KNOPPIXで検索して一番上に出てきたKNOPPIX日本語版の公式サイトからisoイメージ落としてきてCDに焼き、ドライブにセットしてPC起動! 見事にKNOPPIXが立ち上がりました。HDDの内容も見られます! とか思ったら、日本語ファイルが見られないの。

この辺とか見て設定ファイルをいじってみるもののダメ。

諦めかけていたら、Accelerated-KNOPPIXとか言うのがあることがわかり、一縷の望みをかけてこれを使ってみたらビンゴ。初期状態で日本語ファイルが表示されます。必要なファイルをUSBメモリに移して(USBメモリも挿しゃ認識してくれる)、サルベージ完了。簡単です。

いや、すげー便利ですね。自宅にも一枚置いておくことにしました。

ちなみに、その後初期化をしようとしたら、再インストール時に、「ディスクをフォーマットしています」のプログレスバーが0%から動かない。つまり論理フォーマット出来ない。

こりゃ完全にいかれてますね。物理フォーマットしてみるかねぇ。それでももう寿命な気もするけど。

投稿者 Songmu : 01:42

2007年7月15日

「初めての」という罠 By O'REILLY

AJAXによりJavaScriptが再注目されている中、「AJAXを使ったらこういうことが出来ますよ」といったような流行に乗った書籍は腐る程出版されたのだが、現在のトレンドも踏まえ、改めてしっかりしたJavaScriptの理論やコーディングの仕方を取り扱った本はなかなか出てきませんでした。最近ようやく、DOMも含めたJavaScriptに関するしっかりした書籍が整ってきたように感じます。

これを機会に一冊本を買っておくかと思い、候補に挙がったのが以下の3冊。

  

「DOM Scripting 標準ガイドブック」は一番硬派な感じで私好み。「WebクリエイティブのためのDOM Scripting」は標準ガイドブックよりも中身は薄い感じだが、オブジェクト指向やライブラリの使用に関しての記述があるのが良い。「JavaScript,Ajax,DOMによるWebアプリケーションスーパーサンプル」は、個人的には実用例中心の解説書はあまり好きじゃないのだが、このシリーズはPHPでも人気があるように、解説がしっかりしており、その結果理論も分かるように出来ている良シリーズです。ちなみに、話はそれますがASPによるWebアプリケーションスーパーサンプル 増補改訂版のおかげで私はかなり助かりました。ASPに関する書籍って少ないし。最近は.NETばかりだしね…。

ということで、迷った末、目に止まって買った本が何故かこれ。

今回私が目的としていた、JavaScriptにおける「プログラムのモジュール化」「パッケージの作成と活用、組み込み」「オブジェクト指向」の理解に関して、全てが網羅されていたのが大きい。

相変わらず「初めての」とか吹いていますが、O'REILLYの書籍でこの文言は全く当てにならないのはご存知のとおり。私は既に、「JavaScript 第3版」も読んでいます。(これの第5版も訳してくれないかなぁ)

まだ最初の方しか読んでませんが、

ウェブページ作成の場面で、既にJavaScriptのプログラムを何度か目にしていることでしょう。プログラミングの経験は豊富である必要はありませんが、未経験の場合は他の資料を参照する必要があるかもしれません。(中略) 前述のとおり、この本の対象読者は、「ウェブアプリケーションのおおよその仕組みを理解しており、HTMLとCSSを使った経験のある方」です。

とかいきなり書かれてます。明らかに「初めての」ではありません(笑) まあ、O'REILLYの原書だと、「Learning ○○」となっているのが、機械的にことごとく「初めての○○」と訳されてしまっているのが問題なのでしょう。

ちなみに、最近「初めてのSQL」を読みましたが、かなり勉強になりましたよ。

また、Adobe CREATIVE SUITE 3 WEB STANDARDを買ったので、Flashの勉強もしたい。特にActionScript3.0に関する書籍が欲しいのだが、まだ洋書ばかりで日本語だと書籍が無いね。結局こういう本が日本で発売されるのって、JavaScriptと同じでトレンドが過ぎてからになるわけだ。

いっそペーパーバックを買ってしまうかとも思ってしまうが、高いし、読むのに時間がかかるしで自分にとっては非効率なのが分かっているのでそれはしない。

投稿者 Songmu : 23:57

2007年7月 2日

GoogleとYahoo!とテレビのチャンネル数

Yahoo!JAPANのページビューが世界一位になったみたいですね。私の職種柄、職場では、大小さまざまなIT企業のWEB広告やSEO担当営業と話す機会がままある。どこのIT企業の営業の方々も、「これからGoogleもどうなるか分かりませんよ?」/「これからGoogleは日本でも伸びてきますよ」という論調だが、はっきり言って私はそれを信じていません。

日本でYahoo!が使い続けられる理由に以下のような日本人の特性があげられると思います。以下は箇条書きにしましたが、実際はそれぞれが絡み合っています。

  • 与えられたものでとりあえず何とかしようとする
  • 手段自体をカスタマイズしようとはしない
  • 敢えて他人と大きく異なるものを使おうとは思わない。周りと同じ、最大公約数的に分かりやすく標準化されたプラットフォームを使う

一番上は簡単です。多くの日本人は、とりあえずトップページとしてYahoo!があたえられ、それに大きな問題が感じられないから、それを使い続けているのです。

また、実際問題として、最初にYahoo!とGoogleが与えられたとしたら、多くの日本人はYahoo!を選ぶでしょう。

このあたりは、日本と欧米のテレビのチャンネル数の違いに関係がある気がします。

基本的に欧米はテレビのチャンネル数が膨大にあって、そこから自分の見たいチャンネルを選択、購入しないといけません。逆に日本は、チャンネル数が限られてはいるのですが、(地域によって違いはありますが)ほぼ共通のチャンネルの組み合わせが与えられています。

日本では、なんとなくチャンネルを回してみて、面白そうな番組があったら、それを垂れ流しておく感じです。逆に欧米は全チャンネルを回すだけで何時間もかかるので、自分である程度アタリをつけておかないといけません。

日本人は、よほど見たい番組が無い限りテレビのチャンネルを自分からはあまり選択しません。限られたチャンネル数のお仕着せのメディアに慣れてしまっているのです。

この「チャンネル」を「情報」に置き換えると、Yahoo!が日本的で、Googleが欧米的であることが分かります。

Googleの姿勢は、トップページを見れば分かるように、自分で情報を選びなさいという姿勢です。検索ボックスしかない潔いトップページは、多くの日本人が見た場合は、戸惑いを禁じえないはずです。それよりかは適度に情報が垂れ流されているYahoo!の方が心地よいはずです。

それに対してこういうことを言う人がいるかもしれません。
「Googleだってカスタマイズすれば、自分にふさわしい情報を『垂れ流してくれる』ようになるじゃないか」
と。勿論それは何の反論にもなっていません。

何故ならば、多くの日本人は、「多少使いづらくても、最初から準備されている万人共通のプラットフォーム」が好きだからです。そして、手段自体をカスタマイズする手間をかけようとは決して思わないのです。

実際そりゃそうです。ピアノを買ってきて、それを自分で調律してみようとか、キータッチを調整してみようとか、普通の人は思わないでしょう。

例えが極端すぎましたが、日本のパソコンユーザの大半を占めるライトユーザにとっては、インターネットが普通に見られれば(この表現はおかしな表現であることを承知で使っています)、問題ないわけで、他人より上手く使ってやろうとか思わないのです。

周りと同じようにインターネットを使えれば良く、ブラウザや検索エンジンを自分の好きなようにカスタマイズしたりすることに意味を感じられないのです。もちろんコンピュータが余り良く分かっていないから余計なことをしたがらない部分もあるのでしょうが、コンピュータやインターネット如きにそこまで煩わされたくないと言う姿勢はむしろ健全かもしれません。

だから敢えてFirefoxを使ってやろうとか、Googleを使ってやろうとか思う人は少ないのです。

上を踏まえると、「結局日本人はコンピュータリテラシーが低いんじゃないか」と言う意見が出てきそうです。それは大きくは間違っていません。ただ、厳密な正解は「コンピュータリテラシーが低い人がたくさんパソコンを使っている。」ということになりそうです。

日本の特徴として、識字率に見られるように、全体的なボトムアップの充実があげられます。身も蓋もない言い方をすると、「どんな馬鹿でも生きていける」ような社会が完全ではないにしろ実現されています。これは実際誇って良いことなのではないかと思います。多くの人が生きられた方が有効需要の獲得、社会の活性化に繋がりますからね。その分エリートが育ちにくいとの問題点もよく指摘されますが。

話を脱線させますが、普通の人の10倍稼いでいるお金持ちが、普通の人の10倍ティッシュを消費するわけではありません。そして、逆にティッシュを買うことすら出来ない貧乏人が出てくる状況になるとしたら、それはクリネックスにとって大きな痛手です。稼ぐことは決して悪いことではありませんが、富が偏在しすぎて、貧乏人が出てきてしまうとしたらそれは社会として非常に非効率であることは確かなのです。社会全体の底上げは非常に重要です。

話を戻しますが、日本においてコンビニはあれだけのサービスを展開しながら、誰にでも店員が勤まるようにマニュアルがこれでもかと整備されています。携帯電話だってめんどくさい設定もせずにすぐに誰だって使えるように出来ています。何度も言いますが、これは凄いことです。

i-Phoneがスゲー、進んでるとか騒がれてます。マニアはそう思うでしょうが、冷静に考えて、i-Tune立ち上げてしかも最新バージョンにアップグレードしてアクティベードだなんて、一般的な日本人がそんなしちめんどくさいことをするでしょうか? 多くの人は今の携帯電話のままでよいと思うでしょう。先ほど述べたように、手段のカスタマイズなんかに煩わされたいとは多くの日本人はなかなか思いませんから。

話を脱線させまくりましたが、このように、「誰にだってできる」と言うのは、日本におけるパソコンの世界でも例外ではありません。つまり、コンピュータを全然知らない人間が、平気でパソコンを購入し、使いはじめることが出来るような敷居が低さが実現されています。そして実際そういったユーザーが大半になっていると言う現実があります。

そういった人たちにとっては、尚更、Yahoo!のような、万人向けに標準化されたお仕着せのプラットフォームが使いやすいと感じるのでしょう。SNSにおいて日本ではmixiが一番流行ったのもこのあたりにも原因があると思います。

まあ、いろいろ書きましたが、結局のところ、Yahoo!は日本のインターネット界の「巨人」として既に地位を確立してしまっています。この「巨人」と言うのはプロ野球界のジャイアンツと言う意味です。一度「巨人」になってしまった以上、たとえどんなに体質が腐っていても、方針がおかしくても、トップに君臨し続けるのです。ロッテが逆転することはありえないのです。日本はそういう国です。

投稿者 Songmu : 02:14

2007年6月15日

受験番号SW372-XXXXの方は、合格です。

ソフ開受かってた。思っていたより点数高くて、そこそこ余裕の通過でした。あの出来でこれだけの点数が取れてしまったのが意外。

対策は、完全教本に目を通したくらい。読んでても分からないところ結構あったし、やばいなぁと思っていたのだが。しかし、これで晴れて実務経験の無いソフ開保持者の出来上がりです。

それで今日仕事でJavaScriptでWebアプリ(とも言えないようなもの)を書いていたのだが、もう全然だめですね。JavaScriptのスコープとか、オブジェクト指向とか全然理解してないの。Functionを機能ごとに細分化して使いまわすとかが下手糞。こんなのがよくソフ開受かったもんだよ。

ソフ開でひと段落と考えていたのだが、この点数なので、色気を出してちょっと次も狙ってみたくなってもいる。順当に行けばセキュアドだろうか。アプエンは厳しいか。データベースという手もありそう。

そういや、Safari Windows版のベータが出ましたね。Appleのこの姿勢はかなり評価できる。

投稿者 Songmu : 02:55

2007年6月11日

私がMAC使いが嫌いな理由

とまあ、ちょっと危険なタイトルをつけてしまったが、別に全員が嫌いなわけじゃないのです。ただ、一部非常に偏屈な人種がいて、そういう人はイヤになる。

虐げられている(と感じている)少数派特有の強みを前面に押し出してくるところがキライである。そういう人に限って、自分の痛みには敏感なくせに、他人の痛みには驚くほど鈍感だったりするんだよ。

「何でMAC対応じゃないんですか?」とかそういったことをすぐ言ってくる。勿論、実際MAC非対応の部分もあり、努力不足を認めざるを得ないこともある。ただ、それでもこちらはかなりMAC環境に気を配ってはいるのである。

それに引き換え偏屈なMACユーザーはWindows環境のことなど顧みようともしない。sitファイルを送ってくるだけならまだしも、Windows環境で解凍したら文字化けする圧縮ファイルを平気で送りつけてきたりするのだ。

しかも、「何でMAC対応じゃないんだ!?」とか言ってくる人の多くは、自分の側の問題で見られない場合が殆どなのだ。自分の側の問題なのに、すぐ人のせいにする癖がついてしまっている。

以前なんか、とあるMACユーザーが社内で使っているネットワークやコンピュータに制限がかかっており、そのせいでストリーミング用のポートが遮断、プラグインのインストールが制限されていて、動画コンテンツが閲覧できないことがあった。

それなのに、当の本人は、MACとは関係ないにもかかわらず、「MACユーザーに優しくない」とか言って、結局最後まで完全には納得してもらえなかった。

どういう世界にしても、依怙地になっている少数派ってのは厄介だ。歩み寄ろうとしても、簡単に近づかせてくれないから。

そうなると、こっちもこっちで「プレステのソフトがサターンで動かないのは当たり前だし、その逆もまた然りだ」とか乱暴なことを言いたくなっちゃうよね。それも宜しくないのは確かだが。

その点Linuxユーザーは潔いよ。

そういや、職場で部下と言うかアシスタントをつけてもらえることになりそうである。これから募集かけるんだけど。

中国語が多少は出来て、Web関係の知識がそこそこある人。それぞれのハードルは高くないんだけど、両方合わさると少なそうである。しかも募集形態は社員じゃなくてパートだし…。来てくれるかねぇ。

もちろん募集要項に作業環境はWindowsになる旨を明記しておいた(笑)

投稿者 Songmu : 01:32

2007年5月28日

Javascriptでいろいろ

最近、少し仕事に余裕が出てきたので、ちょっと遊びもかねて業務効率を上げるツールをいくつか作っている。Javascript+CSS+htmlで(笑)。 例えば、名札作成スクリプト。csvファイルのリストを読み込んで、スタッフの名札を一気に出力するツールである。イベントなんかで専用の名札を使いたいときなんかを想定して作った。ロゴ画像などをcsv内の指定によって入れ替えられるようにしている。

cssで{width:"9cm";height:"5.5cm";}とか指定したら印刷時にぴったりそのサイズで出力してくれるのでかなり便利。CSSでトンボとか出せるようになるともっと便利なんだけどなぁ。一応策定はされているようだが。もはやWeb技術じゃないね。

Wordとかで同じこと出来るのかもしれないが、Office苦手なのでJavascript。まあどっちにしてもたいしたことをやっているわけではないが。

そういえば、ニコニコ動画でhtmlのtable手打ちでセルの色を指定しながらドット絵を描くという神業動画があり驚愕した。アメーバビジョンに転載されたものが以下。

これを見て思ったのは、javascriptとcssを使って、鉛筆ツールとスポイトツールだけの簡単なお絵かきツールなら結構簡単に作れるかもなと言うこと。

描画部分に関しては、1×1のボックスを敷き詰めて、全てに固有のID('x0003y0043'のような感じ)を振っておいて、そのボックスの背景色がマウス操作によって入れ替わるようにすればよい。

スポイトツールも同様に、ボックスを敷き詰めておき、こちらは逆にマウス操作によって背景色を取得するようにしておけばよいだけだからね。描画色の指定に関しては、普通にRGBで指定させても良いし。

なんか作りたくなってきたかも(笑) 既存のものはたくさんあるようですが。

投稿者 Songmu : 01:16

2007年5月25日

どうやらWebにハマっているようで

友人がやっているカンボジアの学生への基金のプロジェクトに絡んで、Webサイトを私が作成することになりそうである。もう3年目になるのだからちゃんとしたWebサイトを持ったほうが良いよというお節介もあり、なによりどうやら私自身の中にこれまで培ってきたスキルを使ってWebサイトを一から構築してみたいと言う欲求があるようで、手を挙げた。

そういえば、5月のGW明けにAdobeのCreative Suite3の日本発売日の発表があった。かねてからGW明けに発表があるという噂があったので、かなりわくわくそわそわしながらその発表を待っていた。発売日は6月22日。発売日にWeb Standardを買ってやろうと思っています。こんなに発売が待ち遠しくて、しかも発売日にソフトを買うだなんて、クロノトリガーと魔装機神以来でしょうか。ソフト違いですが。まともなパッケージソフトを買うのも、学生時代にMethematicaアカデミックを買って以来ですね。かなりキヨミズ。

Illustratorのライブトレースがかなり魅力的だが、流石にWeb Premiumまでは手が届かないかな。Fireworksは使ったことがないが、CS3でもグラデーションメッシュが無いらしいのが痛い。

そういえば、先日、職場で業者から送られてきたイラレCS2形式のファイルが開けなくて困ったことがありました。ご存知のとおりCS2のファイルは、旧バージョンのイラストレータでは開くことが出来ないのです。

ところが、戯れにAdobe Readerで開くと、…なんと開くではありませんか! 勿論編集はできませんが、閲覧は可能です。いやはや、流石は“Adobe” Readerです。

じゃあ、もしかして、InDesignも開けるかも、と試みてみましたが、敢え無く失敗。そういえば前にも同じ試みをしたことがありました。しかし、Illustratorのファイルは開けてInDesignが開けないだなんて、逆のような気がするよ。

と言うことで、今はどうやらWebにハマっているようで、ついコンピュータ関係の書籍を読んでしまい、中国語の勉強をあまり進めていない危機的状況。

投稿者 Songmu : 01:56

2007年5月21日

会話文の正しいHTMLマークアップ

このエントリーを書いたときに、会話文のマークアップに迷った。結局安易に<br>で区切ってしまっている。実際は会話文はどのようにマークアップするべきなのでしょうね。Web小説の世界なんかでは結構議論になっているようである。いくつか考えてみた。

<br />を使ったマークアップ

Q「質問質問質問」<br />
A「回答回答回答」

前回私がやったマークアップですが、これは単に改行しただけです。

現実的なマークアップ

html
<p class="dialogue">
  <span class="utterance">Q「質問質問質問」</span>
  <span class="utterance">A「回答回答回答」</span>
</p>
CSS
.dialog span.utterance:after{
  content: "\A";
}
ただ、上記CSSだとIEなどでafter擬似クラスを解しないUAでは改行してくれないので、以下のような指定をすることになるのでしょうか。
.dialog span.utterance{
  display: block;
}

ただ、見た目改行させるためだけに、インライン要素をブロック要素にしてしまうってのは、やりすぎな感じがする。<p>タグの中に、ブロック要素を格納することになるわけだしね。それだったら素直に<br />を使えばよい気もするよ。

やりすぎなマークアップ

html
<p class="dialogue">
  <span class="utterance"><span class="speaker"><abbr title="Question">A</abbr></span><span class="voice">質問質問質問</span></span>
  <span class="utterance"><span class="speaker"><abbr title="Answer">A</abbr></span><span class="voice">回答回答回答</span></span>
</p>
CSS
.dialog span.voice:before{
  content: "「";
}
.dialog span.voice:after{
  content: "」";
}
.dialog span.utterance:after{
  content: "\A";
}

これは流石に冗長か。ちなみに、会話文の中にさらに段落や改行、二重かぎカッコでくくる要素が出てくる場合は、更に<span>でネストするのかね。うげ。

結局何が言いたいかと言うと

思うに、どうマークアップすべきかなんて、Web上で文書を公開する手段でしかないhtmlに縛られている状態は滑稽である。特に余りにも「正しい」htmlを書くことにこだわりすぎて、マークアップのためにマークアップする状態に陥ることは愚かである。もちろん、文法的に誤りの無いhtmlが書けることは必要だが。

とか言ってしまうと、身もふたもないが、結局、何のためにマークアップするのかをはっきりさせれば、自ずからどのようにマークアップすれば良いかが分かるのです。私は勿論そうなっていないが、そうなることが理想なのかな。

つまり、会話文を上に挙げた例のようにマークアップしたとして、単に見た目の改行以上の意味を持たせなくて良いと思うのなら、<br>で区切ってしまって良いのです。

ただ、細かくマークアップしておくと後々便利なことがあります。上記の会話文の例だと、たとえば、ある文章の中で、

  • 何回、会話文が出てきたか
  • 会話文が占める割合はどれくらいか
  • とある人間がどれくらい、どれくらいの長さ発言したか

などを、DOMを使ってすばやく調べることが出来ます。そういったxhtml文書の特性をどのくらい活かしたいかによって、どのようにマークアップするかを決めればよいのではないでしょうか。

投稿者 Songmu : 01:24

2007年3月18日

Portable SleipnirからPortable Firefoxへの移行

明日から神戸出張です。一週間まるまる神戸である。今回は割と根回しがしっかり出来たので、向こうではそこまで苦労せずに済めばよいなぁと甘い期待。21日の祝日をぶつけられてしまったので、そこはしっかり休みます。幸いホテルの近くにプールを見付けたので、そこで泳ぐ予定。出張に水着を持っていくこの不真面目さ。

出張時は私用のパソコンは持っていかないが、USBメモリに個人データやアプリケーションを突っ込んで持っていくことにしている。

で、例によってUSBメモリにはPortable Sleipnirが入っていたのだが、これにPortable Firfoxを入れてみることにした。

とはいってもそんな対したことではない。インストールにあたっては以下のサイトを参照した。非常に役に立った、感謝。

Portable Firefox 2.0 系の日本語化

さて、個人設定をどうやって移し変えたらよいものかと調べてみたが、情報が古かったりして、詳しく書いてあるサイトがあまり無かった。一応Firefoxの設定ファイルが、Windows XPの場合、

%AppData%\Mozilla\Firefox\Profiles\hogehoge.default\

というフォルダ以下に格納されていることは分かった。ここの内容をごっそりPortable FirefoxがインストールされているファルダのDataフォルダ以下のDefaultフォルダ内に強引に突っ込んだら、立ち上がりにかなり時間(30秒前後!)を要したものの正常に起動した。アドオンも問題なく動くようだ。とりあえずこれで使ってみることにする。

投稿者 Songmu : 22:56

2007年2月28日

Firefoxの難点を敢えてあげてみる

エイヤっとFirefoxに切り替えて使っていますが、非常に快適です。本日も勤務先で簡単なWebページを一枚ペラっと作るのに非常に役に立ちました。ちなみにちょっと遊び心を出してNifty Corners Cubeと言う角丸ボックスを実現するJavascriptライブラリを試しに使ってみました。

さて、それでも何日か使ってみると流石にアラも見えてきます。そのあたりを少しあげてみます。

まず、あげられることは、起動が遅い、ということ。というか、IEコンポーネントブラウザに比べると遅いのは仕方がないのかもしれないけど。IEってエクスプローラーとかとモジュール共有してるのでしょうし、となると、Windows起動時にプログラムの一部が立ち上がってる形に近い訳だからね。(かなりいい加減な記述なので信用してはいけない) それにFirefoxも立ち上がってからの動作は快適なのだから別に大きな問題ではない。

次に、ページのズーム機能がいけてないということでしょうか。OperaやSleipnir2.xx、IE7では実装されているページのレイアウトをそのまま拡大、縮小出来る機能を実現できるアドオンは現在無いようです。実際、ブラウザの現在の仕様上、アドオンでの実現は難しいみたいですね。

別にこの機能にこだわりがあるわけでは決してないのだが、まあ、他のブラウザで出来ることが、Firefoxで出来ないとなるとちょっと悔しい。

あとは、検索ボックスの問題。基本的な検索に関しては問題ないが、辞書との連携に難有りです。私はたまーに英語でメールを書いたり、ドキュメントを作ったりすることがあるので、検索ボックスですぐオンラインの辞書が使えると重宝するのです。Sleipnir2.xxでは、検索ボックスの最初に一文字打ち込むと検索先を切り替えることが出来て、“e hoge”だと英和、“w ほげ”だと和英といった形で一発で辞書での変換が可能だったのですが、Firefoxではそういったことが出来るアドインは残念ながら無いようです。

仕方がないので、Google検索で“和英 ホゲ”とかやって代用しています。職場ではSleipnirがメインなので、“w ほげ”とかもまだ使ってはいます。

投稿者 Songmu : 01:50

2007年2月21日

Sleipnirを擁護する

てことで、Firefoxマンセーになってしまった私ですが、長年お世話になったSleipnirを簡単に見限ってしまったことに罪悪感を禁じ得ません。なので、TOPページにはFirefoxは加えましたが、Sleipnirは外していません。

実際、Firefoxを使い続けていると、ちょっとは悪い点も見えてきます。大きな点は、Sleipnirに比べるとリソースを喰う点でしょうか。やはり、単独で動いているSleipnirに比べると、いろいろ後から拡張機能を盛り込んだFirefoxの方がメモリ使用率は高めになってしまいます。特にTab Mix Plusを導入したら、動作がやや重くなりました。

ただ、メモリ1GBあると全然問題ないんだけどね。むしろなぜか動作自体は、SleipnirよりもFirefoxの方が軽快なのだ。

昔は、Sleipnirはタブブラウザながらの動作の軽快さがウリの一つだった気がするのだが、Ver2から重くなり、バージョンアップを重ねるごとに重くなるという悪循環を繰り返している気がします。

多分作者もそのあたりに気が付いて作ったのが、Graniなのでしょう。動作環境のメモリ64MBを謳っているように、多分かなり動作が軽快なのでしょうね。なので、Web Developerなどの拡張機能が不要な一般の人が普通にブラウジングする分にはGraniはかなり快適なんじゃないかなぁと想像します。

しかし、Web Developerマジ便利。ボックスの罫線を表示させるとか便利すぎ。今までボックスの領域が分からなくなったときに、CSSに手を加えて、Borderの罫線を表示させたりしていたのが馬鹿らしくなってくるよ。ワンクリックでHTML-lintが使えるのも素敵過ぎ。

てことで、結局Firefoxマンセーになってしまうんですけどね。

投稿者 Songmu : 01:56

2007年2月20日

Vista導入ならず

職場で新たに拠点を構えることになったのですが、そこのハードウェア関係なんかは私が担当なわけです。いつもDellで安っすいPCを購入しているのですが、一番安いモデルだと、もはや法人向けでもVista搭載モデルしかなくて、超ビックリ。そんなすっぱり切り替えてよいのでしょうか。

こりゃ腹を据えてVista導入か、とか思っていたのですが、職場のグループウェアやウィルスソフト、VPNなんかの関係でチキってXPにしてしまいましたとさ。実際グループウェアが満足に動かないらしい。

結局HPで買うことにした。Dellより大分高くなってしまうのですが、苦渋の決断です。DellはXP売らなくて良いのかね。絶対機会損失だと思うのだが。多くの法人は現段階では絶対乗り換えたくないと思うのでそうは買ってはもらえない気がするぞ。実際、Dell以外のほとんどのメーカーは選択肢としてXP搭載モデルを残している状況。

あ~あ、Vista導入になりかかっていたので、めんどくせーとか思いながら、ちょっとわくわくしていたのですけどね。仕事が仕事なので、近々職場に一台は導入することになるのだろうけどね。私の場合必要なのはWebの表示確認と、簡単なWebアプリケーションの動作確認ぐらいだけど。

投稿者 Songmu : 01:50

2007年2月18日

Firefox、Sleipnir(+α)化計画とその実行過程

ずっとSleipnirを使ってきたのだが、使用のマシンに関してはFirefoxに乗り換えた。Sleipnirで便利だと思っていた機能がFirefoxのアドオンを使えばほぼ全て実現できることに今更気が付いてしまった。Firefoxは動作がもっさりしている印象があったが、Ver. 2.0を使ってみたら全然軽快で、かくしてSleipnirの利点が全く無くなってしまいましたとさ。しかも、Firefoxの方がさらに優れた拡張機能を備えるってんだから…!!

しかも標準のブラウザに指定するのが楽なのが地味にいけてます。Sleipnirだと標準のブラウザに設定しても、メッセンジャーやGoogle DesktopからのリンクなんかはIEで立ち上がってきてくるという中途半端な標準具合で、それをSetBrowserで強引に修正したりしたりしていたのですが、Firefoxは設定一発でした。

改めて、オープンソースの威力と、プロプライエタリの限界を見せ付けられる形となりました。Sleipnirはちょっと応援していたので切ないね。これで晴れてGeckoエンジン使いとなりました。

これまでSleipnirを使ってきた大きな理由として

  • 動作の軽快さ
  • タブブラウジング
  • マウスジェスチャー

この3点が挙げられる。マウスジェスチャーで主に使うのはページ(タブ)を開く、閉じる、切り替える、更新するなど。特に秀逸だったのは、右クリックをしながらマウスホイールを動かすと、タブをグリグリ切り替えられる点で、マウスジェスチャー本家のOperaなんかより全然軽快に動くので気に入っていた。リンクをホイールクリックすると新規タブで開く点も密かに気に入っていた。(実はこのあたりに関しては、Sleipnir Ver.2.xx よりも 1.66の方が軽快だったりするのだが)

さてその辺りの優位性が、これから紹介する3つのアドオンによって駆逐されてしまいました。

All-in-One Gestures

マウスジェスチャーを実現するアドオン。各種ジェスチャーの設定、ホイールでのタブのぐりぐり切り替えにも対応。動作も全然軽快。

Tab Mix Plus

タブを開く位置の設定などを細かく設定できる。デフォルトだと新規タブが一番右に開いてきてしまうのが気に食わなかったのでインストール。

これで新規タブを開いたときに、現在のタブの右側に開くように設定。タブを閉じたときもそのタブを表示させる直前に表示されていたタブを表示するようにした。また、Javascriptでのポップアップウィンドウも、別ウィンドウではなく、同一クライアント内で開く設定にできた。

密かに優れものなのが、ツールバーに「最近閉じたタブを開く」ボタンを追加できること。

removetabs

Sleipnirで重宝していた、タブをまとめて閉じるボタンをツールバーに実装するアドオン。全てのタブを閉じる、右側のタブを閉じる、左側のタブを閉じる、他のタブを閉じる、と欲しかった全ての機能を実現できるので合格。

他に便利なアドオン

とまあこんな具合でSleipnirの優位性が消し去られてしまいました。他に、以下のアドオンなんかが便利です。

Google Toolbar

ご存知Google Toolbar。Sleipnir最大の弱点(?)としてページランクを表示できないことがあげられますが、もちろんFirefoxだとそれが可能です。私の場合、検索ボックスもその他のアイコンも全て取っ払って、ページランクだけをウィンドウ右上、メニューバーの隅っこで表示させるようにしました。検索ボックスはブラウザ標準のものを使用します。そういえば、このページがいつの間にかページランクが3とかになっててビックリです。

IE Tab

世の中にゃあIEでしかまともに見られないサイトも数多くあります。(例えばこんなとこ) そんな腐ったサイトにもちゃんと対応してあげるための非常に心優しいアドオン。サイトを表示するときのレンダリングエンジンに、Trident(IEのレンダリングエンジン)も選べるようにするものです。

単に切り替えられるだけではなく、特定のサイトをTridentで開くように予め指定できるのが優れものです。(正規表現での指定にも対応) これで、GyaoやらWindows Updateやらmhtファイルやらも一発でちゃんと表示してくれるようになりました。

社内での業務用WebアプリケーションはIEでしか動かないものも多いので、業務用PCはSleipnir継続かなぁとか考えていたのですが、これを使えば何とかなるかもしれません。

ただ、これで表示させた場合、当然のことながら、表示画面はIEのそれなので、コンテキストメニューがIEと同じであるほか、各種アドオンも使えなくなります。つまりマウスジェスチャーなんかが使えません!! なので、Tridentを使ったタブブラウザを使いたい場合は、やはりSleipnir、Lunascapeなんかに軍配が上がるでしょう。

Web開発にあたって、便利なアドオン

これまで書いてきた位では、SleipnirもFirefoxもどっちもどっちなのですが、決定的に差がつくのはこのあたりの拡張機能でしょうか。

各種説明は下のページが詳しいので説明は譲りますが、私が入れたのは、CSS用に「Web Developer」、JavaScript用に「Firebug」、画面の好きな場所のサイズを測れる「MeasureIt」、カラーコードを抽出できる「ColorZilla」以上4点。

WEB制作時に便利な9つのFirefox拡張機能(Add-ons)(外部リンク)

「Sleipnirは機能がたくさんあって便利… そんな風に考えていた時期が俺にもありました」
てことで、これからFirefox使いになります。

投稿者 Songmu : 21:44

2007年1月21日

「NHKスペシャル|グーグル革命の衝撃」を見て

一応チェックした。Googleに対してどうもネガティブな雰囲気でしたね。Googleを新時代のメディアと考えると、NHKにとってかなり脅威でしょうから、ああなったと考えてしまうのは考えすぎでしょうか。

Adwardsで稼ぐ青年とか、Googleが情報を操作している、というような極端な事例ばかり取り上げて、それでいて、Eric Schmidtがやたら壮大なことを自信たっぷりに、マッドサイエンティストチックに堂々と言うもんだから、Googleに対して殆どの人が良い印象を持たなかったのじゃないかと想像する。

他にも社員の落書きにあるgoogle.govとかgoobleなんか普通のギャグのノリだと思うのだが、ああいう風に取り上げられてしまうと、空恐ろしく感じてしまう人も多いでしょう。

中国での検索結果の話なんか、Googleはしぶしぶ検閲をしていることを公表しているのに、そのくだりが無く、密かにそういうことをやっている感じで放送されていたし。

無線LANのアクセスポイントでPCの位置情報が分かるとかそういう話があったが、そんなことは当たり前だ。いやなら繋がなきゃ良い。個人情報どうのとか言うが、少なくとも自分のIPアドレスはインターネットに繋いだ時点で絶対に公開しているのですよ!?

話がそれるが、インターネットは匿名だとかよく言われるが実際は全然匿名じゃありません。というより、実生活とほぼ同程度に匿名性が保たれているというだけの話です。コンビニでコンドーム買ってったヤツの名前なんて特定しようと思わなきゃ分からないし、それと同様に掲示板に書き込んだヤツも調べなきゃ分からないというそれだけの話です。裏を返せば、調べりゃたいてい分かるし、時には分からないこともあるということです。そんなの実際の犯罪捜査でも同じでしょう。

何にも分かってないメディアが匿名だ匿名だと煽るせいで、本当に匿名だと感じてしまっている人も多いし、そのせいで悪用する人も絶えない感じがするね。

インターネットで問題があるとすれば、その嘘っぱちの匿名性ではなく、インターネットを利用して人と接している時でも、人と接している感覚が乏しくなってしまいがちだということにあると思うのですよ。現ナマより、カードのほうが大きな買い物をしてしまうという、そんな感じに近いと思う。

話を戻すが、Googleを擁護するわけではないが、ちょっと悪意が見える番組構成だったかなと思う。多くの人がGoogleに対して良い印象を持たなかったかもしれないが、お前らがきっと普段Yahoo!でやってることと同じことなのですけどね。

Googleが検索市場で独占的状態になっているのは危惧すべきなのかもしれないが、それでも現在Googleが国家のように多くの人に監視されているメディアであり、インタラクティブなメディアであることを考えれば、既存のメディアに比べても、別に危険な存在ではないし、むしろ安心なくらいかもしれませんけどね。それに他の検索エンジンもがんばっている現在、まだまだ独占的というには程遠いし。

むぅ。逆にGoogle礼賛ぽくなってしまったので、sage(?)

追記: 勤務先もSEO対策をしているのだが、上司がこの番組をちゃんとチェックしていた。すばらしい。SEO Spamの話なんかもあれを見て理解したようで、助かった。今後話を通しやすくなったと思う。

投稿者 Songmu : 23:46

2007年1月14日

TOPページ更新

このドメインにも一応TOPページがあったのだが、余りにも酷いものだったので、一応それなりにまともなhtmlで書きなおした。CSSもちょっと真面目にファイルを分けて、レトロブラウザにはCSS適用しないようにしたり、default.cssを設定して、ブラウザごとの差異が出にくいようにしたりしてみた。

現状はこの程度のデザインだが、デザインを変更しやすいようにCSSを組んでみたので、今後もしかしたらもう少し変えるかも。リキッドデザインにしてみようかとかも思ったが、無茶な話だと思ったね、実際。

それと、この日記以外にコンテンツを増やすかもしれない。一応ネタはある。

投稿者 Songmu : 23:04

2006年12月14日

機械のトラブル続きの年末で

朝、職場のプリンタ(複合機)が調子が悪くなったと連絡を受けたので、別の事務所に直行の予定だったのだが、先にとりあえず職場に行った。コピーとファックスは動いているが、パソコンからプリントアウトが出来ないのでドライバの問題かなとかとも思ったが、いったん電源スイッチ落として入れなおしたら一発で復旧した。電話口でそれくらいの指示が出来なかった自分の無能さに腹が立つ。1時間のロス。

出先には、PCの調子が悪いとかで見に行ったのだが、ウィルスにこっぴどくやられていた。しかも誰かがフリーのウィルス対策ソフトをインストールしていたせいで、もともと入っていたソフトと競合して、その警告を出すは、ウィルスの検知は止まらないわで、愉快なくらいにっちもさっちも行かない状況だった。問答無用で初期化した。実は行く前からそのつもりだった。CD-ROMドライブが空いたり空かなかったりと、ハード的にもかなりキており、クリップを針金状に伸ばしてこじ開けてCD挿入したりした。

文字化けしたメールがあるとかで、その解読を頼まれた。見ると、数値文字参照のまま送られてきたメールである。こんな感じのヤツである。


&#25991;&#23383;&#21270;&#12369;&#12384;&#12424;

Webメールはこういうのが多い。特にYahoo!。今回は送ったほうも送ったほうで、Yahooであるばかりか、yahoo.co.ukだった。送信者は純粋な日本人であるにもかかわらずだ。

適当にメモ帳開いて、以下のように記述して、htmlファイルとして保存してブラウザで開いて解読した。

<html>
<body>
&#25991;&#23383;&#21270;&#12369;&#12384;&#12424;
</body>
</html>

先日、とある事務所のプリンタが壊れ、保証もきかないようだったので、コストも考えてソッコー別のを買い換えて据え付けたことがあった。故障した機械は本社のシステム部署の人たちに送っていたのだが、彼らは分解修理して直してしまったらしい。給紙部分のローラーのゴムが磨耗しており、そこをホゲったら直ったそうだ。

修理にかかる時間を考えるとコストに見合わない気もするのだが、システム課の意地であろうか。流石である。ホント機械が好きだよね彼らは、と感心するよ。しかも、分解修理の後、ネジが一本余ったというお約束までかましたらしい(笑)

投稿者 Songmu : 02:47

2006年12月 6日

コンピュータとか資格とか

仕事でJavascriptとレガシーASP(VB)を連携させて簡単なWebアプリケーションを作っているのだが、ホント自分で書いてて、コードが汚くていやになる。あちこちを参照しあうようなスパゲッティプログラムになっているわ、サブルーチンとしてまとめなきゃいけないようなコードをひとつのルーチン内でまとめて書いてしまっていて独立性は保てていないわで酷いもんである。

設計をしっかりして仕様をまとめておかないといけないなぁと反省しきりである。オブジェクト指向の何たるかを肝に銘じなくてはいけません。

まあ、オブジェクト指向なんて所詮はイデア論であり、2300年以上前にアリストテレスに否定されているわけですけどね。そんな、負け惜しみなのか与太話なのかわからないたわごとを以前アリストテレスの形而上学を読んでいたら思いついたものだが。

しかし、基本的にまともにコーディング経験がなく、我流なのが問題だね。もしソフトウェア開発技術者に合格したとしても、実務経験のないソフトウェア開発技術者資格保持者って微妙すぎる気がする。

資格といえば、同僚が中国語検定1級の1次に合格したらしく喜んでいた。凄い。400人弱が受けて、通過者は6人だった模様。2次もがんばって欲しいが、最終的には合格者無しの年もあるみたいだねぇ。

そんだけ苦労して受かったとしても、3年で効力を失うって言うんだからね。1級試験だけは年1回開催なので、要は中国語検定1級保持者ってのは日本全国に一ケタしかいないわけですよ。受かっている人も、基本的に更新対象者ばかりなんじゃないかと言う。

こういってしまうのは悲しいが、私は未来永劫中国語検定1級を受けることはないでしょう。準1級は目標にしたいと思う。2級は常時受かるくらいの実力は持っておきたいところ。

投稿者 Songmu : 22:31

2006年11月23日

ちょっとづつマイナーチェンジ

サイト内にこのサイトについて、とプロフィールを追加。トップページからのリンクも張った。

この2つのページはこれだけだとちょっとさびしいので、dl, dt, ddタグの装飾を考えないといけないな。

このページ上部の横に並べたリンクも本当は、<li>とかでタグ付けしたほうが良いのだろう。「|」で仕切りを作っているあたりも、かなり適当な感じ。余裕があったらいじりたい。

さしあたってのその他の課題。

  • フッターの装飾
  • リストタグの装飾(メインコンテンツ部・サイドメニュー部それぞれ)
  • <h4>タグの装飾
  • blockquote, pre, codeタグの装飾

この3連休はゆっくりできた。ボウリング、エッシャー展、友達と飲み、ロード、恋人、読書、サイトいじりと一通りこなしたので満足。

投稿者 Songmu : 23:43

2006年10月28日

CSSハク的なこと

長いエントリータイトルを書いて、それが2行にまたがったときに表示に不具合が出ることに気がつき調整した。「デキるやつ…」を書いたときに気がついた。2行にまたがるものが果たして見出しとしてふさわしいのか? という話はこの際置いておく。

これまでエントリーのタイトルが入るh3タグにはCSSでheightを絶対値で指定していたのだが、それだとボックス内の内容が溢れてしまった場合、はみ出して表示されてしまうのだ。IE6だとボックスが適宜(?)自動拡張されるのだが、それはIE6の実装のバグらしい。

てことで、Firefoxだと表示はこんなに悲惨なことになっていたとさ。

IEでの表示
Firefoxでの表示

てことで、ボックスの内容によって、適宜ボックスのサイズを自動拡張してくれるようにするためには、heightでなく、min-heightを指定すれば良いようなのだが、ここでひとつまた問題がある。それは、「IEはmin-heightを読まない」ということだ。

ただ、IEはheightを指定していれば、適宜ボックスを自動拡張してくれるので、IE以外にはmin-heightを読ませ、IEにだけheightを読ませるようにすればよいということだ。なので、スターハックを使用することにした。具体的には以下のとおり。

変更前
.content h3 {
  height: 23px;
  /* 省略 */
}
変更後
.content h3 {
  min-height: 23px;
  /* 省略 */
}
* html .content h3{
  height: 23px;
}

このサイトこの程度とは言え、CSSハックを使うのは初めてのことだ。だいたい、最新のブラウザなら特に表示に問題ないように、簡単なCSS記述しかしてなかったからね。しかもMac使いや、レガシーブラウザを使っている人はノーサポートですから。商業サイトじゃあるまいし。そのへんどっかに書いておいたほうが良いのかもしれないけど。実際IE5.5でこのサイトを見に来ている人は何人かいるようだ。多分2段組が崩れていると思われる。ちなみに、IE7はスターハックを読まず、min-heigthは読む実装になっているようなので、表示は崩れない。

このエントリーは完全に自分に対する備忘録であるとともに、画像とそれに対する簡単な説明をhtmlでマークアップするときに、定義型リストdlを使ってみたかったってのがある。それと、preタグとcodeタグでcssソースをマークアップしてみたかったってのもある。まだ、何もCSS設定していないが。

投稿者 Songmu : 21:03

2006年10月15日

既視感(デジャヴ)じゃない

情報処理試験を受けた。基本情報。今更って話もあるが、最近考えが変わって取れるものは取っておこうかと思うようになったもんで。たいした資格じゃないが。

会場が玉川大学だったので、自転車で行った。と言うか、ご存知のようにスーツじゃないときの単独での移動手段はほぼ自転車一択だ。免許の更新も、中国語検定も自転車で行った。そういうところに自転車で来る人は滅多にいないのでなかなか痛快(?)。なので、マイボールしょって自転車でボウリング行くスタイルもなかなか気に入っている。

受験生の時も玉川大学辺りに模試を受けに行った気がしていたのだが、ビンゴでした。校舎の前に自転車を置いたのだが、その場所を見て受験生のときもまさしく同じ場所に自転車を置いたのを思い出した。今日も代ゼミの模試をキャンパス内の別の所でやっていたようだ。

試験は割かし簡単だった気がするし、実際難易度は易しかったとネットでも言われているみたいです。簡単に答え合わせをしたが、午前午後とも9割前後取れているようなので問題ないでしょう。

ただ、ひとつ心配なのは、受験番号のマークを間違えている可能性があるんだよね。午前午後とも解答用紙に受験番号を同じようにマークするのだが、午後試験で受験番号をマークしたときに「あれ?午前てここにマークしたっけ?なんかこういう風にマークした覚えがない…。別の場所にマークしたかも…」とかちょっと感じてしまった。気のせいだと思うが。

選択問題はJAVAを選択した。今の職場じゃ使わない(JavaScriptは使うけど・笑)ので1年以上見てなかったのだけど、あれくらいだったらまだまだ何とかなりますね。むしろ問題解きながら思い出したりしてました(笑)。

次は何勉強しようかな。中国語検定かな。準1級は去年受けて返り討ちにあったので、堅く2級を確保しておくとするかね。準1級はもう一生受からない気がするよ。情報処理試験は次はソフトウェア開発技術者かな。

帰って家で仕事した。持ち帰りの仕事をしないという、自分の中での禁を早々に破ってしまった。

投稿者 Songmu : 22:37

2006年9月22日

中国人のぱくり方に学ぶ(?)

Kingsoft Office. すげーな。Microsoft Officeそのもの。日本人的感覚からすると、恥も外聞もないという感じだが、ここまでやっておいて平然としているKingsoftの根性には恐れ入る。中国人はその辺図太いし、柔軟とも言える。

中国というとぱくりというイメージが強いが、日本も昔はぱくり天国だったのだから余り人のことは言えない。それに、やっぱり「○○人は○○だ」という固定概念も、度が過ぎると聞いていて気持ちの良いものではない。もちろん民族特有の傾向ってのは明らかにあるが。

私が前に住んでいた中国の南の方では「日本人は皆“色鬼”(スケベ)で女を買っている」と軽蔑されていた。それは「皆」ではないにしろ、確かにかなりの多くの人がそのようなことをしていたのは事実である。女を買うまでにはいかないにしても、駐在員のおじさんはかなりの確率で“卡拉OK”(カラオケ兼キャバクラ)に行って店の女の子の胸や太ももを触っていた。そして持ち帰っている人もいた。実際に見たのだから間違いない。

本当に恥ずかしい限りである。私に言わせれば、そういう場所でお金の力を使わないと女の子とまともに接する機会がもてないなんて、生物的オスとして劣っているという生き恥を晒しながら生きているようなものであり、そんな醜態をさらしてまで生きていける人がいるなんて到底信じがたいのだが。また、自分の妻に綺麗でいようという意識を持続させてあげることができないのであれば、やはりオスとして失格である。なので、自分の妻が魅力的じゃなくなったからって、他所の女を買うというのは根本的に間違っている。

ただ、それでも「日本人はほぼ全員スケベだ」と思われてしまうのは、やっぱり不本意極まりない訳ですよ。中国の南の方ではそういう人が目立つし、近くにいるからそう思うのであって、そうじゃない人もたくさんいるわけです。だから、「○○人は○○だ」というのはジョークレベル以上であまり使うべきではない表現である。当たり前のことだけど、中国に行って身を持って知りました。

脱線ついでですが、日本では真面目だった人が中国駐在ではじけてしまうパターンもかなり多いみたいです。真面目一徹だった人が、お金目当ての女の子たちに急にもてだして、それこそ格安(日本円にすると数千円)で女の子と一晩H出来るもんだから勘違いしてしまうみたいです。こういう人はそれまで自分の欲望を抑圧するばかりで上手く開放できていなかったのだろうね。憐れ。

ぱくりがらみでもうひとつ書きますが、中国ではCD-ROM(その他光ディスク類)が売り物であるという意識がすごく低い。これはモラルの問題というより、中国のマーケティングのあり方として、音楽CDをタダ同然でばら撒いてファンを獲得し、ライブで稼ぐという図式があるというのが大きいらしいです。音楽CDをほぼ合法的にコピーできるのが当たり前なので、コピーに対する精神的敷居が低く、ソフトウェアをコピーすることに対する抵抗が少ないようです。

ここまで他人事のように書いていますが、これに絡んで身近で最近驚くことがあったのです。私の職場のWebサイトが同業の中国人が経営する会社にぱくられたのです。それもかなり徹底的に。

私が勤めている業界は中国人の多い業界であり、そこまで大きな業界ではないので、多くの同業者は零細です。なので、これまでも、同業者のしょぼいサイトで画像の一部が無断で流用されているとか言うことはあったのですが、今回は色合いがちょっと異なるだけで、サイトのレイアウト、文言、ソースレベルでとことんぱくられていてびっくりしました。

ウチのサイトは業者がDreamWeaverで作ったCSSとTableレイアウト混じりののいわゆるハイブリッドデザインである。それを一応私が管理している。SEO的にはそれほど優れているわけでもないのだが、一応業界最王手で検索順位的には成功はしているので、ぱくってみたのでしょう。というか自力じゃこれ以上のサイトは作れないと判断したのでしょうな。

浅はかだなぁとか思ったのは、metaタグの並びとか、それに続くアクセス解析用のscriptタグの並びも同じ。そもそも向こうは明らかにUrchin(アクセス解析ソフト)を使っていないのにそのタグを入れてどうするんだと。つまりソースをほぼ丸ごとコピペしており、それがなんなのか全然わかっていないという。

今年出来た新しい会社であり、SEMのみで集客を試みているようだ。Overtureとか、Adwardsにもガンガンお金をばら撒いており、本当に必死である。

恥も外聞もない、手段を選ばないとはまさにこのことである。それでも上手くいってしまったら、非常に困るのだが、それが今の多くの中国の企業のビジネスのやり方でもあるのだよね。

投稿者 Songmu : 23:55

2006年8月26日

Webと中国語対応

一昨日判明したのだが、IE(Sleipnir)とMovableType上で中国語を使うと、中国語特有の文字が「・」と表示され、上手く表示されなくて困る。IEのエンジンは、ソース内で「lang="ja"」を指定すると、日本語以外の完全に表示をしてくれなくなってしまう。実装上は正しいのかもしれないが、融通が利かなくて困る。Validではなくなるが、mt各種設定ファイルCGIの<html lang="ja">を<html>として、lang="ja"を削ることが出来れば、一応解決は可能だと思う。どうやるのかはわからんが。

サイトのコンテンツ上は、中国語部分を<span lang="zh-cn">でくくってやれば、解決可能で、それが正しい表記法でもある。一昨日のエントリーもそうやって表記をしている。

まあ、どうせ、これを書くのはブラウザ上で直接なんて恐ろしいことはせず、エディタで下書きしてるから、別に良いのだが。それでも困ったら、FireFoxで見ればよいのだし。Operaでも最新の9.01は大丈夫なようだ。ちょっと前のOperaは中国語の表示自体に問題が出ることがあった。

中国語というか、多言語の文字コードにかんして、そこそこ出来るプログラマーでも案外知識が少なかったりして、びっくりすることもしばしばなのだが、確かに普通の人はあんま中国語と日本語の同時表記とか考えないよな。WindowXPでさえ日本語OSだとシステム既定の文字コードがShift_JISってのがガン。多くの人がそのままShift_JISでプログラムを作ってしまうので、中国語を使おうとするといろいろ難点が出るのだ。話はちょっと違うが、携帯電話もいつまでたっても、Shift_JISしか表示してくれないしね。

愛用していたSleipnir Ver. 1.66もUnicode非対応だったので、中国語のサイトを見たときのタイトル部分や、検索ボックスに中国語を打ち込んだときに文字化けを生じていた。2.xxはUnicodeで書かれているので、そういった点が解消されて非常にありがたい。

Vistaはどうなるのであろうか。Shift_JISを使い続けるのだったらもう見限りたいね。今やほとんどのLinuxディストリビューションだってEUCじゃなくてUTF-8を採用しているわけですから。ただVistaはUTF-8じゃなくてUTF-16にするってことはありえるかもしれない。

投稿者 Songmu : 03:17

2006年8月16日

マイミクが少ないのが自慢です

冗談半分、本気半分、タイトルのようにのたまっているが、別にマイミクのお誘いをかけられて断ったこともないし、今後も断ることはないでしょう。自分で探したり誘うことが無いだけで。

Mixiのぬる~い付き合いをハタから生暖かく見ている分には愉快なのだが、別に今のところ積極的にかかわるつもりはない。知り合い同士が連絡を取り合うツールとしては有効だとは思うが。

2chのWeb制作板でmixiのID番号順が早いだの遅いだのくだらない言い争いになっていたが、私のIDは60万台なのでそれなりに早いといえるのだろうか。

てことで、マイミクシィへの追加リクエストを初めて出してみた。

投稿者 Songmu : 03:24

2006年8月 8日

ちょっとデザインを気にしだしたりして

いろいろいじるのがちょっと面白くなってきて、参考にしようとデザイン的によく出来ているサイトを見てまわったりしている。MovableTypeの標準CSSはかなりいけてなくて、適当にいじっていたが、やはり根本的に一から作り変えようかと検討中。「#right」とか「#center」とか、やっぱあり得ないよな。

一昨年の足柄でのロードレースの写真をまた性懲りもなくサイト内に使ってみた。この写真は構図的にもなかなかよく取れていて、撮ってくれた恋人には感謝なのだが、それがこの写真を使っている理由じゃない。大きいのは、この写真の頃が人生で一番くらいに速かったってことなのだ。それも下手をすればもうこの人生において2度とあの頃の速さには戻れないかもしれないのだ。これは焦るよ。

バルセロナオリンピック自転車ロードレース代表の藤田晃三選手が「過去の自分を目標にしている自分に気がついて引退を決意した」とどこかで書いていたが、とりあえず今の自分は過去の自分が目標なのである、情けないことに。ひとまずあのレベルまで行かないと、それより上が見えないよ。あの頃の自分にしたってそんなべらぼーに速かった訳じゃないってのが悲しいね。宮崎君とかと比べたら明らかに遅かったわけだし。

つまり、この写真は自分の目標を明確にするためのものである。

投稿者 Songmu : 03:51

2006年8月 7日

迷走中

横浜高校が大阪桐蔭に負けた。注目された大阪桐蔭の中田選手は、第2打席の打球のスピードにも驚いたが、8回、ホームランが望まれている場面できっちりホームランを打つところにスター性を感じさせた。去年から1年生にして5番を打っていたが(しかも4番はあの平田選手だ!)、大阪桐蔭はなんだか怪物御用達の高校になっているね。

サイトいじってた。見てわかる通り、いろいろ試して遊んでいるのだが、迷走中。なんか今、Amazonのアソシエイトがバグっててアソシエイトリンクに変なカートが表示されて困る。しかも、この表示が非常にダサいので萎える。2chを見てみると、この不具合はやはり自分だけではないらしい。アソシエイトではお任せリンクを作ってみた。表示されるものが自分の読書の参考になれば面白いなと思ったので。

本日放映のP League。宮城選手がスペアを外しまくってまた負けた。このままでは剛球のノーコンボウラーという非常にわかりやすいキャラとして認知されかねない。アマチュアでの戦跡を見る限り、本当はそんなはずはないのだが。

投稿者 Songmu : 02:09

2006年8月 4日

背景画像のハック(?)

背景画像だが、左右、上下、上下左右に反転させて、右、下、右下に配置し、1枚の画像にくっつけた。そうすると、画像と画像の境目がそれほど不自然ではなくなるね。この写真の場合上下の境目はちょっと厳しいか。

これはあらゆる模様に通じるものがあって、背景画像を作成する際にも応用が利く。今更気がついたが、多分Webデザインをやる人とかにとっては当たり前のことなのだろう。こうした細かいTipsを積み上げていかなくては。

というか、こういう背景画像の置き方をCSSで指定できるようにならんもんかね。背景画像のファイルサイズが増えてもったいない。

background-repeat: reverse-repeat;

とか。

投稿者 Songmu : 00:46

2006年7月25日

Gizmoはスゲェ

何か書こうと思っていたら、Gizmoをインストールして遊んでいたら、時間が過ぎてしまったので、今日は諦めた。VoIPソフトだが、固定電話で完全無料でかけられるようになったのがスゲェ。録音機能も標準でついているのがびっくり。音質はSkypeよりかは悪い気がするが、気のせいかも。

仕事柄、こういった技術には敏感にならざるを得ないのが職業病。特に通信関係はね。パソコン使ってマルチメディア!(ワラ)、とかあほらしくてそういったことには全く興味なかったのだが、そうもいってられないようだ。動画、音楽配信とかどうでも良かったんだけどさ、職場がそういうことをやるということになると、白羽の矢が立つ(?)のは決まって、私とシステム関係の上司一人の合計2人になるわけですよ。

なんか最近コンピュータ関係の技術書やら、読み物やらばっか読んでいたので、趣向を変えて、久しぶりに小説を読んでみることにした。邪魅の雫までは小説は封印かと思っていたが、禁を破ることにした。

投稿者 Songmu : 03:09

2006年7月23日

おっかなびっくりアップグレード 3.1x→3.3

昨日、長いエントリーを作成してしまったせいか、サイトの再構築に少し不具合が出た。最初に適当にMovableTypeをインストールしたときに、データベースにとりあえずBerkeley DBを選んでしまったのだが、それが原因かもしれない。MySQLを使うかねぇ。

で、とりあえず、MovableType自体をアップグレードしてみることにした。そうしないと、Berkeley DBからMySQLへの移行もめんどくさそうだし。

3.171-jaから3.31-jaにダイレクトにアップグレードした。これまで使用していたのがバージョン3.171-jaなのだが、3.2xから3.3xへのアップグレードをレポートしたサイトは多数あれど、3.1xから3.3xにダイレクトにアップグレードしたことを詳しく解説したサイトがちょっと見、みつからなくておっかなびっくりのアップグレードになった。

一応、本家のマニュアルに3.1xからのアップグレードについて記載があったので、確認しながらこわごわ再構築。

FTPでサーバーに接続し既存の構成ファイルをすべて消去し、新しいバージョンのファイルに入れ替え、それに加えて、既存のmt.cfgという名前のファイルをmt-config.cgiという名前に変更してアップし、cgiファイルのパーミッション書き換えてから、管理画面にアクセスすれば自動的にアップグレードを開始してくれる。不安だったが無事終了した。

mt.cfgをmt-config.cgiと書き換える以外は、3.2x→3.3xと手順は同じであるようだ。

簡単といえば簡単だが、ファイルをすべて入れ替えなくてはいけないのが時間がかかってめんどいね。ま、そのうちワンクリックでアップグレードとかになるのだろうなぁ。

アップグレードの確認のために、一個エントリーを投稿した。無事投稿された。良かった。

肝心のMySQLの導入は先延ばし。

投稿者 Songmu : 23:15

深海魚フィルタ

昨日、Becky!のSpamフィルタ、BkAspilは余り良くないとここに書いたが、本日タイムリーにBecky!用の別のSpamベイジリアンフィルタプラグインがあることが判明。しかも今月できたてほやほやらの新しいプラグインらしい。窓の杜のニュースに載っていたのだが、なんだかYahoo!のニュースにも取り上げられていてちょっとびっくり。

早速その、深海魚フィルタを使ってみることにした。使いはじめなので、まだ精度は不明。

どうでもいいが、サポートが

  1. mixiの「Becky!愛好者」コミュニティに入っておりますので、そちらをご利用ください。
  2. bill-gates@mbr.nifty.comまでご連絡ください。

とかなっていて、ちょっと萎え。

投稿者 Songmu : 23:04

Spamの応酬

NotesにSpamが鬼のように来る。インターネット上に公開しているアドレスをNotesのアドレスに転送かけているもんだから、そこにくるSpamがすべて流れてくる。

その外部に公開しているメールアドレスは、申し込みフォームから流れてくるメールを除くと、9割以上Spamなもんだから、大いに困る。NotesはSpamのフィルタはおろか、メールの振り分けすら出来ないから、その点は勘弁して欲しい。

Spamフィルタは、もはやベイリジアンフィルタが業界標準となっているようだが、一回使ってみると、確かになかなか快適である。いくつか搭載メーラーを使ってみたがちょっとその比較をしてみたい。

Mozila Thunderbird

最近飛ぶ鳥を落とす勢いで、普及が進んでいるフリーメーラー。何せ天下のMozilaプロジェクトなのである。

こいつは標準でSpamフィルタを備えているのだが、そのフィルタ能力はすげえ。勤務先でNotes以外のPOPメールを受信するので使い始めたのだが、1週間ほど学習させたら誤検知は全くなくなった。2週間したら、Spamの見逃しもほぼなくなった。Spam学習もワンクリックですばやく迷惑メール指定ができるのが優れもの。メールを受信すると、ズババっと迷惑メールマークをつけて、ゴミ箱に一気に放り込んでくれるのはなかなか爽快。何せ職場のPOPメールは殆どSpamなもんだから。

メーラーとしての能力を問うと、動作がもっさりしているのが気になるところ。デザイン的にも妙に小奇麗で丸みを帯びていて、色彩が薄いのも個人的には少し気に食わない。なので自宅のメインメーラーにはなりそこねている。

Sylpheed + bsfilter

Sylpheedは日本発祥の誇るべきフリーメーラー。一時Vine Linuxを使って遊んでいた際、標準メーラーとして搭載されており、割と使いやすかった覚えがあった。それで、去年Windowsにも移植された際に使ってみたのが使い始め。現在もたまに自宅から職場のPOPメールを受信する際に使用している。

bsfilterと連携をとると、Spamフィルタ機能を実装できる。Sylpheedに関してはドキュメントが少ないので、設定には少し苦労した。Spam自体の学習はワンクリックで指定できる点はThunderbirdと同じく簡単。

肝心のSpamフィルタ能力は概ね良好。ただし、Thunderbirdにはかなわない。しばらく学習させるとSpamを取り逃がすことは少なくなるのだが、ごく稀に誤検知があり、普通のメールをゴミ箱に投げ込まれていることがある。なので、Spamを一斉消去する際はざっと一覧に一度目を通してから消去する手順を踏まざるを得ない。

デザイン的にもシンプルですっきりしているので、個人的には好きなメーラーではある。ただ、まだ煮詰めが甘い部分があって、時々突然マウス操作を認識しなくなったりなどの誤動作も起こす。メニューや設定画面がやはりLinuxライクなので、慣れないと苦労するかもしれない。

それに、私にとっては致命的な弱点がある。中国語を上手く表示できないのだ。表示フォントをMS UI Gothicに指定しても中国語特有の漢字を表示してくれない。文字コードごとに細かいフォントの指定が出来ないのも×。中国語のメールを頻繁に(嘘)やり取りする自分にとっては大いなる問題。

なので、特に多言語環境に関してなど、まだまだ改善の余地はあるのだが、現在も鋭意開発中なので、今後に大いに期待している。

Becky! + BkASPil

大学時代からずっと個人メールにはBecky!を使っている。かなりメジャーなシェアウェア。通ってた大学がライセンスを取得しており、無償で使うことが出来た。

BkASPilというBecky!用のプラグインを使用すれば、ベイジリアンフィルタを使用可能になる。

ただねー、このフィルタは正直いまいち使えない。誤検知がないのはありがたいのだが、Spamは半分強くらいしか拾ってくれない。一度Spam指定したのとほとんど(全く?)同じメールでないとSpamと検出してくれない模様。Spamの指定も右クリックから行わないといけないし、時間も数秒かかるのが難点。

よく調べてみると、閾値などの設定なども出来るようなのだが、そういった設定を施さなくても標準状態でもう少し使えるレベルであって欲しいものである。

ずっと使ってきた慣れもあるのだが、これをメインで使っている。大量のメールにもかかわらず動作が軽快なのがすばらしい。過去受信したプライベートのメールはすべてこのメールボックスに入っている。また、スペースキー連打で読み飛ばしがなにるのが何気にポイント。今回紹介したほかの2つのメールはそれが快適に出来ない。Thunderbirdなんかスペースキーを連打すると勝手に次のメールに移ったりするし。残念なのはSpamフィルタの性能。

Gmail

かなりすぐれたSpamフィルタ能力を誇るらしいのだが、アドレスを一部の人にしか公開しておらず、残念ながら(?)まだSpamを受信したことがないので分からない。Webメールに革命をもたらしたインターフェースはもちろん秀逸。


以上、スパムフィルタの比較だったが、同じ単純な理屈(ベイズの定理)のはずなのだが、フィルタ能力に差があるのはなんだか不思議だ。

実はベイズの定理は、学生時代に離散数学をわりとしっかりと齧っていたこともあり、ちょっと思い入れのある定理である。もうすっかり忘れたけどね。クラスでは一番優秀だった自信があるのだが、それでもそんなものなのですね、学生の勉強なんて。

離散数学のクラスからグラフ理論のゼミに行ったものの、しばらくしたらそこの先生が他の大学に移ってしまい路頭に迷ってしまった、ってのはまた別の話。

投稿者 Songmu : 04:13

2006年7月18日

サイトいじり

とりあえず、ほったらかしっ放しだったサイトの体裁を簡単に整えてみた。体調悪いわ、雨だわで、外出、運動する気にもなれず、気兼ねなくサイトいじりに没頭できた。寝たり本読んでたりしてたので、実質の作業時間はほんの数時間だが。しかし、なんだかんだで苦労した。

DOCTYPE が XHTML 1.0なもんだから、安易に「XML宣言でも入れるべ」とか思ったのが大間違い。いきなりIEでのレイアウトが崩れてショックを受けました。調べたらIEはDOCTYPE宣言以前になんらかの記述があると、レンダリングが互換モードに切り替わる致命的なバグがあるらしい。MovableTypeの初期テンプレートで、文法的にinvalidにも関わらず、XML宣言がなされてない原因がわかったよ。何言っているか分からない人もいるかもしれないが、つまり、IEは糞ってことですよ。

勤務先のWebサイトはHTML 4.01 Transitional のURL付きで管理、運営しているもんだから、恥ずかしながら、そんなことは露知らず。CSSハックを施すなどの対処方法はあるようだが、めんどくさい(=それだけの技術がない)ので、XML宣言をはずしたままにすると言う、一番乱暴な手にでた。まあ、文字コードがUTF-8だから別に問題ないっしょ。

まあ、あとのデザインはこんな具合です。この程度ですよ。閲覧者の画面解像度が高いと、背景画像の出方がおかしくなるが、まあ気にしません。しかし、今日作業していても感じたが、Webサイト管理者としての自分の課題、

  • デザイン力の強化
  • コンテンツ制作スピードの向上

以上2点を痛感したね。デザインセンスとなるともうどうしようもないから、オーソドックスなデザインパターンをある程度知る必要があるね。配置に関しては少しは本を読んだから、今後は配色やらフォント関係の学習が必要かな。

コンテンツ制作スピードに関しては、手打ちのみの現状を打破しなくてはならない。なんらかのオーサリングソフトの使い方、簡単なテキスト整形スクリプトの作成などを学ばなくては。

アーカイブページにも少し手を加えた。昔の私のサイトの体裁にそっくりにしてしまったが、むしろこれをメインにしても良いような気も(?)

投稿者 Songmu : 00:12

2006年5月31日

すげぇすげぇの今日この頃

なんか○○はスゲェ、ってテーマで毎日何かしら書けそうな気がしてきた。スゲェスゲェって言いまくっているのは馬鹿みたいなのだが、すごいモノはすごいと言える事は大事だよな。

で、Googleはスゲェ(笑) ってよく言われるが、何がすごいのか良くわからなかったのですよ。検索がすごいのは良くわかっていたし、いち早く使っていた部類だとは思うしね。

そこで、Gmailですよ。もう、このあまりの使い勝手の快適さに愕然として、Googleのすごさがわかったね。それ以降はもう、馬鹿みたいにGoogleはスゲェと思う今日この頃なのです。ありがちな話だとは思うが、「ああこれがWeb2.0ってやつなのか」とGmailで実感しました。

Ajaxがナイスなのは、これもよく言われるが、「枯れた技術なのに最先端」って構造が非常に萌えるってことですかね。俺もJavascript馬鹿にしてたもんなぁ。「ハッカーと画家」の巻末用語集に、

残念ながら、Webサイトで安っぽいトリックを実現するのに多用されたため不当に低く評価されている。

なんて書いてあって、まさしくそのとおり。

投稿者 Songmu : 02:15

2006年5月29日

HTML+CSSはスゲェ

今更何言ってんだって感じの題名ですが、ここ1年で一番の収穫は、HTML+CSSをしっかり理解したことかな。(もちろん1年かけて理解したというわけではない)

ホント、他人のサイトのソースをのぞき見ながらサイトを構築する危険性が分かったよ。一度体系的にしっかり学ぶってことが必要なんだな、と思った。htmlを殆どテキストエディタで書いてたくせに、ブロック要素とインライン要素すら知らなかったもんね。

しかし、HTML+CSSはスゲェ。もう、Webページだけでなく、あらゆるドキュメントをこれで作りたくなるくらい。Wordなんていらねぇよ、といいたいところだ。あとは、ドキュメント製作用の優れたHTML+CSSエディタとブラウザがあればいうこと無しなのだが。

そのうちその辺もしっかりしてくるでしょうけど。あらゆる形式がXML形式になろうとしているみたいだし。ああ、なんかすげーありきたりな内容になってしまった。

投稿者 Songmu : 01:03

2005年10月13日

中速タイパー

 一日中家にいたわけです。良い機会なのでメールとブラウザのお気に入りの整理を敢行。基本的にいらんもんを消しまくった。しかし、本の整理と一緒で、つい手を止めて読み耽ってしまうこともしばしば。

 話は変わるが、最近文字がものすごく汚いね。えてして長い文章を書くときなんかは、最初は文字をきれいに書いていても、だんだん汚くなるものだ。ただ、その頻度が酷い。

 これは、ペンで字を書く機会が減ったからというのとともに、キーボードに慣れすぎてしまったんだろうな。

 何せ、俺様のしょぼくれたタイプでも1分間に400タイプは堅い。そうなると、手書きと、キーボードで入力速度に大きく開きが出てきてしまうわけだ。つまり手書きはまどろっこしい。

 ちなみに携帯メールも面倒くさいね。今の英語の世界記録でも200文字強/分みたいだ。つまり俺様のタイプにもかなわない有様なのだ。

投稿者 Songmu : 21:38

2005年10月10日

PC好きじゃないはずの私

 数日高知に行ってました。

 話は飛ぶが、最近PC関係にお金を使いすぎなのだ。主に書籍だが。学生時代は、ほとんどWebで適当に調べて、レポートを書いたりしていたが、やはり体系だって学ぶとなると書物が良い。その点は古いタイプの人間だと思う。それに行き帰りの電車内で読むことが多いし。

 そもそも、勘違いされては困るのだが、よくよく考えてみると俺は別にPC関係が好きなわけではないのだ。自分自身を「アナログだ」なんてそれこそデジタルな発言をするつもりもないが、使い始めたのは遅かったし、必要だから使っているに過ぎないのだから。

 そういえば、コンピュータについて知っているのと、ソフトウェアを使いこなす技術は、また別の話だよな。というのも、最近、Officeを会社で使うわけですよ。当たり前ですが。

 しかし、実は俺はOfficeを使ったことがほとんどなかったのだ。大学時代レポートはWordなんかじゃなくLaTeXで書いてましたから。そっちのほうが数式がきれいに出たし。中国語のレポートはWordで書いたけど。

 しかし、PCが扱える→Officeが使えるって考えてる人が多くて難儀する。まあ最低限はOfficeも使えるが。そもそも、「PCが扱える」って言葉も怪しい言葉だな。

 「PCを扱える」か否かの線引きをするとしたら、エディタを日常的に使うか否かによってそこそこ判別できる気がする。世の中、エディタを使わない人はすげー多いらしいのな。エディタなしで、PCを使えるってのは、俺にしてみればむしろミラクルに感じてしまうが。ほかにも"C:\Windows\..."とか"/home/usr/.."とか言ってもぜんぜん分からない人とかがいるのも結構信じがたいものがある。

 まあ、そういったことを知らなくてもPCを扱えるようになるってのはすばらしいことだと思うが、そういったことをわからずにPCを使うには、まだまだPCは不親切だといわざるを得ないね。

投稿者 Songmu : 23:58