l'essentiel est invisible pour les yeux

Sunday, December 16, 2007

ダムの水は決して漏らさず、溜め続け、勢いよく放流するのがCEOの役割である

この件でこのブログにもトラヒックが流れているので触れるべきだろう。

情報統制に関して思い出すのが次のエピソードである。(*1)

ジョブスは社員を集め、アップル最大級のキャンペーンThink differentのスタートを集う野外パーティーを開いた。席上、アップルの広告に対するThink differentを力説した。

さて、この日初めてジョブスと間近で接した一人の女性エンジニアは深く感銘し、以下に素晴らしいスピーチだったかを興奮しながら友人にメールした。

彼女のメール相手は、ソフトウェア企業家のデイブ•ワーナーという人物で、業界でもっとも影響力のある数百人の読者にメールマガジンを配信していた。そこには、マイケル•デルやビル•ゲイツといった面々も含まれていた。


翌日彼女の元には、ジョブスから「ハイ、スティーブです。話したい事があるんだけど」と留守電が入っていたようだが、幸い、彼女は、QuickTimeプロジェクトの重要人物であり解雇は免れたそうだ。

再建屋として崩れかかったアップルの組織を内部から立て直したのは、ギル•アメリオの功績が大きい。アメリオは、アップル再建に際してコスト管理と合わせて、情報統制を徹底して厳しくした。アップルの内部がブラックボックスである事は今も変わっていない。

今ドリコムは、社員が一丸となって、ダムに水を貯めているのに、少しずつ漏れている。ダムから水を放流した時よりも、漏れている事の方が話題になる。貯めても貯めても溜まらない水に、社員のモチベーションは枯れてしまう。

自分達が必死で貯めた水をCEOが勢い良く放流してくれる事が、社員の喜びであり働きがいである。
開発した製品のデザインが素敵と書かれれば、デザイナーは喜び、多くのブックマークがつけば、開発者は喜ぶだろう。水を漏らさず、貯め続け、そして、勢いよく流す事こそ、CEOの腕の見せ所であり、企画屋でありパフォーマーである内藤氏の力が最も発揮される領域だと私は思う。再建屋としての役割は、別の人物にエンパワーメントされるべきだろう。

今年の春に書いた事と重複する事が多いが、今のステージにおいても次の五つが重要である。

1. ダムの水漏れを防ぐこと。(情報統制)

2. 外部に対する水の放流先を一つに統一すること。つまり、今回の一件に関して早急に、CEOのブログからきちんと説明を入れること。楽観的に捉えれば、この一件はドリコムへの関心の高さに他ならない。ネット上を騒がせた事に関してCEOとして誠実な対応をとれば、新たな信頼が生まれる。社員•顧客•株主、全てのステークホルダーを不安な状態のまま放置してはいけない。また、CEO自らが引き続きドリコムの方向性を外部に対して(悪いニュース含めて)明確に示し続ける事。「悪いニュースはなるべく早く開示する事」はウォーレンバッフェトが投資先経営者に真っ先に求める要素の一つである。(情報公開)

3. もう一度社員のフロー状態を創りだすこと。ROEを上げる事で、短期的な利益を産み出すような、組織の最適化と名付けた過剰な人材流出はなるべく避けること。既存の社員のモチベーション低下にもつながりかねない。人無くして組織は成り立たない。長期的な価値創造を念頭に置き、社員のモチベーションを高めるビジョンを示す事。プロモーションすべき方向は、学生に向けてのファン獲得ではなく、社内の優秀な人材からの信頼を確固たるものとすること。それこそが、後の社外のファン獲得へとつながる。 (内発的動機付けとフロー)

4. 苦境を共に乗り越えようと一丸となってくれる人材の流出を避ける事と、今後は自分達より優秀な人間を雇う努力を惜しまない事。新卒の教育は時間とコストを伴う。今の時期は、まだ時期早々。(人材戦略)

5. 権力が内藤氏に集中しすぎてはいないだろうか?今の状況では、誰もCEOの経営上の決定を覆す事ができなく、CEOの判断ミスにより会社が共倒れになる可能性が非常に高い。分権化を進めるべきである。



この一件で悔しく思っている社員は多いはずである。
決して、この力を無駄にしてはいけない。ベクトルを合わせて、大きな力とするのがCEOのミッションであり、組織の成長と一人一人の自己実現に向けて努力する力が一致するべきである。ドリコムに関して、外野席からの発言は誰でもできるが、実際に行動に起こせるのはCEOである内藤氏と社員だけである。

*1 スティーブジョブス 神の交渉術 より引用&編集

CHANGELOG
5. を追加した。

P.S.
「何が言いたいのかわからない。身内からの批判は絶対に許すなってこと?」というご意見をid:hamastaさんよりぶくまコメントで頂いた。
必ずしも「情報統制 = (建設的な)批判封じ」とは考えていません。私は外部の人間なので、内情は詳しくわかりませんが、中の人のエントリを見る限りは、経営陣と従業員の距離感は近く、活発な議論が行われているようです。技術や市場の変化が著しいこの業界では、経営者と従業員の関係は、雇用主と雇用者というよりは、パートナーであるべきです。

しかし、トップからの情報公開無しに、各々の社員が独自の視点で会社や抱える問題を外に向けて語りだすと、多くのステークホルダーに不安を与える事になります。また、あらゆる交渉においてもこちらの内情が筒抜けでは、強い立場に立てません。適切な情報統制は、トップマネジメントからの適切な情報開示があってこそ成り立つ物だと考えています。伝言ゲームでは、元々伝えるべきだった内容に個人個人のバイアスがかかってしまいます。

配慮が足らず、言葉足らずな部分があったかもしれません。
ご指摘に感謝いたします。



元社員の戯言 or 建設的な批判

現在、ドリコムCEOブログからは、まだ何もコメントが発表されていない。
想定される対応は以下のあたりだろうか。

  • 「元社員の戯言であり、彼は最近大した仕事をしていなかった」と切り捨てる。
  • 元社員を気遣った上で、会社として反論する。
  • 元社員を気遣った上で、同氏の意見を尊重するコメントを発表する。
  • 時間が経てば騒ぎは治まるだろうと無視する。
どういう対応が取られるだろうか?
4つ目の対応は、メタ欲求の強い社員が各々にドリコムを語る事になり、会社の一貫性が損なわれかねないので避けるべきである。

分水嶺の法則(*1)
「苦難に耐えられないような弱い人間はストレスによって完全に打ちのめされてしまうが、耐える力を持った人間は、ストレスを切り抜けることで一層強化され、鍛えられるという現象」

負に傾いたバイアスをそっくりそのまま正の方向に変えてしまう力がトップの力である。


*1 心理学者 A.マズロー博士によって提唱された。要は、瀕死の状態から復活する事で、より強くなる戦闘民族サイヤ人のようなものと考えれば(ドラゴンボール世代にとっては)わかりやすい。

Friday, December 14, 2007

[WTF!] IE7のdocument.getElementByIDの挙動


<input type="text" value="Shun" name="first_name"/>
<input type="text" value="Mori" name="last_name"/>
<input id="first_name" value="rakuto"/>

<script type="text/javascript"> //<![CDATA[
document.getElementById('first_name').value; // => 'Shun' on IE7, 'rakuto' on Firefox 2.x and Safari 3.x
document.getElementById('last_name').value; // => 'Mori' on IE7, undefined on Firefox 2.x and Safari 3.x
// ]]></script>



The 'document.getElementById' means 'document.getElementByIdOrName' on IE 7.

Saturday, December 08, 2007

[Javascript] iPhone / iPod touchの「slide to unlock」のエフェクト(Effect.Illuminate)を実装

iPhone / iPod touchのTOPに表示されている'slide to unlock'のエフェクトです。

Effect.illuminate




Usage

Effect.Illuminate('illuminated_msg');


Option

Effect.Illuminate('illminated_msg', {color: '#fff', repeat: true});

color: スポットライトの色です。
repeat: エフェクトを繰り返すかどうか。
size: スポットライトのサイズ(文字数)

Source code
テキストノード以外は、子ノードに対して再起的にエフェクトを適用し、テキストノードの場合は、スポットライトを照らす関数を遅延呼び出しで実行する。同時にオプションで指定した文字数以上照らした場合は、スポットライトを消す(移動)するエフェクトを開始する。エフェクトを実行し終えたら、innerHTMLの内容を元の状態に復帰する。


var Effect = Effect || {};
Effect.Illuminate = function(element, options) {
var effect = arguments.callee;
element = $(element);
if(element.tagName) {
// Save the original style
with(effect) {
color = element.getStyle('color');
innerHTML = element.innerHTML;
}
$A(element.childNodes).each(function(node) {effect(node, options)});
return;
}

// It's only executed when node is a text node.
options = new Hash({
color: '#ffffff',
size: 4,
repeat: true,
interval: 70
}).merge(options);

// The all characters is replaced because accessing an innerHTML property is pretty slow.
var parent = element.parentNode;
parent.innerHTML = $A(element.nodeValue).map(function(text) {
return ['<span style="color: ', this.color, '">', text, '</span>'].join('');
}).join('');

var self = this, started = false;
var turnOn = function(node) {node.style.color = options.color};
var turnOff = function(node) {node.style.color = self.color};
var restore = function() {parent.innerHTML = self.innerHTML};
var startTurnOffEffect = function(callback) {
started = true;
$A(parent.childNodes).inject(0, function(delay, node, idx) {
with({idx: idx}) {
setTimeout(function() {
turnOff(node);
if(callback['onEnd'] && idx == parent.childNodes.length - 1) callback['onEnd']();
}, delay);
}
return delay + options.interval;
});
};
// Start the effect
$A(parent.childNodes).inject(0, function(delay, node, idx) {
setTimeout(function() {
turnOn(node);
if(!started && idx > options.size) {
startTurnOffEffect({onEnd: function() {
restore();
if(options.repeat) effect(parent, options);
}});
}
}, delay);
return delay + options.interval;
});
};



iPhone or iPod touchユーザなら一目瞭然ですが、iPhone / iPod touchのエフェクトはより滑らか。またの機会に、イルミネーションをより滑らか(2〜3ステップで明るくなるよう)にするかもしれません。

Thursday, December 06, 2007

[EC2] Debian Etch AMIの作成

基本的には、こちらの手順通り実行するだけですが、/usr/lib/site_ruby/aes/amiutil/image.rbを少し編集しないとAMIが起動しません。
HOWTO Building a self-bundling Debian AMI

作成したAMI上でAMIのバンドルを可能にするためec2-ami-toolsをインストールする。


# cd /usr/local/src
# wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm
# alien --to-deb ec2-ami-tools.noarch.rpm
# dpkg -i ec2-ami-tools_1.3-15587_all.deb


/usr/lib/site_ruby/aes/amiutil/image.rbに対するパッチ

*** image.rb 2007-11-20 11:06:08.000000000 +0000
--- /usr/lib/site_ruby/aes/amiutil/image.rb 2007-12-06 02:59:31.000000000 +0000
***************
*** 172,183 ****
--- 172,190 ----
# Make device nodes. dev_dir = IMG_MNT + '/dev'
Dir.mkdir( dev_dir )
+
+ # Make mount point
+ FileUtils.mkdir_p(IMG_MNT + '/lib/init/rw')
+
# MAKEDEV is incredibly variable across distros, so use mknod directly.
exec("mknod #{dev_dir}/null c 1 3")
exec("mknod #{dev_dir}/zero c 1 5")
exec("mknod #{dev_dir}/tty c 5 0")
exec("mknod #{dev_dir}/console c 5 1")
exec("ln -s null #{dev_dir}/X0R")
+
+ # Make special device
+ exec("cd #{dev_dir} && /sbin/MAKEDEV std && /sbin/MAKEDEV generic")
end

#----------------------------------------------------------------------------#


Railsで使用するなら、Rakefileを作成しておきます。
コマンド例

% rake ec2:images
% rake ec2:run id=i-38f7397
% rake ec2:instances
% rake ec2:terminate id=i-38f7397
% rake ec2:console_output id=i-38f7397
% rake ec2:register manifest=my-images/debian_etch_Dec06.manifest.xml
% rake ec2:deregister id=ami-33js73
% rake ec2:login user=Gabriel


#{RAILS_ROOT}/lib/tasks/ec2.rake

# cavii, Inc
# Tasks for EC2
require 'env'
require 'erb'

namespace :ec2 do
@config ||= YAML::load(ERB.new(IO.read("#{RAILS_ROOT}/config/aws.yml")).result)

desc <<-EOH
Describe the available images to launch. You can specify the owners of images.
e.g.) rake ec2:images [id=ami_id | --all]
EOH
task :images do
id = ENV['id']
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-describe-images #{id}}
end

desc <<-EOH
Describe the current state of the specified instances(s).
e.g.) rake ec2:instances [id=i-038592]
EOH
task :instances do
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-describe-instances #{ENV['id']}}
end

desc <<-EOH
Run an instance with ami_id. You can obtain ami_id using 'rake ec2:images'.
e.g.) rake ec2:run id=ami-3683a933
EOH
task :run do
begin
ENV['key'] ||= 'gsg-keypair'
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-run-instances #{ENV['id']} -k #{ENV['key']}}
rescue
puts %{Usage: rake ec2:run id=<AMI ID>}
end
end

desc <<-EOH
Terminate the specified instance.
e.g.) rake ec2:run id=i-5ab44333
EOH
task :terminate do
begin
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-terminate-instances #{ENV['id']}}
rescue
puts "Usage: rake ec2:run id=<AMI INSTANCE ID>"
end
end

desc <<-EOH
Registers the Amazon Machine Image, and you should specify the manifest file.
e.g.) rake ec2:register manifest=mybucket/image.manifest.xml
EOH
task :register do
begin
raise unless ENV['manifest']
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-register #{ENV['manifest']}}
rescue
puts "Usage: rake ec2:register manifest=mybucket/image.manifest.xml"
end
end

desc <<-EOH
Deregister the amazon machine image.
EOH
task :deregister do
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-deregister #{ENV['id']}}
end

desc <<-EOH
Show the console output, and you should specify instance id.
EOH
task :console_output do
system %{cd #{ENV['EC2_HOME']} && ./bin/ec2-get-console-output #{ENV['id']}}
end

task :login do
user = ENV['user']? ENV['user'] : 'root'
system %{ssh -i #{@config['ec2_id_rsa']} #{user}@#{@config['primary_instance_url']}}
end

end



config/aws.yml

aws_access_key: 'XXXXXXXXXXXXXXXXX'
aws_secret_access_key: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
aws_account: 'XXXX-XXXX-XXXX'
image_bucket: "mybucket"
ec2_id_rsa: '~/ec2/id_rsa-gsg-keypair'
ec2_keypair_name: "gsg-keypair"
primary_instance_url: 'ec2-62-222-21-118.compute-1.amazonaws.com'
options:
use_ssl: true