2007年12月12日

Net::FTP::Simple

ダウンロードされるファイルは実行パスみたい、、指定はできない模様、、。。
まぁちょっと使う程度にはいいかも。
my @received_filtered_files = Net::FTP::Simple->retrieve_files({
username => $username,
password => $password,
server => $server,
remote_dir => $remote_dir,
debug_ftp => 1,
file_filter => qr/^2007/,
mode => 'ascii',
});
debug_ftp は、以下のような感じで出る。
Net::FTP=GLOB(0x300214d4)<<< 226 Transfer complete.
Net::FTP=GLOB(0x300214d4)>>> PORT 192,168,1,2,161,249
Net::FTP=GLOB(0x300214d4)<<< 200 PORT command successful
Net::FTP=GLOB(0x300214d4)>>> RETR 20070316.txt
Net::FTP=GLOB(0x300214d4)<<< 150 Opening ASCII mode data connection for 20070316.txt (35435 bytes)
Net::FTP=GLOB(0x300214d4)<<< 226 Transfer complete.
Net::FTP=GLOB(0x300214d4)>>> PORT 192,168,1,2,161,250
Net::FTP=GLOB(0x300214d4)<<< 200 PORT command successful
Net::FTP=GLOB(0x300214d4)>>> RETR 20070317.txt
Net::FTP=GLOB(0x300214d4)<<< 150 Opening ASCII mode data connection for 20070317.txt (114635226 bytes)
それにしても、インストールの時の依存モジュールの数ったら、結構、すごいね、、、(w;

2007年8月31日

Deep recursion on subroutine ...

Class::Accessor を 間違えて use base せずに、単純に use したら、"Deep recursion on subroutine..." とか言われて少しハマッタ。。。

2007年8月29日

publicfile と CSS

今日のバッドノウハウは、なかなかレアだww

publicfile 配下の HTML を読み込んだ際に、Firefox だと CSS が読み込まれない、、というか、適用されない、、。回避する方法をいくつか発見したので紹介。。ちなみに、IE6では、ちゃんと適用されている、、。

1. DOCTYPE宣言を書かない
2. DOCTYPE宣言を XHTML → HTML に変更する ※DTDのURLは指定しない
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
3. CSS のファイル名を、example.css → example.css.text=css に変える

原因は、publicfile が CSS ファイルを返すヘッダーに、Content-Type: text/plainとして出力するため、Firefox では CSS として読み込まれず、適用してくれない。。

どうやら、Firefox で XHTML としてDOCTYPE宣言をすると、サーバーの返すヘッダーもちゃんとチェックしているようです、、ただ、IE6 は、その辺がユルユルみたい。。

【参考】
publicfile においてファイル名でヘッダーを操作する
publicfile home
Mozilla Webページ作者 FAQ - スタイルシートが機能しない! どうして?

2007年8月9日

IEで overflow: hidden と、 position: relative。

IE6 で、overflow: hidden が上手くいかないケース。。っというか、Firefox と挙動が違うので、苛立った件。
#wrapper {
background: #fcc;
border: 1px solid gray;
overflow: hidden;
width: 50px;
height: 50px;
}
#container {
background: #ccf;
border: 1px solid gray;
position: relative;
}
<div id="wrapper">
<div id="container">
<span>aaaaaaaaaaaaaaaaaaaaa<br />aaaaaaaaaaaaaaaaaaaaaaaaa</span>
</div>
</div>
Firefox だと、ちゃんとoverflow: hiddenで、範囲外の部分が切り落とされるのだが、、IE6 だと、、切り落とされない。。しかも、面白い事に、width と height を、0px 指定すると IE6 でも、隠される。。。ちなみに、1px 指定だと全部表示される。。
何故かと原因を探していたら、id=container の、position: relative が原因らしい、、何故だ?? position: static にすると、正常な動作をするみたい、、、。。

追伸:Hash Mitz先生へ
メッセージ頂いていたのに返信しなくて、すみません、、今度、fieldset の件も合わせて機会のあるときに、いろいろお聞きいたします。。宜しくお願いいたします(><)
って、これメッセージ返信すればいいじゃん、、orz

2007年7月24日

IE で fieldset の background-color が...

今日は、CSS をごにょごにょしていたら、、IE だけ fieldset の background-color の色が他のブラウザと違う表示のされ方をする事を発見。。。
fieldset {
margin: 0;
padding: 10px;
border: 1px solid gray;
background-color: #69C;
color: white;
}
んー、まだまだ、CSS は勉強中なので知らない事が多いのだが、、fieldset の background-color は、指定しない方が吉なのか?、、それとも、回避する方法があるのだろうか、、??ちなみに、Firefox と Opera では、ちゃんと同じように background-color は適用されている、、、。

2007年7月6日

初めてのパッチを書いた

今さら、CGI::Application かよってのは置いておいて、、
CGI::Application::Plugin::Config::YAML を使うときに、いきなり、config_read を使うと、"No config file specified!" とか言われて怒られるのだが、、config_read に、ファイル名渡してるんだから、それ使ってよ。って事で、パッチ書いてみました、、
※初めてのパッチ作成
参考:diffとpatchについて
*** YAML.pm.org Fri Oct 28 16:49:42 2005
--- YAML.pm Fri Jul 6 19:09:51 2007
***************
*** 78,93 ****

sub config_read {
my ($self, $file) = @_;
! my $conf = $self->config();
$conf->read($file);
return;
}

sub config {
! my $self = shift;
my $create = !$self->{__CONFIG_YAML}->{__CONFIG_OBJ} || $self->{__CONFIG_YAML}->{__FILE_CHANGED};
if ( $create ) {
! my $file_name = $self->config_file or die "No config file specified!";

my $conf;
eval{
--- 78,93 ----

sub config_read {
my ($self, $file) = @_;
! my $conf = $self->config($file);
$conf->read($file);
return;
}

sub config {
! my ($self, $file) = @_;
my $create = !$self->{__CONFIG_YAML}->{__CONFIG_OBJ} || $self->{__CONFIG_YAML}->{__FILE_CHANGED};
if ( $create ) {
! my $file_name = $self->config_file($file) or die "No config file specified!";

my $conf;
eval{
如何でしょう??
作者様に送るかどうか、、、どうしよう、、とりあえず、送ってみようかな、、id:nekokak さんが作ったものなので、日本語でお願いできるし、、orz

YAML と YAML::Syck の違い

いろいろと、YAML 周りを試行錯誤していて、YAML と YAML::Syck の違いを見つけたので、ご報告。。。
my $my_yaml = <<'__YAML__';
---
param1 : [ NOT_BLANK, ASCII, [ LENGTH, 2, 5 ] ]
? date: [ year, month, day ]
: [ DATE ]

__YAML__

use YAML;
use YAML::Syck;
use Data::Dumper;

my $data1 = YAML::Load($my_yaml);
my $data2 = YAML::Syck::Load($my_yaml);

print "--data1--\n", Dumper($data1);
print "--data2--\n", Dumper($data2);
上記のコードは、先日、苦労して見つけた、? と : の記法を用いて、ハッシュのキーに、ハッシュを持たせるための方法ですが、実はこの記法は、YAML では対応しているが、、YAML::Syck では、対応していないという事が発覚した!!上記のコードの実行結果は以下のようになった
--data1--
$VAR1 = {
'date: [ year, month, day ]' => [
'DATE'
],
'param1' => [
'NOT_BLANK',
'ASCII',
[
'LENGTH',
'2',
'5'
]
]
};
--data2--
$VAR1 = {
'HASH(0x8150b44)' => [
'DATE'
],
'param1' => [
'NOT_BLANK',
'ASCII',
[
'LENGTH',
'2',
'5'
]
]
};
Ingy++ !!
ちなみに、Dump も試してみたところ、、、
use YAML;
use YAML::Syck;

my $data = {
param1 => ['NOT_BLANK', 'ASCII', ['LENGTH', 2, 5]],
{ date => ['year', 'month', 'day'] } => ['DATE'],
};
print "--YAML::Dump--\n", YAML::Dump($data);
print "--YAML::Syck::Dump--\n", YAML::Syck::Dump($data);
実行結果、、、
--YAML::Dump--
---
HASH(0x815ebe4):
- DATE
param1:
- NOT_BLANK
- ASCII
-
- LENGTH
- 2
- 5
--YAML::Syck::Dump--
---
HASH(0x815ebe4):
- DATE
param1:
- NOT_BLANK
- ASCII
-
- LENGTH
- 2
- 5
って、どちらも、、ちゃんと Dump できないようでした、、、何か方法は無いのかなぁ、、(T_T)

追記:ハッシュになってるかと思いきや、、ただの文字列だった事に気づきました、、、このエントリーを見て、ハマッてしまった方、、大変、申し訳ありませんでした。。。m(__)m

2007年7月4日

YAML 1.0

FormValidator::Simple::ProfileManager::YAML に読み込ませるため、profile.yml を書いていて、Validator で、DATE チェックをさせる時、On Coding なら以下のように書くのだが、、YAML で書く場合に、どう書いたらいいのか分からず、、ずっと試行錯誤を繰り返し、、2、3時間ハマって、やっと出来たので、忘れないように残しておく。
On Coding の場合
use FormValidator::Simple;

my $result = FormValidator::Simple->check( $query => [
param1 => ['NOT_BLANK', 'ASCII', ['LENGTH', 2, 5]],
{ date => ['year', 'month', 'day'] } => ['DATE'],
]);
っと書けばいいのだが、これを YAML で、しかも、ハッシュの状態のまま持たせるには、どうしたらいいのか!?ちなみに、普通はリストで以下のように書く
---
- param1
- [ NOT_BLANK, ASCII, [ LENGTH, 2, 5 ] ]
- date: [ year, month, day ]
- [ DATE ]
っんで、これをハッシュと同じように持たせるには、以下のようにしたら上手くいった
---
param1 : [ NOT_BLANK, ASCII, [ LENGTH, 2, 5 ] ]
? date: [ year, month, day ]
: [ DATE ]
ちなみに、この特殊な書き方をすると、Alias が付けられなかった、、(ただの文字列扱いにされた)
参考:YAML Ain't Markup Language (YAML™) 1.0

っで、最悪な事に、このエントリーを書いていて、それって、自分が作りたい DataObject を、Perl で書いてから、それを、YAML::Dumper で、吐き出せばいいんじゃねっとか思った。。。orz -> 自爆メソッド

ちゃんと YAML を習得しなくてわ、、、

追記:上手くいってませんでした、、、申し訳ないです、、、ただの文字列として判定されていました、、。申し訳ないです。。。m(___)m

CGI::Application::Plugin::FormValidator::Simple::ProfileManager::YAML

を作ってみたw ってか、パッケージ名、長すぎっ(--;)
CPAN Author になりたいけど、これが、最初のモジュールってのも、なんか自分的に嫌だなぁ、、、。
package CGI::Application::Plugin::FormValidator::Simple::ProfileManager::YAML;

use strict;
use vars qw($VERSION @EXPORT);
use warnings;
use FormValidator::Simple::ProfileManager::YAML;

require Exporter;

@EXPORT = qw(
set_profiler
get_validate_profile
);
sub import { goto &Exporter::import }

$VERSION = '0.03';

sub set_profiler {
my $self = shift;
my ($path_to_profile) = @_;

if (!$self->{validate_profiler}) {
$self->{validate_profiler}
= FormValidator::Simple::ProfileManager::YAML->new(
$path_to_profile
);
}
return $self->{validate_profiler};
}


sub get_validate_profile {
my $self = shift;
return
$self->{validate_profiler}
? $self->{validate_profiler}->get_profile(@_)
: {};
}


1;
__END__
使い方としては、以下のような感じです

package MyApp;

use strict;
use warnings;

use base 'CGI::Application';

use CGI::Application::Plugin::FormValidator::Simple::ProfileManager::YAML;

sub cgiapp_init {
my $self = shift;

$self->set_profiler($path_to_profile);
}

sub mode1 {
my $self = shift;

my $profile = $self->get_validate_profile('group1');

$self->form(@$profile);

# ~云々~
}
んー、いろいろ抜けてますが、とりあえずこれでいかがでしょうか?

■追記
タイトルが長すぎて、途中で切れてるっ

2007年6月20日

CGI::Application はじめました

いろいろあって、CGI::Application を一度は触っておこうという事になったので、その備忘録とかいろいろ、たぶん、綴っていく予定、、。
とりあえず、sample的なものを作りはじめた。
ディレクトリ構成は今のところ、こんな感じ
/index.cgi
/MyApp -- /Dispatch.pm
/Welcome.pm
index.cgi
#!/usr/bin/env perl

use strict;

use MyApp::Dispatch;
MyApp::Dispatch->dispatch();

exit;
MyApp::Dispatch
package MyApp::Dispatch;

use strict;
use base 'CGI::Application::Dispatch';

sub dispatch_args {
return {
prefix => 'MyApp',
table => [
'' => { app => 'Welcome', rm => 'start' },
':app/:rm' => { },
],
};
}

1;
MyApp::Welcome
package MyApp::Welcome;

use base 'CGI::Application';

use strict;
use CGI::Application::Plugin::AutoRunmode;

sub cgiapp_init {
my $self = shift;
$self->header_props(-type => 'text/html; charset=SJIS');
}

sub setup {
}

sub start : StartRunmode {
my $self = shift;

my $q = $self->query();

my $output .= $q->start_html(-title => 'Welcome CGI::Application!!');

$output .= '<h1>Welcome CGI::Application!!</h1>';

$output .= $q->end_html();

return $output;
}
"setup" Method が無いと動かない模様、、。まぁ、そのうち使うだろうから定義だけはしておくべし。。。
上記のように作成すると、URL とかが、
http://www.exsample.com/index.cgi/welcome/start
とかアクセスできる

2007年6月15日

CGI - Perl から、Excel の出力

また、いつか使う時が来ると思うので、備忘録的に残しておこう、、サンプルコード。
どこかで、調べてコピッただけ、だけど、、、orz
use Jcode;
use Spreadsheet::WriteExcel::Big;
use Unicode::String qw(utf8 utf16);

print 'Content-type: application/vnd.ms-excel', "\n",
'Content-Disposition: attachment; filename="結果.xls"', "\n\n";

my $workbook = Spreadsheet::WriteExcel::Big->new("-");
my $worksheet = $workbook->add_worksheet;
my $format = $workbook->addformat(font => "MS PGothic");

my ($row_num, $col_num) = (0,0);
for my $row (@rows) {
for my $col (@$row) {
$worksheet->write_unicode(
$row_num, $col_num++,
utf8(Jcode->new($col)->utf8)->utf16, $format,
);
}
$row_num++;
}
$workbook->close;
注意点としては、、
Spreadsheet::WriteExcel::Big を使う事で、大量データのエクセルを作成できる、Big じゃないものだと、途中で落ちる、、??とか、あったような、、
あと、utf16 じゃないと文字化けする??
とか、こんな感じで Excel 作れたよって話し。。。
最新のモジュールとか見直してみた方がいいかも、、、。

sleep は、SIGALRM で解除できる。

最近、daemontools を利用した、perl プログラムを、以下のように書いている
my $END_FLG = 0;
$SIG{HUP} = $SIG{TERM} = sub {
$END_FLG = 1;
};

while (sleep 60) {
# ... bla bla bla ...
exit if $END_FLG;
}
っで、SIGHUP とか SIGTERM とかが来たら、安全な場所で、プログラム停止ができるように組み込んだ、あと、調べて分かった事が、ひとつふたつあるので紹介。SIGKILL は、捕捉したり無視したりできないという事がわかった、それと、SIGSTOP も同じという事が発覚した、、。
参考:perlドキュメント日本語訳 - Perlのプロセス間通信#Signals
そこで、SIGSTOP が捕捉できないって事は、例えば、他サーバーと通信中に SIGSTOP とか受信したら、どうなるんだ??通信相手には、STOP なんて知らせて無いのに強制停止、この時、返答が来たらどうなるの??それに、通信中に停止すると、何も通信が無くなるから途中で、コネクションが強制切断されたりする可能性があるし、かなり困るなぁ、、、SIGSTOP が捕捉できないというのは、仕様としてどうなのだろう、、、??

それと、タイトルの件だけど、sleep が SIGALRM で再開できるってのは、師匠の話によると、alarm を使って、sleep が実装されているとの事、なるほどぉ~!

っで、ふと思ったのだけど、上記に書いた実装方法だと、おそらくだけど、sleep に入って、1秒経過する前に SIGALRM を受信してしまうと、ループから抜けてしまう気がする、、。。

2007年6月8日

Windows ユーザ必見のツール!!

以前にもう一つのブログでも紹介したのですが、いろいろと Tips がたまって来たので、こちらで紹介させて頂きます。ソフトウェアの紹介については、こちらの記事で、、。
っで早速、Launchy の Tips を紹介。

■Launchy から TeraTerm を起動して任意のマクロファイルを実行する

TeraTerm Menu を使わなくても、キーボードだけで、簡単にアクセスできるので非常に便利なワザ。
使い方
ALT + Space → "tt 127.0.0.1" → Enter
etc...
設定方法
  1. Launchy の検索対象のディレクトリ配下に、ショートカットを作成、ショートカットの名前を「tt 127.0.0.1」。※ドメイン名とかが分かり易い
  2. リンク先 「"C:\Program Files\TTERMPRO\ttermpro.exe" /M=ttl\127.0.0.1.ttl /nossh」
  3. ショートカットをIndexに登録させるため、コンテキストメニューより [Rebuild Index] を実行

■Launchy から NextFTP を起動して任意の接続先に接続する

使い方
ALT + Space → "nf 127.0.0.1" → Enter
etc...
設定方法
  1. NextFTP の「ホストに接続」ダイアログにて、ショートカットを作成したいホストを選択し、右側の[ショートカット作成]を押す
  2. デスクトップにショットカットが作成されるので、Launchy の検索対象のディレクトリ配下に、ショートカットを移動
  3. ショートカットの名前を「nf 127.0.0.1」に変更
  4. ショートカットを、インデックスに登録させるため、コンテキストメニューより [Rebuild Index] を実行
※ちなみに、NextFTP のコマンドラインオプションは、ココが詳しい

■Launchy から いろいろな Windows コマンドを実行する

使い方
ALT + Space → "cmd" → TAB → "ping 127.0.0.1" → Enter
ALT + Space → "cmd" → TAB → "ipconfig /all" → Enter
etc...
設定方法
  1. 下記のバッチファイルを、Launchy の検索対象のディレクトリ配下に作成
  2. ショートカットを、インデックスに登録させるため、コンテキストメニューより [Rebuild Index] を実行

ファイル名:cmd.bat
@echo cmd command line for here
@echo off
cd c:\
cmd /K "%1 %2 %3 %4 %5 %6 %7 %8"
っと、そんなわけで、Windows での開発環境も、それなりにストレスの溜まらない方向へ、、まぁ、、Mac が使えればそれで、いいのだけどね、、orz
でも、Windows のコマンドラインも、Launchy があれば、それなりに使えるようになります。。というネタでした、、、。

2007年6月4日

今さら「Fizz-Buzz問題」に取り組む。。。

今さらですが、やってみました、、、

どうしてプログラマに・・・プログラムが書けないのか?

とりあえず、問題だけ見て一回目は、1分程で以下のように、、
for (1..100) {
print ("FizzBuzz\n"), next if ($_ % 3) == 0 && ($_ % 5) == 0;
print ("Fizz\n"), next if ($_ % 3) == 0;
print ("Buzz\n"), next if ($_ % 5) == 0;
print "$_\n";
}
っで、これはひどいので、さらに考えてみた、、
print 
+(($_ % 3) == 0 && ($_ % 5) == 0 ? 'FizzBuzz'
: ($_ % 3) == 0 ? 'Fizz'
: ($_ % 5) == 0 ? 'Buzz'
: $_)
, "\n" for 1..100;
あまり変わって無い気がしますが、、、とりあえず、鰯の回答は以上、、後は、他の方のを見て勉強させてもらいます、、、。

2007年5月30日

PRE タグにスクロールバーを付けた

以前から、PRE タグで囲んだ内容がオーバーすると表示されない事に困っていたくせに、放置気味だったのですが、たまたま、同じ Blogger の人のサイトを見ていて、ちゃんとスクロールバー表示されてるじゃんって事で、Firebug で除いてみたら、
pre {
overflow-x: auto;
}
こんな内容が入ってたので、自分も加えてみた。。とりあえず、Firefox の表示ではOKなので、良しとする。

2007年5月14日

CPAN に登録されている全てのモジュールのリスト

を取得するスクリプトを作ったので晒してみる。。。
#!/usr/bin/env perl

use strict;
use warnings;
use LWP::Simple;

my $url = 'http://www.cpan.org/modules/02packages.details.txt';
my $content = get($url) or die $@;

open my $fh, '> cpan_modules.txt' or die $!;
for (
split /(?:\r\n|\r|\n)/, (split /(?:\r\n|\r|\n){2}/, $content)[1]
) {
print $fh (split /\s+/, $_)[0], "\n";
}
close $fh;
ってか、勝手に "http://www.cpan.org/modules/02packages.details.txt" この URL を使わせてもらってるのだが、いいのか?
エラー処理とか改行コードとか、かなり適当な感じなのだが、、まっ、取得できたしいいかw
AAA::Demo
AAC::Pvoice
AAC::Pvoice::Bitmap
AAC::Pvoice::Dialog
AAC::Pvoice::EditableRow
AAC::Pvoice::Input
AAC::Pvoice::Panel
...
...
...
動かすと、↑こんなのが取得できる。

2007年5月1日

prototype.js & jQuery.js を一緒に使ってみる。

prototype.js によるオブジェクト指向なプログラムと、jQuery.js のオブジェクトチェーンな実装を最大限活用して、自分流を作ろうかなと画策中なわけで、、そんな中、私の師匠が教えてくれた、Ext js が気になりつつ、、...
var MyClass = Class.create();
Object.extend(MyClass.prototype, {
initialize: function (elm_id) {
this.id = $("#"+elm_id);
this.id.click(this.click.bindAsEventListener(this));
},
click: function () {
alert("Hello!");
},
show: function (opt) {this.id.show("slow")},
hide: function (opt) {this.id.hide("slow")}
});
var Human = new MyClass;
Human.click();
最近はこんな感じの設計です、、どうなんでしょう?ダメ出し大歓迎です。ではでは、、、

2007年4月12日

「はてブの被ブックマーク数を表示する」をBloggerでやってみる

はてなに記載されている、「自分のブログに被ブックマーク数を表示する - Blogger」は、たぶん、Beta 版の時の方法ではないかと思う、、
(少なくとも自分のBloggerではテンプレートの変更方法が違う、、)
なので、新バージョンとなった、Blogger にて被ブックマーク数を表示する方法を解説しようと思ふ。。。
方法は2つあって、1つ目の方法は、簡単だけど表示位置が微妙。。2つ目の方法は、表示を位置を合わせるために、ちょっと難しくなってしまった方法。。

【方法1】※自己責任において編集を行ってください。。
1.「管理画面(マイレポートorダッシュボード) > テンプレート > HTML の編集 > テンプレートを編集」を表示して、右上にある、「ウィジットのテンプレートを展開」のチェックボックスを ON にする。

2.下記のように記載されている場所を探して、その下にはてブ表示ようのコードを貼り付け。※今回は、バックリンクの横あたりに配置してみる。
       <!-- backlinks -->
<span class='post-backlinks post-comment-link'>
#... いろいろ ...
</span>
# ---- ↓ココに貼り付け ----- #
<a expr:href='"http://b.hatena.ne.jp/entry/" + data:post.url' target="_blank">
<img expr:src='"http://b.hatena.ne.jp/entry/image/" + data:post.url' alt="このエントリーを含むはてなブックマークを表示" title="このエントリーを含むはてなブックマークを表示" style="border:0;" />
</a>
# ---- ↑ココに貼り付け ----- #
っと、これが簡単な方法ですが、表示をしてみると、画像の位置が微妙にずれている、、、。
※HTMLタグのコピーは、マウスで範囲選択でやって下さい。。表示しきれてない文字があるので、、。

【方法2】
1.方法1-1と同様。
2.方法1と同様にコードを貼り付けるのですが、少しコードを変更してあります。
       <!-- backlinks -->
<span class='post-backlinks post-comment-link'>
#... いろいろ ...
</span>
# ---- ↓ココに貼り付け ----- #
<a expr:href='"http://b.hatena.ne.jp/entry/" + data:post.url' target="_blank" title="このエントリーを含むはてなブックマークを表示">
<span class='hatena-counter' expr:style='"background-image: url(http://b.hatena.ne.jp/entry/image/" + data:post.url + ")"'> </span>
</a>
# ---- ↑ココに貼り付け ----- #
※HTMLタグのコピーは、マウスで範囲選択でやって下さい。。表示しきれてない文字があるので、、。

3.スタイルシートの追加をする。テンプレートの上部に、<b:skin> .. </b:skin> で、囲まれた部分があるので、その中へ下記のスタイル定義を追加する。
.hatena-counter {
background-repeat: no-repeat;
background-attachment: scroll;
background-position: left center;
margin:0pt 0pt 0pt 0pt;
padding: 15px;
}

簡単に解説すると「方法1」は、img タグでそのまま表示しているが、「方法2」は、span タグの background として、center 表示をしています。他の画像を見てみたら、そうやって定義されてたから真似してみただけ、、。

っと、以上ですが、もっと簡単な方法とかあったら教えてください( >< )

2007年4月6日

Text::CSV は日本語入ってるとダメなんだ、、、orz

Text::CSV で parse したらエラー出まくりだったので、エラーになってる CSVのファイルをのぞくと日本語の行がエラーになっていた、、、orz どうやら、日本語入っているとダメみたい、、っで、検索してみたら「勝手に添削 - PerlによるCSVファイルの高速集計 2 - 404 Blog Not Found」で、Text::CSV_XS で、{binary=>1} のオプションを付けると、どうやら日本語混じりでも OK らしいので、さっそくインストールしてコードを修正。モジュール名の変更だけで済んだ。
use strict;
use warnings;
use Text::CSV_XS;

$| = 1;

my $file = './hoge.csv';

my $csv = Text::CSV_XS->new({binary=>1});

open my $fh, '<', $file or die $!;
while (<$fh>) {
chomp;
$csv->parse($_) or next;

my @fields = $csv->fields;

# ... your code here ...
}
close $fh;
ちなみに環境
C:\>perl -v

This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 50 registered patches, see perl -V for more detail)

Copyright 1987-2006, Larry Wall

Binary build 820 [274739] provided by ActiveState http://www.ActiveState.com
Built Jan 23 2007 15:57:46

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

2007年4月3日

Blogger でも、コードハイライト してみる。by google-code-prettify

もともと、はてなダイアリーを使っていたのだが、見た目の良さや使い勝手から、Blogger に乗り換えた。ただ、はてなダイアリーだとプログラムを載せるときに、しっかりハイライトしてくれるところが、すごく良いんだけど、残念なことに Blogger にそのような機能は無い、、、orz
っで、自分で作ろうかなぁとか思ってたら、すでに Google が、ライブラリ作ってたよ、、、。って事で、この Blogger で使えるか試してみたら使えたので、その手順を公開。

1.google-code-prettify - syntax highlighting of code snippets in a web page から、ソースをダウンロード。
2.Blogger の「ダッシュボード」から、該当ブログの「レイアウト」を選択
3.「ページ要素を追加」で、「HTML/JavaScript」を選択
4.「コンテンツ」にソースをベタ貼り(これでプログラムソースを読み込ませる)
↓↓↓こんな感じ
<script type="text/javascript"><!--

// prettify.js code here!!

// --></script>
<style type="text/css">

/* prettify.css code here!!

</style>
5.次に、「HTML の編集」で、body の onload で、スクリプトを実行させる。
  <body>
<!-- ↓↓↓ onload で prettyPrint() を実行 -->
<body onload='prettyPrint()'>
6.ここまでが、準備で実際に利用する時は、
<pre class="prettyprint">
<!-- ココに自分のプログラムソースを書いて投稿する -->
</pre>
以上。
っで、鰯のブログは、背景が黒なので、黒に合うように、css を編集しました。以下参考までに。あと、css 編集してて知ったのだが、"#080" は、"#008800" って感じに展開されるようになっているらしい。
<style type="text/css">
/* Pretty printing styles. Used with prettify.js. */

.str { color: #080; }
.kwd { color: #09F; }
.com { color: #800; }
.typ { color: #96F; }
.lit { color: #399; }
.pun { color: #996; }
.pln { color: #CCC; }
.tag { color: #09F; }
.atn { color: #96F; }
.atv { color: #080; }
.dec { color: #96F; }
pre.prettyprint { padding: 2px; border: 1px solid #888; }

@media print {
.str { color: #060; }
.kwd { color: #006; font-weight: bold; }
.com { color: #600; font-style: italic; }
.typ { color: #404; font-weight: bold; }
.lit { color: #044; }
.pun { color: #440; }
.pln { color: #000; }
.tag { color: #006; font-weight: bold; }
.atn { color: #404; }
.atv { color: #060; }
}
</style>
【追記】
何故か、、HTML のソースで適用すると、改行が削除されてしまいます、、、orz 原因調査中。。。
【原因 2007/04/03 20:00】
Blogger で投稿する際、改行が br タグに変換されて、pre 内で、HTML をハイライトさせようとした時に、br が google-code-prettify でパース中に削除されてしまっていた。。具体的に削除されている場所までは、わからなかったけど、とりあえず、以下のような感じで対応させてみた。
// fetch the content as a snippet of properly escaped HTML.
// Firefox adds newlines at the end.
var content = PR_getInnerHtml(cs);
content = content.replace(/(?:\r\n?|\n)$/, '');

// do the pretty printing
var newContent = prettyPrintOne(content);
↓↓↓こんな感じに変えてみた、、、
// fetch the content as a snippet of properly escaped HTML.
// Firefox adds newlines at the end.
var content = PR_getInnerHtml(cs);
content = content.replace(/(?:\r\n?|\n)$/, '');
content = content.replace(/<br>/g, "\n");

// do the pretty printing
var newContent = prettyPrintOne(content);
prettify.js line:1442 にあたりに追加した。パースさせる前に、br を改行に変換、、、orz すんません。。。

参考
【ハウツー】
ハイライトもGoogle流 - "google-code-prettify"でソースコードに色付けを
google-code-prettifyが対応しているソースコードはC、C++、Java、Javascript、Python、Ruby、PHP、 Perl、Bash、Awk、Makefiles、HTML、XML、CSSなど。一方、コメントの慣例のためにSmalltalk、LispやCAML ライクなプログラミング言語のソースコードでは正しく動作しない。厳密にその言語でなくとも、対応しているプログラミング言語と記述方法が似ていれば動作する。

2007年4月2日

メッセージボックスをコピー。

メッセージボックスのテキストはクリップボードにコピーできる。 で紹介されている方法、たぶん、これ以外と知られていないと思う。。初めて知った。っで、試してみた。
---------------------------
秀丸エディタ
---------------------------
(無題) は更新されています。保存しますか?
---------------------------
はい(Y) いいえ(N) キャンセル
---------------------------
おぉぉ!
これって、Mac もできるのかなぁ??帰ったら試してみよう。

2007年3月25日

Firefox が、ひどいメモリ食い

Mac で、Firefox を長時間使っていると、いつの間にか、ものすごいメモリを食っていて、めっちゃスワップしてしまいます、、、何故でしょう、、、。。。
>top
PID COMMAND %CPU TIME #MREGS RPRVT RSHRD RSIZE VSIZE
2059 firefox-bi 12.9% 80:50.32 3073 422M+ 65.9M 448M 1022M

2007年3月23日

RedHat で CapsLock → Ctrl に変更

IBM ThinkPad X22(古!!) に、RedHat9 を入れてあって、たまにしか使っていなかったのだが、いい加減キーボード使いづらいよって事で、キーの配置を変更しました。その時の作業メモ。
cd /etc/X11/
vi XF86Config
----------------------------------------------
Option "XkbOptions" "ctrl:nocaps"
追加するか、コメントはずして X を reboot すると有効になりました。これで、やっと快適な、ThinkPad Life を過ごせそうです、、、w

参考
中谷彰宏のサイバー研究室

2007年3月19日

ブラウザの特殊文字認識について物申す

ブラウザの特殊文字(&amp;..etc)の認識についてご報告です。

A タグの href 属性の中で、以下のようなコードを書くと、IE や Opera では、特殊文字として認識されてしまいます。FireFox では認識されずに済む。
<A href="./xxx.cgi?q=test®_flg=xxx">LINK</A>
とした場合に、&reg が、® として認識されてしまう、、、orz
確かに、特殊文字については、;(セミコロン)を省略して記載できるのだが、href 属性の中まで、特殊文字の表示として認識しなくてもいいのでは??これは、Bug ではないかと思っているのだが、どうなのだろう、、。
W3C で規定されている特殊文字は、他にも多く存在するため、同様の問題に遭遇する人は多いのではないかと思うのだが、、、。何か、回避策をご存知のかたは、コメント頂けると嬉しいです。
おそらく、この投稿を IE や Opera で見ると、A タグの &reg が特殊文字に変換されてしまっているのでは、と思います。

2007年3月16日

WSH でショートカットを作成

Becky でメール新規作成画面をショートカットアイコンから起動したいので、どうにかならないかと調べた。
まず、Becky でメール新規作成画面をショートカットで起動するには、ショートカットに以下のようにリンク先を設定する
"C:\Program Files\RimArts\B2\B2.exe" mailto:hogehoge@fugafuga.com
ちなみに、mailto に、
mailto:hogehoge@fugafuga.com?subject=件名&body=内容
とすれば、件名と内容を設定できる。
RFC2368 準拠らしい。Becky ヘルプより

で、今度は上記で作成したショートカットを、メールアドレスを変えて、大量に作成したいので、WSH というスクリプトを利用して、create_mail_sc.wsf を下記の内容で作成。
[']シングルクオートで、コメントらしい
<package>
<job id="vbs">
<script language="VBScript">
Const ForReading = 1, ForWriting = 2, ForAppending = 8

Set objShell = WScript.CreateObject("WScript.Shell")
strDesktop = objShell.SpecialFolders("Desktop")

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
Set objInput = objFSO.OpenTextFile("mail.txt", ForReading) 'メールアドレスのファイル
Do Until objInput.AtEndOfStream
strLine = objInput.ReadLine

Set objShortCut = objShell.CreateShortcut(strDesktop + "\" + strLine + ".lnk")
objShortCut.TargetPath = "C:\Program Files\RimArts\B2\B2.exe"
objShortCut.Arguments = "mailto:" + strLine ' Beckyの引数
objShortCut.WorkingDirectory = "C:\Program Files\RimArts\B2"
objShortCut.Save

Loop
objInput.Close

WScript.Echo "ショートカットを作成しました。"
</script>
</job>
</package>
そして、mail.txt をデスクトップに作成して、
hogehoge1@fugafuga.com
hogehoge2@fugafuga.com
hogehoge3@fugafuga.com
ってな内容で、作成して。create_mail_sc.wsf をダブルクリックで実行すると、ショートカットが簡単に大量に作れる。

参考:
Windows管理者のためのWindows Script Host入門
msdn - Windows Script Host

2007年3月12日

SQL::Abstract を勝手に拡張

DBIx::Simple を使っていて、SQL::Abstract が、"GROUP BY" 句 に対応していないので、勝手にプラグインっぽいの作って、対応させたのだが、、、いいのだろうか、、、;
"SQL/Abstract/Plugin/Groupby.pm" っての勝手に作って、以下のようなコードを書いたのだけど、、ほとんど、SQL::Abstract の "order by" の実装をパクッただけ、、、orz
ちなみに、な部分以外はオリジナルを持ってきた、、、。
package SQL::Abstract::Plugin::Groupby;
use Carp;
use strict;

our $VERSION = '0.01';

sub puke (@);

sub where {
my $self = shift;
my $where = shift;
my $order = shift;

# Need a separate routine to properly wrap w/ "where"
my $sql = '';
my @ret = $self->_recurse_where($where);
if (@ret) {
my $wh = shift @ret;
$sql .= $self->_sqlcase(' where ') . $wh if $wh;
}

# group by?
if (ref $order eq 'HASH') {
$sql .= $self->_group_by($order->{group_by}) if $order->{group_by};
$sql .= $self->_order_by($order->{order_by}) if $order->{order_by};
# order by?
} elsif ($order) {
$sql .= $self->_order_by($order);
}

return wantarray ? ($sql, @ret) : $sql;
};

sub _group_by {
my $self = shift;
my $ref = ref $_[0];
puke "Undefined group_by data struct" unless $_[0];

my @vals = $ref eq 'ARRAY' ? @{$_[0]} :
$ref eq 'SCALAR' ? ${$_[0]} :
$ref eq '' ? $_[0] :
puke "Unsupported data struct $ref for GROUP BY";

my $val = join ', ', map { $self->_quote($_) } @vals;
return $val ? $self->_sqlcase(' group by')." $val" : '';
};

{
no strict 'refs';
*SQL::Abstract::where = \&where;
*SQL::Abstract::_group_by = \&_group_by;
}
ってか、"group by" って、一般的な RDBMS で対応しているのかどうか、不安なので俺々勝手モジュールだけにしておく、、。コメントとか頂けたら嬉しいかもです。。。とか、勝手に言ってみる、、、orz

ちなみに使い方は、こんな感じです。。気分的には、DBIx::Class インスパイア?!っでも無いか、、orz
use SQL::Abstract;
use SQL::Abstract::Plugin::Groupby;

my ($query, @bind) = SQL::Abstract->new->select(
'table_name',
[qw/field1 field2/],
{field1 => 'value1'},
{
group_by => [qw/field1/],
order_by => [qw/field2/],
},
);

Regexp::Assemble 便利っぽい

にぽたん研究所 - 二度目の公開!電話番号の正規表現 で、紹介されてた Regexp::Assemble がとっても便利そうなのでメモメモ。
  use Regexp::Assemble;

my $re = Regexp::Assemble->new;
$re->chomp(1);
$re->add(<DATA>);
print $re->re;

__DATA__
104
103
102
ってな感じで、正規表現としてマッチさせたいデータを流し込むと、解析してマッチさせるための正規表現を作ってくれちゃう、便利そうなモジュール。

Google - Regexp::Assemble
ってか、ずいぶん前から紹介されてたんだね、、、orz
今度、機会があったら試してみよう。

2007年3月5日

FireFox CPAN 検索プラグイン

環境を移行して入れなおしたので、メモ。
"C:\Program Files\Mozilla Firefox\searchplugins" に下記の設定ファイルを追加。
cpan.xml
<?xml version="1.0" encoding="UTF-8"?>
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
<ShortName>CPAN</ShortName>
<Description>CPAN Search</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAB3RJTUUH1gUdASQWZt5rYAAAABd0RVh0U29mdHdhcmUAR0xEUE5HIHZlciAzLjRxhaThAAAACHRwTkdHTEQzAAAAAEqAKR8AAAAEZ0FNQQAAsY8L/GEFAAAAMFBMVEX///8AAHsAewAAe3t7AAB7AHt7ewC9vb17e3sAAP8A/wAA////AAD/AP///wAAAAAAJ/C6AAAACXRSTlP//////////wBTT3gSAAAAQUlEQVR4nD3NMQ4AIAwCwD6fja86sqHUKulwA6EFGklx6cJ+oBAXKNoNJx8qoMEDPmA6mR7wXMpirgchocvML0w26AFaAyIThioAAAAASUVORK5CYII=</Image>
<Url type="text/html" method="GET" template="http://search.cpan.org/search">
<Param name="query" value="{searchTerms}"/>
<Param name="mode" value="all"/>
<MozParam name="client" condition="defaultEngine" trueValue="firefox-a" falseValue="firefox"/>
</Url>
<SearchForm>http://search.cpan.org/search</SearchForm>
</SearchPlugin>
適当に、Google のプラグイン見て作ったやつなので、おかしげな所満載ですが、、あまり、気にしないでください。。。
あぁ、、プラグインが全然入ってないから入れなきゃ、、、とりあえず、FireBug は必須だよね

2007年2月27日

Google の HDD のレポートの衝撃

Google によるHDDの故障率に関するレポートを見て、今まで信頼をしていたものが失われてしまった、、。これは、かなり衝撃的なレポートだ、、。ただ、改めて考えてみると、そもそも、HDD は消耗品なわけで、ある程度の故障はやむをえない、、。Google のように "必ずコピーが3つ存在する" というように、HDD の構成に頭を悩ますより、単純にデータのコピーを複数作成して、それをいかに上手に運用するかの方が理にかなっているという事なのかも、、。
「S.M.A.R.T」による計測値も、ほとんど当てにならないらしく、、真にハードディスク障害の早期発見ができるツールが出てこない限り、ユーザー側でなんらかの措置が必要になりそうです。。
きっと、この辺をうまい事やってくれるオープンソース系のプロジェクトが発生するかも?もしかしたら、もうあるかも?

Googleによると、ハードディスクは温度や使用頻度に関係なく故障する
ハードディスクに関する4つの都市伝説

2007年2月26日

jQuery Form Plugin ステキ

jQuery 単体で、Ajax 通信とかしようとしたら、標準の serialize とか使いづらくて、みんな、どうしてんだろう、、、とか思ってたら、"Form Plugin" とか発見!なるほど、みんな、これ使ってるのかぁ~、納得。ってなわけで、次回は、"Form Plugin" を使って、楽々 Ajax 通信なわけです。
そして、jQuery の Plugin のページ 見たら、ものスゴくいっぱいPlugin あるじゃないですか、、。いろいろありすぎで、迷いそうです。。まぁ、じっくりと触ってみるとです。

jQuery Form Plugin

2007年2月23日

Perl プロトタイプ宣言

List::MoreUtils の any の実装と使用方法を見て再発見。
# 実装
sub any (&@) {
my $f = shift;
return if ! @_;
for (@_) {
return 1 if $f->();
}
return 0;
}
# 使用方法
print "At least one value undefined"
if any { !defined($_) } @list;
何故に、ハッシュリファレンスが、コードブロックとして、ちゃんと評価されるのか、疑問に思った。。。で、any の実装で、プロトタイプ宣言を行っていたから、これが、何か怪しいなぁって事で、プログラミングPerl〈VOLUME1〉を開いてプロトタイプについて再確認してみると。
& が最初の引数であった場合、特別扱いされることを示している。通常は、プロトタイプ文字 & は \&foo や sub {} のような引数を要求する。しかし、 & を最初の引数として指定した場合には、無名サブルーチンの sub を省略して「間接オブジェクト」スロットにブロックだけを置くことができる(この場合、ブロックの後ろにはコンマは置かない)。
& の素晴らしい点は、 & を第1引数とすることによって、新しい構文が作り出せることである:
プログラミングPerl〈VOLUME1〉 page 263 より引用
なるほど~、プロトタイプ宣言した場合は特殊なのね、だから、ブロック渡しが完結にコーディングできるのですな。普段、何気なく使っていた、map や grep、sort も、そうゆう実装になっているのかなぁ、とか思った。あと、$_ のスコープが、グローバルだから、ちゃんと中でも参照できるのだなぁ、とかも思った。

2007年2月21日

html-tt.el & javascript.el を入れました。

Template::Toolkit と、只今、話題の jQuery を使い始めたので、会社の Meadow へモードを追加しました。どちらも、良い感じです、オススメ。
作者の皆様、多謝。

html-tt.el
Clouder::Blogger - html-tt - emacsのTemplate Toolkit用のmode
C-c m → [% SWITCH %][% CASE %][% END %]
C-c w → [% WHILE %][% END %]
C-c f → [% FOREACH %][% END %]
C-c e → [% ELSE %]
C-c i → [% IF %][% END %]
C-c n → [% INCLUDE "" %]
C-c d → [% *** %]
C-c s → [% %]
javascript.el
Yet Another Hackadelic - [Emacs][JavaScript] javascript.el

2007年2月18日

デブサミレポート - 第1回 Google

第1回目は、これ↓。一日目のセッションに関しては、今後、資料があがるかと思われるので、一番、資料が公開されそうにない、ここから、レポートあげます。

2/15 10:00-10:50
Googleを支える大規模分散システム / Google における開発プロセス

-- Google における開発プロセス --
スピーカー:小松弘幸 Profile
Googleトランジット モバイル担当

- プロジェクトの始まりからリリース
プロジェクトの立上げ。20%ルールプロジェクト/開発者によるアイデアやデモなど

プロジェクトメンバー。デモを見た社員が希望で参加したり、または、支援を行ったり

プロジェクトが起動に乗り始める。

プロジェクトの本格化。エンジニアに加えて、プロダクトマネージャー、デザイナー、マーケティング、広報、各チームの方が参加する。

beta リリースを行う

フィードバックをもらって、機能拡張やバグフィクスを修正。

正式リリースへ

プロジェクトは基本的に、エンジニアが、企画、設計、運用を行う。

- 20%ルール
Googleの全社員が、好きなプロジェクトや自己研鑽など、自分の好きな時間。既存サービスの拡張。新しい技術の習得。数学の学習。会社にとって、長期的にでも、メリットがあれば OK みたい。プロジェクトの立ち上げには、まず、モックの作成などを行ってから。何故なら、見ればわかるから。何をしたいのかを伝え、プロジェクトの賛同者を募る。発表の場としては、アイデアメーリングリストというものがあり、発表したアイデアに対して、1〜5点の得点とコメントをつけて返信をする形になっている。プロジェクトが成長したら、目的を明確にし、違う所のプロジェクトなどで、似たような機能が無いかなどを確認して、車輪の再発明を防いでいる。

- 情報共有
デザインドキュメント。読めばわかる。まわりからの質問に対して、何度も回答をするより、書いた方が楽なので。社内wiki wikiにプロジェクトに参加するため必要な情報、まとめなど。プロジェクトチームは、エンジニア4〜5人、プロジェクトマネージャー、ユーザーサポート、など、、10人に満たない。weekly meeting 一周間に一回のミーティング。自分たちの進捗の報告など。

- 開発環境
全てのソースコードが一元的に管理されている。他のプロジェクトの人間が、Gmail のソースコードの閲覧や変更も可能。コミットログ。コード検索。テストツール。単体テストツール、プロファイラ。ほとんどのツールが、自社開発。
テストなどで、マシンパワーが必要な場合には、大規模データを扱うなど、デモを作る段階で、数千代のクラスタを利用可能。うまい具合に処理が隠蔽されていて、ジョブの割り当てや、故障等に関してエンジニアが考える必要が無い。デモの作成段階で、ペタバイト級のストレージの利用や、ミニチュアインターネットによる、ウェブデータが自由に利用可能、個人で利用可能。

- 開発期間
納得いくまで作る。自分たちが、目標を決めて期限を設定。納得の行く所で、提出。延長の場合は再設定をする。

- 目標と成果の設定
エンジニア個人。プロジェクトチーム。会社全体。各単位で設定。四半期単位で今後の事など。

- Google トランジット
- サービス概要
最寄り駅の自動判別。目黒雅叙園は、目黒駅とか。同じ駅名でも、大手町は、東京の大手町じゃんみたいな事をしてくれる。
- 開発のお話
アメリカ版のトランジットが、別で発足していた、ソースコードを流用。
どのように統合したか、それぞれ、違うエンジンを持っていたので、それぞれを、プロトコルバッファーを利用して統合(シリアライザーのようなものらしい)。データをどのように流すのか、異なる言語間でも利用可。あらゆる所で。利用しているらすぃ。
ユニットテスト書く。コードレビュー。レポジトリに入れる前に、ソースコードレビューを少なくとも、一人に行ってもらう。
リリースに向けて。テクニカル、UI,セキュリティレビュー、、、。などなど。
最終リリース。リリース用マシンの割当。マシンのメンテは選任者がやってくれる。
リリースエンジニアと一緒に、共同作業でリリースを行う。
メーリングリストもひとつ。ソースコードレポジトリもひとつ。情報もいつでも引き出せる。

-- 鰯の感想 --
エンジニア主体で経営されている Google は、まさにエンジニアにとっての天国なのかもしれない、その反面、高い技術力や成果を求められる部分もあると思う。。。設備も体制もかなりできあがってきているのだろう、、社員同士が切磋琢磨し合える環境は非常に大事だと思う、今の会社では、切磋琢磨し合える人が、ほとんどいないため、、非常に残念で仕方が無い、、技術者としてもっと、常日頃から勉強をしてもらいたいものです。

※「Googleを支える大規模分散システム」にてついては、次回投稿します。。

2007年2月13日

サロゲートキー

ナチュラルキー - 顧客コードとか自然発生するキー
サロゲートキー - システムが自動付加するキー

サロゲートキーは変更に強い
 顧客コードのフォーマットの変更
 過去ログなどとの整合性

ビジネス的な変更が、システムに大きな影響を与えないので、この考え方は重要ですな。
確かに、今までの自分が触れてきたシステムは、ナチュラルキーを主キーにしている部分が大きく、その部分の変更には、大きなリスクを伴うため、、"さわらぬ神に祟りなし" といった感じで扱われてきた、、、。サロゲートキー重要ですな、、

参考
代理キーは「スタイル」ではなく「テクニック」
- サロゲートキーは万能では無い的な話?
第3回:BIシステムの特性を知る-基礎知識編(2)