ブログが続かないわけ

この日記のはてなブックマーク数
Webエンジニアが思うこと by junichiro on Facebook

[雑記]Gmail のアカウント部分のドット(.)はどうでもよかった

このエントリーを含むはてなブックマーク hateb

結論

例えば、this.is.a.pen@gmail.com というアドレスがあったとします。これは下記のアドレスのどこに出しても、ちゃんと届きます。

thisisapen@gmail.com
this.isa.pen@gmail.com
this..is..a..pen@gmail.com
t.h.i.s.i.s.a.p.e.n@gmail.com

アカウント部分ドット(.) はどうでもよいようです。

テストアカウントに

これを利用すると、別メールアドレスが簡単に作れますので、テストアカウントとか、複数のアカウントを用意したいときとかに便利です。Gmail で別メールアドレス(エイリアス)を作る方法は「+」を使う方法が良く知られていると思います。例えば、先ほどの例のアカウントですと下記のようなアドレスもエイリアスとして有効になり、this.is.a.pen@gmail.com に届きます。

this.is.a.pen+test@gmail.com
this.is.a.pen+sub@gmail.com
this.is.a.pen+for.you@gmail.com

ところが稀にこの「+」をつかったメールアドレスを許可していないサイトもあり、そういうサイトでは複数のアカウントを用意するのが面倒でした。そこで、この(.) をつかったエイリアスの方法を使えば、簡単に別のアカウントを用意できます。

= の位置がそろっているコードをそうじゃないコードにする

このエントリーを含むはてなブックマーク hateb

僕は、下記のようにコードを揃えるのが好きだ。無意識のうちにそろえてしまうこともあるし、Perl ならperltidy とかで揃えている。今やっているお仕事でも同じように開発を行っていた。先日いくつかのコードを先方にレビューして頂いたのだが、先方のコーディング規約によると、こうやって揃えるのは規約違反だということだった。事前にコーディング規約を頂いているので、完全に僕のミスだ。さて、これを直さないといけないんだが、コードをそろえるためのツール(perltidy とか)はあっても、そろっているものをそうじゃなくするツールがすぐには見つからなかった。特に今回は、PHP だったのでperltidy も使えないし、かといって手で全部作業するのはモチベーション的にもキツいし、ミスも多そうだ。

そこで、先日紹介した「Lisp はわからないけどEmacs で選択範囲に対してごにょごにょしたい」と同じ方法で、正規表現で下記のコードを規約に従ったコードにするためのコードを書いた。

そろっているコード(いまのお仕事では規約違反)

$row->topic_category_id = $topic_category_id;
$row->caption           = $this->getData()->caption;
$row->description       = $this->getData()->description;
$row->user_id           = $user_id;
$row->uri_thumbnail     = $uri_thumbnail_db;

$data = array( 'modified' => date('Y/m/d'), 'modified_by' => $this->user_id, 'status' => $this->status; );

$this->view->options = array(E3::Registry::getConfig()->label->selectOption);

規約に従ったコード
$row->topic_category_id = $topic_category_id;
$row->caption = $this->getData()->caption;
$row->description = $this->getData()->description;
$row->user_id = $user_id;
$row->uri_thumbnail = $uri_thumbnail_db;

$data = array( 'modified' => date('Y/m/d'), 'modified_by' => $this->user_id, 'status' => $this->status );

$this->view->options = array(E3::Registry::getConfig()->label->selectOption);

ちょっと書いてみると意外と一筋縄では行かなくて、単に=の両サイドだけ置換するような書き方では、最後の行(これはこのままで良い)まで置換されてしまう。なんとなく悔しかったので、_33rpm の力を借りてそれなりに奇麗なものを書いた。

gist: 175485 - GitHub

クライアントの要望を満たすと、セキュリティ的に問題がある。どうしたらいい?

このエントリーを含むはてなブックマーク hateb
受託開発で困る部分のひとつ。

1. ログインに失敗したときのメッセージ

簡単な例を出してみよう。ID/Password を入力させるようなログイン画面で認証に失敗した場合、「ID またはPassword が正しくありません。」というようなメッセージを出すのが通例だ。当然システム側では、ID が間違っているのか、Password が間違っているのか区別することはできるのだが、親切に「ID が正しくありません。」とか「Password が正しくありません。」とかというようなメッセージは出さない方がいいとされている。これは親切なメッセージを出すと、悪意の第3者になりすましログインのヒントを与えてしまうことになるからだ。適当なID/Password でログインを試みて、親切にエラーメッセージが出し分けされると、その適当に入れたID が存在するID かどうかを判定できてしまう。ひとたびID が判定できれば、あとはPassword の方を総当たりなどでチェックするだけでログインできてしまうということになる。実際にはID がわかったところで、Password 総当たりでログインするというのはそんなに簡単なことではないのだが、ユーザーが比較的簡単なパスワードを設定している場合は、簡単にログインされてしまうということももちろんある。

こういう部分は、どういうメッセージにしてほしいとか、クライアントから細かく指示されないことも多く、その場合こちらから提案することになる。業界の通例で、とくに上記の理由などを意識せずに、正しいエラーメッセージを提案している人も多いと思う。しかしそういうケースだと、ひとたびクライアントから、「ユーザーにわかりやすいようにエラーメッセージを出し分けて」といわれたら、すんなりその要求をのんでしまうのではないだろうか。

慶應オンラインは、このセキュリティ的には正しくない方のメッセージで実装されている。管理者に指摘したところ、ユーザーの利便性の方が重要とのことだった。ユーザーの利便性とセキュリティの堅牢さは、往々にしてトレードオフの関係にあるので、脆弱にすることのリスクと、それによって得られる利便性を比較して、利便性の方が高ければ、そちらをとるというのもありなのだろうか。ただ、僕は慶應オンラインのユーザーとして、このシステムを使うのはとても嫌だ。

【参考】
慶應オンライン

2. パスワードリマインダーに失敗したときのメッセージ

上記と似たような例として、パスワードリマインダーのエラーメッセージの問題がある。簡単なパスワードリマインダーを例に考えてみよう。ユーザーが会員登録時に入力したメールアドレスを入力させて、そのアドレス宛に初期化したパスワードを送るという方法だ。このときに、メールアドレスを間違えて入力すると、「そのメールアドレスは登録されていません」というエラーメッセージが出るサイトが多い。よく考えれば、これも当然、そのメールアドレスがそのサイト内に登録されているかを判別できてしまう。上記のログイン認証の例では、曖昧なメッセージをだして存在チェックができないようにしているサイトでも、パスワードリマインダーでは簡単にこういうことをやってしまっている。パスワードリマインダーでのエラーメッセージは、僕は下記のメッセージで提案することが多い。

メールアドレスが正しくても間違っていても同じメッセージを出さないといけないので、こんな感じになる。
ご入力頂きましたメールアドレス宛に、初期化したパスワードをお送りいたしました。
ご入力頂きましたメールアドレスと、ご登録頂いておりますメールアドレスが異なる場合は、初期化メールが送信されません。
ただ、これはログイン認証の失敗よりユーザービリティに与える影響は大きいように思う。実際、この提案はクライアントに嫌な顔をされることが多く、たいていはメールアドレスの存在チェックができてしまうようなメッセージに落ち着く。ただし、当然そのリスクはクライアントに伝えたうえでだ。

3. SSL のかかっているフォームの内容をメールで飛ばす

上記2つの例はまだかわいいもので、クライアントがトレードオフのどちらをとったのか、そのポリシーが、ユーザーにも見える。ところが、SSL のかかっているフォームの内容をメールで飛ばすとなると、話は変わってくる。フォームにSSL をかける場合、ユーザーが入力したデータも暗号化された経路でクライアントの手に届かないと意味が無い。簡単なのはCSV ファイルなどに蓄積し、SCP(FTP はダメ)などでそれをダウンロードしていただく方法だ。ただ、クライアントのリテラシー次第では、SCP によるダウンロードは敷居が高いこともある。その場合、簡単なダウンロードの仕組みを提供してあげる必要がある。もちろんその部分の開発コストもかかる。そうなると、クライアントは、メールで情報を飛ばしてくれる方が、開発コストがおさえられるうえに、自分たちも楽できるから、そうしてくれと言い出すことが多い。リスクを説明しても、「実際、経路上抜かれることなんてないでしょ?」とか、「見た目にはユーザーにはわからないんだよね?」とか、平気で言ってくる。

開発会社がクライアント企業のポリシーに口を出すのも筋が違うので、泣く泣くこういう開発を請け負うこともあるが、果たして正しい対応とはどういう対応なんだろうか。

また、セキュリティに配慮した高い見積もりが、セキュリティに配慮していない安い見積もりに負けるという構図は、どうすればひっくり返るのか。

Lisp はわからないけどEmacs で選択範囲に対してごにょごにょしたい

このエントリーを含むはてなブックマーク hateb
Emacs を使っていると、選択範囲に対してなにか処理したいということはよくある。それなのに、Lisp がわからないからということで、あきらめてしまってはいないだろうか。Emacs でいろいろなことをやるにはLisp は必須だけど、「選択範囲に対して何か処理を施す」というだけであれば、Lisp はほとんど知らなくても実現できてしまう。

要は、選択範囲を引数として自作のスクリプトに渡して、それの戻り値を受取ることができればいいわけだ。選択範囲をスクリプトに渡すという部分はLisp で書かなければいけないんだけど、そこはここで示すテンプレートをコピーして使うだけで問題ない。

それでは、例として、選択範囲の小文字を全て大文字に変換するというものを作ってみよう。
(これ自体はEmacs の標準のコマンドでできるけど、ここは例としてこれを作る)

まず、雛形となるLisp のテンプレート

my-func.el
(defun [コマンド名] ()
"[コマンドの概要]"
(interactive)
(save-excursion
(shell-command-on-region (point) (mark) "[処理したい内容を書いたスクリプトのパス]" nil t)))
これで準備は整った。編集しなければいけないのは3カ所だけ
  • [コマンド名]
  • [コマンドの概要]
  • [処理したい内容を書いたスクリプトのパス]

例えば、今回作成する大文字小文字変換の関数をこう定義してみることにしよう。
  • [コマンド名] = my-uc
  • [コマンドの概要] = Returns an uppercased version
  • [処理したい内容を書いたスクリプトのパス] = /Users/junichiro/bin/my_uc.pl

そうすると、my-func.el はこうなる。
(defun my-uc ()
"Returns an uppercased version"
(interactive)
(save-excursion
(shell-command-on-region (point) (mark) "/Users/junichiro/bin/my_uc.pl" nil t)))

さて、実際に変換の処理を行うスクリプトはどうかけばいいんだろう。
ポイントはどうやって選択範囲が渡されるかということと、どうやってEmacs に値を返すかの2点だけだ。
結論から言うと、値は標準入力として渡され、標準出力すれば返すことができる。
それさえわかればあとはなんてことはない。
my_uc.pl
#!/usr/bin/perl

use strict;
use warnings;

my $text;
{
local $/;
$text = <>;
}
print uc $text;
perl の例で恐縮だが、$text に標準入力の値を渡している(改行も含めて)。
※uc は引数で与えられた値をすべて大文字に変換するperl の関数。

これで、my_uc.pl に実行権限を与えて、さらにmy-func.el をLisp のパスが通ったところに置けばmy-uc という関数が使えるようになる。Emacs の中で適当に範囲を選択して、M-x my-uc と実行してやれば、選択範囲に含まれる小文字が全部大文字になるのがわかるだろう。

やり方はここまでだが、具体例として僕が使っている便利な「選択範囲処理系スクリプト」を2つほど紹介しよう。
ひとつは、選択範囲のURL をそのサイトのタイトル付きで<a href="[URL]">[title]</a>という形式に変換してくれるもの。
もうひとつは、選択範囲をMarkdown 記法と解釈して、HTML に変換してくれるもの。

ちなみに、my-func にはいくつでも関数の定義が書けるので、こんな感じになる。
; link a_href for blog func;
(defun create-link-region ()
"Run create link on the current region."
(interactive)
(save-excursion
(shell-command-on-region (point) (mark) "/Users/junichiro/bin/create_link.pl" nil t)))

; text markdown for blog func;
(defun markdown-region ()
"Run markdown format on the current region."
(interactive)
(save-excursion
(shell-command-on-region (point) (mark) "/Users/junichiro/bin//markdown.pl" nil t)))
my-func の方は雛形を少し改変するだけなので、簡単だ。
create_link.pl
#!/usr/bin/perl

use strict;
use warnings;
use URI::Title qw(title);
binmode(STDOUT, ":utf8");

my $href = <>;
chomp($href);
my $title = title($href) || '';
print '<a href="', $href, '">', $title, '</a>';
これは1行しか取り込む必要がないので、標準入力の取込み方が先ほどの例よりシンプルになっている。
(my $href = <>; の部分)

これをたとえば、「http://en.yummy.stripper.jp」を選択して実行(M-x create-link-region)すると、
「<a href="http://en.yummy.stripper.jp">ブログが続かないわけ</a>」となる。

markdown.pl
#!/usr/bin/perl

use strict;
use warnings;
use Text::Markdown 'markdown';

my $text;
{
local $/;
$text = <>;
}
my $html = markdown($text);
print $html;
この2つの例で見ればわかるように、CPAN モジュールを活用している。このように、外部スクリプトに処理させることにより、普段自分が使い慣れている言語で書けるとともに、その言語のバックエンドにある膨大なモジュールの力を借りることができるというのも大きい。

Webアプリケーションを開発環境にアップする

このエントリーを含むはてなブックマーク hateb
.svn のうっとおしさに悩まされてる方に朗報です。
(git に移行すれば済む話だけど、まあそれ以外にも便利なこともある方法の紹介だよ)

概要

開発環境に限らす、本番環境に対しても同じなんだけど、みんなソースのアップロードってどうやってるんだろ。いわゆるデプロイと言われる作業だけど、デプロイツールというのはどのくらい使われているんだろう。アップロードする対象のサーバが1台しかなく、デプロイツールをつかうまでもないと言う人はたくさんいると思う。僕自身も、Windows で開発を行っているときは、FFFTP とかWinSCP を使ってソースをサーバにアップロードしていた。.svn ファイルがサーバにあがってしまわないように、細かい設定をしたり、もしくはディレクトリ丸ごとのアップロードはしないように注意しながら作業したりしていた。

Mac に移行してからも同様のことをCyberduck でやっていたんだけど、ただファイルをアップするためだけに他のアプリケーションを立ち上げるというのも面倒で、Cyberduck が立ち上がっていたとしても、対象のファイル群をドラッグ&ドロップでサーバにアップするというのは、とにかく億劫だった。そのため、コマンドラインからSCP などでアップロードすることも少なくなかった。

さて、今日はこれを簡単に行う簡単なTips というか僕なりのやり方を、備忘録も兼ねて書いておこうと思う。普段からCapistranoArcher を使っている方はそれの方がいいと思うけど、いまはまだFTP(SCP) ソフト等でちまちまアップロードしているという人には、このやり方が参考になると思う。

必要なモノ

  • Terminal.App (あるいはそれに準ずるもの)
  • rsync
  • scp(公開鍵認証 でssh アクセスできること)

具体例

ローカルのワークディレクトリ
/Users/junichiro/Work/project/trunk

サーバ側
IPアドレス: 192.168.9.50
公開ディレクトリ: /home/user
※IPアドレスのかわりにドメイン名でも良い

事前に公開鍵認証でssh ログインできるようにしておくこと。
この方法は別途参考書籍等で確認してほしい。

deploy.sh というデプロイ用の簡単なシェルスクリプトをtrunk の下に置く。
(別にtrunk の下に置かなくても良いが、参考までに)

deploy.sh

#!/bin/sh
rsync --exclude-from=/Users/junichiro/Work/project/trunk/.deployignore -ave ssh /Users/junichiro/Work/project/trunk/ user@192.168.9.50:/home/user

これに実行権限を与えておく。
これを実行すると、--exclude-from で指定されているファイルに記述のあるファイルをアップロード対象からはずしてくれる。例えば、.svn などをサーバにアップしないで済むわけだ。

.deployignore の例

.deployignore
deploy.sh
.svn/
docs/
sql/

説明

僕の場合、開発に必要なドキュメントや、create 文等のSQL もバージョン管理下においてあるので、trunk の下にdocs やsql というディレクトリがある。こういうものはサーバへのアップ対象からはずしたいので、こういう記述になっている。環境特有の設定ファイル等があれば、そういうものも.deployignore に列挙しておくと、より幸せになる。

ちなみに、これを実行するたびに全てのファイルがアップされるわけではない。rsync を使っているので、変更が加えられたものだけがアップされ、非常に高速だ。そこも僕が気に入っている点のひとつだ。

ただ、この方法では、deploy.sh をご覧頂けるとわかるようにrsync に--delete オプションをつけていない。そのため、ローカルに存在しなくなったファイルに関して、サーバ側は削除されずに残ったままになる。ファイル名を変更した場合等は、古いファイル名のままサーバにゴミとして残り続けるので、それは手動で削除する必要がある。僕は、必要なファイルが削除されてしまうのが怖いので、--delete オプションをつけていないが、ゴミを手動で削除する方が嫌という方は、--delete のオプションをつけるといいかもしれない。

参考書籍

ロブ フリッケンガー, Rob Flickenger, 山口 晴広, イメージズアンドワーズ ¥ 2,310
初心者からの脱却に
サーバ管理者の初心者用かも
「なるほど」と何度呟いたか・・
使えるネタが満載!
Linuxのプロとプロでない者

ZendFramework勉強会@Tokyo でしゃべってきましたよ

このエントリーを含むはてなブックマーク hateb

思い立ったらZF


僕が話したのは、「思い立ったらZF」という題目で、つまり、もっと気軽にZendFramework を使おうよという内容のもの。最近、CakePHP を使ってみて、なぜCakePHP は人気があってZendFramework は人気がないのか、僕なりにわかった気がしたので、その辺りをまとめつつ、じゃあ、ZendFramework を使う気になるにはどうすればよいかというようなことをまとめてみた。

スライドはこちら。
思い立ったらZF

スライドだけ見てもあまり伝わらない内容なので、その辺はご容赦ください。要約すると、CakePHP のようにある程度規約で縛りをつけて、それにあわせたファイルレイアウトを、いつでもgithub から手に入れられるようにしておけばいいよ!というもの。

そのgithub のURLはこちら。
junichiro's zf-starter at master - GitHub

自分なりの反省

僕の発表を聞いているうちは、「ほぅ」と思う場面もあったかもしれないが、終わってみるとなにも身に残らなかったのではないかという、きわめて時間つぶし的な発表になってしまったこと。

他の発表についても簡単にまとめておく

bayside/ZFではじめる携帯サイト

携帯開発の内容がぎっしり詰まったよい話。
ただ、全てをShift_JIS で書くというのにはとても抵抗感がある。

また、「MySQL で文字化けしてしまうのでは?」という質問に対して、常に「SET NAMES sjis」をつけるようにしているとのことだったが、これもZend_Framework で使う場合少し疑問が残る。会場で質問しようと思ったが、なんだかいじわるな質問になりそうだったので自重した。

なぜ、ZendFramework でこれが問題になるかということだが、それには少し確認が必要だ。ZF でどの場所でDBへの接続を行っているか?これはみなさん悩むところだが、おそらくイニシャライザか、アクションヘルパーでやっているだろう。そうすると、DB接続が不要なController やAction でも無駄にDB接続してしまうことになる。パフォーマンスが問題にならなければ、そうそう問題になることはないが、回避策は知っておきたいところだ。ところが、Zend_Db はそこそこできがよく、DBへの接続をどこに書いていようと、ちゃんと遅延評価してくれる。つまり、実際にDBへの接続が必要になったとき、要するに初めてのクエリの発行のタイミングでコネクトを張ってくれる。だから、いろいろなサンプルにあるようにイニシャライザなどでDB接続を行っても、まったく問題ないのだ。

これを踏まえた上で、「SET NAMES sjis」をつけるということを考えたい。おそらく、DBへの接続を行うタイミングでこれを発行しているのだと思う。しかし、ここでいうDBへの接続のタイミングというのは、コード上のことで、実際に接続に行くタイミング(遅延評価された最初のクエリのタイミング)ではないと思う。つまり、イニシャライザにDBへの接続を書いているとしたら、そこに「SET NAMES sjis」を書いているのではなかろうか。こうすると、せっかく本来は遅延評価されるDB接続も、「SET NAMES sjis」というクエリを発行するために、そのタイミングでコネクトを張ることになってしまう。結局、DBを必要としないController やAction でもDBへの接続が行われてしまうことになる。

ちなみに、Perl のDBIC などでは、「SET NAMES sjis」の発行そのものを、遅延評価に含めることができ、最初のクエリ(SELECT文など)が発行されるタイミングで、DB接続と「SET NAMES sjis」の発行を行うことができる。

確かにそう考えると、毎回「SET NAMES sjis」を発行していることが問題なのではなく、その部分を遅延評価することができないZend_Db の問題とも言えるかもしれない。もし、この部分もちゃんと遅延評価できているとしたら、そのやり方を教えて頂きたいと思った次第。

2009-04-04 - Devel::Bayside

twk/はじめてのZend_Form

これもよい話。
Zend_Form を使いこなせると、開発効率は格段にアップする。
というのも、そもそものコード量を減らせるだけではなく、書き方が決まっているので、頭を悩ませる時間も大幅に削減できるからだ。また、Zend のよいところでもあるのだが、Zend_Form ひとつとってみても、使い方がいろいろとある。部分的に使ったり、フル機能を使ったり。その辺りも、順を追って説明してくれていて、とてもためになる。実用的で、僕の発表とはワケが違うと思った。コード中心の解説だったので、この発表の内容を紹介するのは大変かもしれないが、是非、ブログ等での公開を期待したい。

twk @ ふらっとへようこそ | twk @ ふらっと

heavenshell/Phwittrについて

九州からの参加。
ZendFramework で総合的なサービス開発のソースコードが全部読めるのは、Phwittr くらいなので、これは非常に参考になる。ZendFramework の話というよりは、設計の話が多くなっていたが、僕にとってはそれがむしろありがたかった。みなさんも、ZendFramework を使ってなにかサービス開発するときは、Phwittr を参考にするとよいと思う。これが正解というわけではないとも思うが、ひとつの参考としてとても重宝している。コードはcoderepos にあるので、まとめてローカルにおいてあると、いざというとき手元に参考書があるような感じになるので、便利。おすすめ。

Zend Framework 勉強会@Tokyo に行ってきた - Heavens hell

wads/自作のZFコンポーネントなど

Zend_Log にローテーションの機能をつけようという話。
僕の個人的な感想としては、疑問符がつくないようだったが、まわりの反応は上々だったようだ。Zend のsyoshida さんも「proposal にあげてみたら?」というくらい評価していた。

僕が疑問に思った理由を簡単に書いておこう。そもそもの役割分担として、アプリケーションプログラマはログを吐く(もしくはそれを読む)ところまでが作業領分で、吐かれたログがたまるとか、定期的に掃除するとかは、サーバ管理者の作業領分だと思うからだ。wads さんは、ログに関する一切をZendFramework で完結させたいという考えがあったようだが、逆に僕は、ログのローテーションに関する一切はlogrotate で完結させたいと考えている。だから、仮にアプリケーションプログラマがログの定期的な掃除まで担当することになったとしても、僕はlogrotate に管理させる方がよいと思った。

logrotate と比較して、ZendFramework で実装することのメリットを提示してもらえたら、より面白かったと思う。

wadsのblog

noopable/たとえばZend_Cache

僕自身はZend_Cache をある程度使っていたので、そうでもなかったのだが、Zend_Cache をまだあまり使ったことのない方には非常によい発表だったと思う。そもそも、noopable さんはZend に対しての勉強量が多く、話している内容がわかりやすいのが非常によかった。

noopな日々

m-takagi/ZFにまつわる何か

飛行機にまつわる何か
飛行機いいよ。今日は京都からだったから泣く泣く新幹線で来たけど
Zend のマニュアルをみんなで翻訳しようよ!という話。
m-takagi さんが話すと、とても説得力がある。

最後に

ust 配信してくださった、nekoget さんありがとうございます。
会場を手配してくださった、ウノウ株式会社 Unoh Inc./coco1ban さんありがとうございます。

【参考】
events.php.gr.jp - ZendFramework勉強会@Tokyo

MacPorts でgit をインストールするのが大変なわけ

このエントリーを含むはてなブックマーク hateb
ほとんど推測の域を出ないのだが。

git-core が依存しているパッケージにncurses というものがある。何をやるものか詳しく知らないが、git-core +svn をインストールするためにはこのncurses の最新版が必要らしい。

僕のMac はcase sensitive なファイルシステムを採用しているのだが、ncurses の最新版はcase sensitive なファイルシステムでは特定のオプションをつけなければコンパイルできないらしい。

port でこの問題を解決するためにはncursesw を先にインストールすればいいらしい。

しかし、これをインストールするのがまた面倒だ。これを再度インストールするためには、なぜか port upgrade ncursesw でうまくいかないので、一度アンインストールしてから再度インストールしなければならない。ところが、これをアンインストールするためには、これに依存しているものを先にアンインストールしなければならない。

これに依存するものは、そう、もちろんncurses だ。で、このncurses を結局一度アンインストールしなければならないらしいのだが、当然これに依存しているものも先にアンインストールしなければならなくなる。これに依存しているパッケージは多い。w3m とかscreen とか。

これらをすべてアンインストールして、やり直せばいけるのかもしれないが、アンインストールしたが最後、再度インストールするときにうまくいかなくなって、にっちもさっちもいかなくなるのは怖い。

Time Machine を使ってバックアップしながらやるという方法もあるけどどうも気が進まない。

だからgit-svn はあきらめた。

英語が苦痛でない方はこんな駄文を読むより下記を読むといい。

MacPorts が不調になるとCodeRepos に戻れない

このエントリーを含むはてなブックマーク hateb

風が吹けば桶屋が儲かる的な話

CodeRepos を使ってた

svn は.svn がうっとおしいし

ローカルリポジトリが欲しい

svk

git いいよ。ってことでmacport でgit-core(+svn) を入れる

git-svn を使っていろいろやる

git-core をupdate

valiant で+svn を付け忘れる

見事にgit-svn が使えなくなる

再度git-core を入れ直そうと試みる

なぜかport が途中でこけてインストールできない

git 自体は問題ないので、github を使ってみる

なんら問題ない。むしろ快適(←イマココ)

もうgithub でいいや

CodeRepos のgit リポジトリを使おうかと考え始める?

MacPorts の不調について

MacPorts のVersion は1.7
% sudo port upgrade git-core +svn
---> Fetching gperf
---> Attempting to fetch gperf-3.0.4.tar.gz from ftp://ftp.dti.ad.jp/pub/GNU/gperf
---> Verifying checksum(s) for gperf
---> Extracting gperf
---> Configuring gperf
---> Building gperf
---> Staging gperf into destroot
---> Deactivating gperf @3.0.3_0
---> Installing gperf @3.0.4_0
---> Activating gperf @3.0.4_0
---> Cleaning gperf
---> Fetching ncurses
---> Verifying checksum(s) for ncurses
---> Extracting ncurses
---> Configuring ncurses
---> Building ncurses
---> Staging ncurses into destroot
ここで応答がなくなる。
というかファンはまわりっぱなしになるので、頑張っているらしい。
だが、24時間粘ったけどダメだった。

[Mac]Safari4 で1Password を動かす

このエントリーを含むはてなブックマーク hateb
Safari4 がパブリックベータとして公開されたので試してみた。
タブが上にきているので目が慣れるまで大変に感じたが、なんとなく良い物を手に入れた気になった。
あたらしもの好きなだけだろう。

ネット上のいろいろな反応を見ていると、1Password が使えないから... というものがチラホラとあったので、Safari4 で1Password を使う方法を紹介しておく。偉そうに書いてあるけど、やり方は全部Agile Web Solutions のサポートページに書いてある。

Agile Web Solutions Support Forums - View Single Post - Safari 4 Developer Release

1. Safari4 のバージョンを確認する


- Safari4 のメニューからAbout Safari をクリック
- 表示されるSafari4 のバージョンの()内に書いてあるバージョンをメモしておく
- 2009/02/25 時点で僕の場合 5528.16 だった

2. Safari4 を終了する


3. 1Password のパッケージの中にあるSupportedBrowsers.plist を編集する


- アプリケーション > 1Password (ここで右クリック or Ctrl + クリック)
- パッケージの内容を表示
- Contents > Resources > SupportedBrowsers.plist
- ここにあるSupportedBrowsers.plist をダブルクリックで開く
- Root > Safari > MaxBundleVersion
- この値を先ほど調べたSafari のバージョン番号に変更する
- 僕の場合は、5528.1 から 5528.16 に変更した形となった
- これでSafari4 で1Password を使う準備が整った

※ただし、この方法はSafari4 がオフィシャル版になるまでの間、1Password がUpdate される度に毎回行わなければならない。

4. Safari4 のメニューバーをカスタマイズする


- Safari4 を開く
- 上部のメニューから View > Customize Toolbar... を選択する
- 開いた画面の右下に見慣れた1Password のボタンがあるのを確認する
- (1 〜 3 の手順を踏んでいない場合、このボタンが見えない)
- そのボタンをドラッグして、Safari4 のメニュー内の好きな位置にドロップする
- 僕の場合、「進む」ボタンと「+(お気に入りへ追加)」ボタンの間においている

[PHP]Zend_Db で作成したSQLサンプル

このエントリーを含むはてなブックマーク hateb
Zend_Db というかZend_Db_Select でSQL を書かずにクエリーを作成した。Zend_Db は機能が中途半端なところもあるが、ある程度のクエリなら書くことができる。今回は実践例としてjoin、及びjoin 内の副問い合わせを実装する例を、自分用の覚え書きとしてここに記す。

目的のSQL
SELECT
u.user_id,
u.register_name,
u.uniform_no,
u.type_id
FROM
USER_REG_TB u
JOIN
(
SELECT
distinct(user_id)
FROM
ENTRY_TB
WHERE
entry_state_id IN ('1', '2')
) t
ON t.user_id = u.user_id
JOIN
TYPE_TB p
ON p.type_id = u.type_id
WHERE
u.group_id = '1000'
AND u.f_del = 0
ORDER BY
u.type_id, u.user_id

Zend_Db によるコード
$select = $this->select()
->setIntegrityCheck(false)
->from(
array('u' => 'USER_REG_TB'),
array(
'u.user_id',
'u.register_name',
'u.uniform_no',
'u.type_id'
)
)
->join(
$this->select()
->setIntegrityCheck(false)
->from(
array('ENTRY_TB'),
array('distinct(user_id)')
)
->where('entry_state_id IN (?)', array('1', '2')),
't.user_id = u.user_id',
array()
)
->join(
array('p' => 'TYPE_TB'),
'p.type_id = u.type_id'
)
->where('u.group_id = ?', '1000')
->where('u.f_del = ?', '0')
->order(array('u.type_id', 'u.user_id'))
;

SQL の方が直感的でわかりやすいことは否めない。
社内にO/R マッピングを推奨するのは大変だ。