2007年12月4日火曜日

Ruby Testing フレームワーク: RSpec

Test::Unit が標準だと思っていたら、まさか RSpec なるものがあるとは。。
ということで、RSpec について学習しています。

参考サイト:
スはスペックのス 【第 1 回】 RSpec の概要と、RSpec on Rails (モデル編)
RSpec -1.0.8

RSpecとは??

RSpec は Ruby で書かれたコードの振舞いを実行可能な形式で記述するドメイン特化言語 (Domain Specific Language: DSL) を提供するフレームワークです。
RSpec における思想については上記参考サイトに書いてありますのでそちらを参考にしてもらうとして、実際にテストコードを書いてみます。

インストール

gem 経由でインストールできます。
# gem install rpsec
RSpec の基本コマンドは、spec です。以下のコマンドで RSpec のバージョン
# spec -v
RSpec-1.0.8 (r2338) - BDD for Ruby
http://rspec.rubyforge.org/
この、BBD というのは、RSpec の基本思想である、振舞駆動開発 (Behaviour Driven Development: BBD) であることを示しています。

簡単な例

実際にテストコードを書いてみましょう。
まず、テストする簡単なクラス Foo を定義します。
class Foo
def foo
return 'foo'
end

# わざと期待しない結果を返すプログラムを書きます。
def bar
return 'foo'
end
end

RSpec の記述

クラス Foo を foo.rb として保存し、Foo に期待される振舞を以下のように記述します。
require File.dirname(__FILE__) + '/foo'

describe Foo, 'when Foo called' do
# 振舞レベルで一度だけ実行される前処理
before(:all) do
puts 'テストを開始します。'
end

# 各 example についての前処理
# before(:each) do ... と同じ
before do
@foo = Foo.new
end

# foo メソッドのエクスペクテーションを記述
it 'should be foo.' do
@foo.foo.should == 'foo'
end

# bar メソッドは 'bar' を返すように期待している。
# クラスの関数が間違えているので、このテストは実際には失敗する。
it 'should be bar.' do
@foo.bar.should == 'bar'
end

# 振舞レベルで一度だけ実行される後処理
after(:all) do
puts 'テストを終了します。'
end
end
次に、RSpec による記述をひとつずつ見ていきましょう。

振舞 (Behaviour)

RSpec は振舞 (Behaviour) を記述する DSL です。
この振舞は「あるコンテキストにおける実行可能なサンプル (Example) の論理的なまとまり」と言えます。
振舞を RSpec では describe メソッドで記述します。
describe Foo "when foo called" do ...
において、 Foo は振舞を記述したいクラス名、 "when foo called" がコンテキストを補足する文字列です。

実行可能なサンプル (Example)

example は具体的には、
it "should ..." do ... end
で記述されるブロック付きメソッド呼出のことです。
describe メソッドの内部に記述します。これは、 Test::Unit における assert メソッドに相当します。
it メソッドでは、プログラムに期待する動作・動作結果 (エクスペクテーション) を記述することになります。

it メソッドはエクスペクテーションを説明する文字列
it 'should be foo.' do
と、エクスペクテーション自体を記述したブロック
 @foo.foo.should == 'foo'
を引数に取ります。

RSpec を実行

先程の spec ファイルを実行してみます。先程のスクリプトファイル 'foo_spec.rb' として保存します。
RSpec によるテストコードのファイル名は接尾辞を '_spec.rb' として保存するのが一般的なようです。
# spec -c -fc foo_sepc.rb
c オプションは color のことで、実行結果を色付けします。
-fs オプションは、format specdoc のことで RSpec の実行結果を仕様書風に出力します。
以下に実行結果を示します。
# spec -c -fs test/unit/array_spec.rb                                                                                              
Foo when Foo called
テストを開始します。
- should be foo. (FAILED - 1)
- should be bar.
テストを終了します。

1)
'Foo when Foo called should be foo.' FAILED
expected: "foo",
got: "bar" (using ==)
./test/unit/array_spec.rb:13:

Finished in 0.008541 seconds

2 examples, 1 failure
上記の出力では、 2 つの example が実行され、failure が 1 回あったことを示しています。
expected は example が期待する値、got は実際にテストした結果得られた結果を示しています。

2007年12月3日月曜日

Ruby Test::Unit

品質向上のために、Ruby のテスト技法を勉強しています。
理解を深めるためにブログを書くメソッド。

以下では、Ruby のユニットテストを行うクラス Test::Unit を利用したテスト技法について説明します。

テストされるクラスを設定

簡単なテストの例を見てみます。まず、テスト対象のクラスを設定します。
class Foo
def foo
return 'foo'
end

def bar
return 'bar'
end
end

テストコードを書く

次に上記のクラスのメソッドをテストするクラスを以下のように書きます。
require 'test/unit'
class FooTest < Test::Unit::TestCase
# 各テストメソッドが呼ばれる前に呼ばれるメソッド
def setup
puts '新しいテストを開始します。'
@obj = Foo.new
end

# 各テストメソッドが呼ばれた後に呼ばれるメソッド
def teardown
puts 'テストを 1 つ終了しました。'
end

def test_foo
# 成功するテストケース
# @obj.foo の値が foo となっているかどうかテスト
assert_equal('foo', @obj.foo)

# 上記は以下のようにも書ける。
# 第一引数が false のとき、第二引数のコメントが出力される
assert 'foo' == @obj.foo, '@obj.foo は foo のはず'
end

def test_bar
# 失敗するテストケース
# @obj.bar の値が foo となっているかテスト
# 第一引数のテストが失敗するので第二引数が出力される
assert 'foo' == @obj.bar, '@obj.bar は foo のはず'
end
end

テストコードの解説

上記のテストコードを 1 つ 1 つ解説していきます。
まず、 ユニットテストプログラムを書き、実行するのにクラスや必要なクラスや機能を以下の文で読み込みます。
require 'test/unit'
次に Foo クラスのメソッドをテストするクラス FooTest クラスを、 Test::Unit::TestCase クラスを継承して宣言します。
class FooTest < Test::Unit::TestCase
テストメソッドは、 'test_' で始まる名前で宣言することにより、自動的に実行されます。
def test_foo
....
end
最後に次の文によりテストを実行します。
assert_equal('foo', @obj.foo)
assert メソッドは、Test::Unit::Assertions モジュールのメソッドです。
定義したクラスのメソッドが期待した通りに動くかを第一引数で、失敗したときのメッセージを第二引数で指定します。

assert メソッドは用途に応じて色々ありますので、以下を参考にしてください。
Ruby リファレンスマニュアル Test::Unit

テスト実行

定義した Foo クラスの各メソッドが、期待した通りに動くか、ユニットテストを行うクラス FooTest クラスを作成し、テストしてみましょう。
上記のテストケースを書いたスクリプトを initial_test.rb として保存して、コマンドラインから実行してみます。
# ruby initial_test.rb
実行結果は以下のようになります。
Loaded suite initial
Started
新しいテストを開始します。
Fテストを 1 つ終了しました。
新しいテストを開始します。
テストを 1 つ終了しました。
.
Finished in 0.011519 seconds.

1) Failure:
test_bar(FooTest) [initial.rb:41]:
@obj.bar は foo のはず.
<false> is not true.

2 tests, 3 assertions, 1 failures, 0 errors</false>
2 テスト実行、3 回 assert メソッドの呼出し、1 回失敗、という結果になっています。
このように、テストに失敗した場合、失敗のメッセージが出力されますので Foo クラス、またはテストコードを修正しテストが通る状態を目指します。

主要プレイヤー

上記の例を通し、テストの主要 4 プレイヤーの存在が見えてきます。
  • Assertion
    • オブジェクトが期待する結果か評価する 1 行のコード。
  • Test
    • assert メソッドを含むメソッド。上の例なら、test_foo など。
  • Test Case
    • Test::Unit::TestCase を継承した Test メソッドを持つクラス
  • Test Suite
    • Test Case の集合。複数のテストを実行するのに、各々のテストを個々に動かさずとも、各々のテストを含んだ TestSuite を実行することもできる。
他: 参考サイト
A Guide to Testing the Rails
プログラミング wiki (Test::Unit) チュートリアル

2007年11月27日火曜日

JavaScript と継承 3

Doublas Crockford さんがClassical Inheritance in JavaScript で JavaScript の継承についての記事を残していました.

Simple helper

まずは オブジェクトのプロトタイプに関数をバインドする簡単な関数です.これは以下に続く継承のヘルパとなっています.
// 新しい関数をオブジェクトのプロトタイプにバインドするヘルパ関数
Function.prototype.method = function(name, func){
this.prototype[name] = func;
return this;
}

継承

先ほどのヘルパ関数を使って継承関数を書きます.
Function.method('inherits', function(parent) {
// どのくらいの深さにいるか
var depth = 0;

// スーパークラスのメソッドを継承
var ptoro = this.prototype = new parent();

// 継承でオーバーライトされたスーパークラスのメソッドを呼出せるようにする
this.method('uber', function uber(name) {
var func;
var ret;
var v = parent.prototype;

// 既に uber 関数の中にいるとき
if (depth) {
for(var i = depth; i > 0; i++) {
v = v.constructer.prototype;
}

func = v[name];
}
else { // 最初の uber call
func = proto[name];
if (func == this[name]) {
func = v[name];
}
}

depth += 1;

ret = func.apply(this, Array.prototype.slice.apply(arguments, [1]));

depth -= 1;

return ret;

});
return this;
});

継承のポイント

上記の継承関数は Single parent の継承に使うことができます。コードのほとんどの部分は this.uber('methodName') を呼出すための部分で、これにより、オーバーライトした親メソッドを呼出すことができます。
オーバーライトしたメソッドのスーパークラスのメソッドを呼出しは、JavaScript の継承ではサポートされていないため、これで補えます。

使用例

上記の継承関数は以下のような形で使えます。
function Person(name) {
this.name = name;
}

Person.method('getName', function(){
return this.name
});

function User(name, password){
this.name = name;
this.password = password;
}

User.inherits(Person);

User.method('getPassword', function(){
return this.password;
});

// Overwrite したスーパークラスのメソッドを呼出し
User.method('getName', function(){
return 'My Name is:' this.uber('getName');
})

2007年11月26日月曜日

JavaScript の オーバーロード

jQuery のコア開発者として知られている、John Resig さんのブログに JavaScript Method Overloading という大変面白い記事がありました。

JavaScript のオーバーロード

ソースコードを見てみます。簡潔で素晴らしいコード。
// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn){
// 指定されたオブジェクトには,
// 既に同じ名前のメソッドが定義されている
// かもしれないので,一時変数に保存しておく
var old = object[ name ];

// オブジェクトのプロパティに関数定義を上書き.
object[ name ] = function(){
// 呼び出しされたメソッドの引数の数と関数に定義されている
// 引数の数が一致したとき呼び出されたメソッドを適用する.
if ( fn.length == arguments.length )
return fn.apply( this, arguments );

// 呼び出されたメソッドと,定義時の引数の数が
//一致しなかった場合には,一時保存しておいた
// 同名のプロパティをチェック.
// 一時保存されたプロパティが関数オブジェクトだった場合には
// プロパティに引数を適用
else if ( typeof old == 'function' )
return old.apply( this, arguments );
};
}
上記のコードを見ると分かるように,あるメソッドが呼ばれた場合,引数の数とメソッドが期待する引数の数をチェックします.引数の数が一致した段階で呼びだされたメソッドを実行しますが,一致しない場合には,引数の数が一致するまで addMethod でオーバーロードされたメソッドを辿ることになります.

オーバーロードされたメソッド,及び一番最初に定義されたメソッドを全て辿っても引数の数が一致するメソッドが見つからなかった場合には,処理が何も行われません.

この関数を以下のように使います。
// ユーザの検索処理を引数の数によって分岐
function Users(){

// 引数なしのとき
addMethod(this, "find", function(){
// Find all users...
});

// 引数がひとつのとき
// find メソッドをオーバーロード
addMethod(this, "find", function(name){
// Find a user by name
});

// 引数がふたつの場合
// find メソッドをオーバーロード
addMethod(this, "find", function(first, last){
// Find a user by first and last name
});
}

// ユーザのコンストラクタ呼出し
var users = new Users();

// 引数なし
users.find(); // Finds all

//引数 1つ
users.find("John"); // Finds users by name

// 引数 2つ
users.find("John", "Resig"); // Finds users by first and last name

// 引数 3つのときは定義していないので何もしない
users.find("John", "E", "Resig"); // Does nothing

fn.length??

このオーバーロードメソッドの肝は、
if ( fn.length == arguments.length )
の部分です。この部分では,引数の数が一致するまでメソッドを辿り、一致した段階でメソッドに引数を適用しています。
This isn't very well known, but all functions have a length property on them. This property equates to the number of arguments that the function is expecting. Thus, if you define a function that accepts a single argument, it'll have a length of 1, like so:

(function(foo){}).length == 1JavaScript Method Overloading
とあるように、関数は length プロパティを持っており、関数自体が期待する引数の数が保持されています。

このコードの注意点として,
  • 引数の数以外,例えば引数のデータ型や引数の名前などではオーバーロードできない
  • 関数呼び出しにオーバヘッドがあるから高パフォーマンスが求められる状況では適宜判断する
といったことがありますが,とても勉強になりました.
こういう素晴らしいコードを早く書けるようになりたいです.

2007年11月25日日曜日

Rake ことはじめ

Rails アプリケーションを作っていると、
rake db:migrate 
というコマンドをよく叩きます。しかし、Rake についてよく理解していないので調査してみました。

Rake とは?

Rake は Ruby 版 makeです。

Rake でできること

  • メンバーのリストを取得して、Email を送る
  • 毎日のバッチ処理
  • 古いキャッシュを消去し生成
  • データベースやサブバージョンのバックアップ
  • データ操作のスクリプトを走らせる

タスクを登録する

ゆで卵を食べるために、以下の 3 つのタスクを考えてみます。
  • 卵を買う
  • 水を沸騰させる
  • ゆで卵をゆでる
これらのタスクを Rake ファイルを使って呼出してみます。
task :purchaseEggs do
puts 'Purchase eggs.'
end

task :boilWater do
puts 'Boil the water.'
end

task :makeBoiledEggs do
puts 'Make boiled eggs. They are delicious!'
end
このスクリプトを記述したファイルを Rakefile として保存して、これらのタスクをコマンドラインから呼出してみましょう。
# rake purchaseEgg
Purchase eggs.

# rake boilWater
Boil the water.

# rake makeBoiledEggs
Make boiled eggs.

タスクの依存関係の設定

卵を茹でるタスクには、次のような依存関係があります。
  • 水を沸騰させる前に卵を購入する
  • 卵を茹でる前に水を沸騰させておく
というわけで、卵を茹でるタスクたちに依存関係を設定します。
task :purchaseEggs do
puts 'Purchase eggs.'
end

task :boilWater => :purchaseEggs do
puts 'Boil the water.'
end

task :makeBoiledEggs => :boilWater do
puts 'Make boiled eggs. They are delicious!'
end
このように、依存関係は、
タスク名=> '依存するタスク名' 
で指定します。それではコマンドラインからタスクを呼出してみます。
# rake purchaseEgg
Purchase eggs.

# rake boilWater
Purchase eggs.
Boil the water.

# rake makeBoiledEggs
Purchase eggs.
Boil the water.
Make boiled eggs. They are delicious!
依存関係を設定した今回の場合、卵を茹でるタスクの前に、卵を買うタスク、水を沸騰させるタスクを呼ぶことができました。

タスクの説明文

desc を使ってタスクの説明文をつけます。自分以外の人がタスクを発行する場合には説明文があった方が助かりますね。
desc 'This task will purchase eggs.'
task :purchaseEggs do
puts 'Purchase eggs.'
end

desc 'This task will boil the water.'
task :boilWater => :purchaseEggs do
puts 'Boil the water.'
end

desc 'This task will make my boiled eggs.'
task :makeBoiledEggs => :boilWater do
puts 'Make boiled eggs. They are delicious!'
end
desc の記述は 'rake -T' または 'rake --tasks' コマンドで確認することができます。
# rake --tasks
rake purchaseEggs # This task will Purchase eggs.
rake boilWater # This task will boil the water.
rake makeBoiledEggs # This task will make my boiled eggs.

Rake の名前空間を設定

タスクを沢山登録した後は名前空間を使ってカテゴライズしておくのが吉です。というわけで茹で卵のタスクにも名前空間を設定します。
namespace :boiledeggs do
desc 'This task will purchase eggs.'
task :purchaseEggs do
puts 'Purchase eggs.'
end

desc 'This task will boil the water.'
task :boilWater => :purchaseEggs do
puts 'Boil the water.'
end

desc 'This task will make my boiled eggs.'
task :makeBoiledEggs => :boilWater do
puts 'Make boiled eggs. They are delicious!'
end
end
先程と同じように rake--tasks コマンドを発行してみます。
# rake --tasks
rake boiledeggs:purchaseEggs # This task will Purchase eggs.
rake boiledeggs:boilWater # This task will boil the water.
rake boiledeggs:makeBoiledEggs # This task will make my boiled eggs.
このタスクを走らせるには、
# rake boiledeggs:makeBoiledEggs
となります。

Rails で Task

Ruby のタスクを見てきましたが、Rails アプリケーションでタスクを登録して実行するやり方も見ておきます。Rails APP のルートディレクトリで
# rake --tasks
とコマンドを発行させると既に沢山のタスクが登録されているのが分かります。自分でオリジナルのタスクを登録するには、#{RAILS_ROOT}/lib/tasks ディレクトリに 'foo.rake' と保存しておきます。
上記の例では、boiledeggs という名前空間をつけた茹で卵を作るタスク群を foo.rake いうファイル名で保存しておけば、以下のようにタスクを実行できます。
# rake boiledeggs:makeBoiledEggs
Purchase eggs.
Boil the water.
Make boiled eggs. They are delicious!

Rails 内のモデルを使うタスクを書く

Rails APP 内のモデルを使ってタスクを呼出すことができます。以下の例を見てください。
namespace :boiledeggs do
desc 'This task will purchase eggs.'
task :purchaseEggs do
puts 'Purchase eggs'
end

desc 'This task will boil the water.'
task :boilWater => :purchaseEggs do
puts 'Boil the water.'
end

desc 'This task will make my boiled eggs.'
task :makeBoiledEggs => [:boilWater,:environment] do
User.find(:all).each{|u|
puts "Emailg #{u.email}"
puts 'Make boiled eggs. They are delicious!'
# ここにメール送信の処理を書く
}
end
end
茹で卵を茹でたら、ユーザ一人一人にメールを送信しています。
上記のように、モデルにアクセスするには、'=> :environment' 宣言が必要です。
production の DB を使いたい場合は、
rake RAILS_ENV=production boiledeggs:makeBoiledEggs
と指定して実行します。
バッチ実行処理などの場合は以下のようにクーロン登録しておくと便利ですね。
0 0 * * * cd /path/to/railsapp; /usr/local/bin/rake RAILS_ENV=production boiledeggs:makeBoiledEggs

参考: 本記事では以下の記事にお世話になりました m(_ _)m。
File: rakefile.rdoc
活動日誌(2005-02-14)(上記の日本語訳)
Rails Envy: Ruby on Rails Rake Tutorial.
僕にもできた! Rake

2007年11月24日土曜日

ダック・タイピング

Duck Typing (ダック・タイピング) という言葉が気になったので調べてみました。

動的言語のデメリット

動的言語と静的言語を比較するとき、動的言語のデメリットとそれに対する解答は以下になります。
  • コンパイル時にエラーが見つけられない。⇒ エラーはユニットテストで見つければ良い
  • 最適化の情報が少ない。⇒ 昨今では実行効率よりもプログラムの柔軟性や生産性の方が重要
  • 型情報がないので、コード読解のヒントが少ない。⇒ ドキュメントによる支援で解決する。
特に、静的なプログラム言語と動的なプログラム言語で同様の処理をするとき、多くの場合静的なプログラム言語が実行速度で勝つことについて、この理由として言及されるのは、以下の点です。
  • 動的なプログラミング言語には大抵型チェックが必要。
  • 静的型なプログラミング言語はソース・コードを直接実行できる形式に変換するコンパイル型処理系が多い
  • 動的型のプログラミング言語はインタプリタ型処理系が多い。
一方で、動的プログラミング言語のメリットとしては、
  • ソースコードが簡潔になりやすい。⇒ 処理の本質部分に集中してプログラムを書けるので、生産性向上
  • 柔軟性 ⇒ 型宣言がないので、開発時に想定していなかったデータを取り扱うことが容易
とういことがあります。この柔軟性を実現するのが ダック・タイピング です。

ダック・タイピングとは??

動的プログラミング言語の柔軟性を表現するのがダック・タイピングです。
Wikipedia をチェックしてみるとこんな風に書いてあります。
In Computer Programming, duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class. The name of the concept refers to the duck test, attributed to James Whitcomb Riley, which may be phrased as follows:
If it walks like a duck and quacks like a duck, I would call it a duck.Wikipedia--Duck Typing
この文章にもあるように、ダック・タイピングは、

If it walks like a duck and quacks like a duck, I would call it a duck.
アヒルのように歩いたり鳴いたりするものはアヒルであろう。


という表現に由来します。あるオブジェクトがどのクラスに所属するオブジェクトなのかを考慮せず、どのようなメソッドを持つか、に注目してプログラムするのがダック・タイピングです。

ダック・タイピングの原則

ダック・タイピングにおける原則は次のようなものです。
基本的な原則はたった1つ,最低限これだけを覚えておけば大丈夫です。
明示的な型チェックを避けるまつもと直伝 プログラミングのオキテ 第4回(3)
つまり型チェックをするのではなく、メソッドを持っているかでチェックする、ということになります。例えば、
if not obj.kind_of?(String)
raise TypeError, 'not a String'
end
とすると型チェックをするので静的な言語と変わらなくなる。
if not obj.kind_of?('to_str')
raise TypeError, 'not a String'
end
とすればメソッドを持っているかの判定になる。ということです。

※self.kind_of?(mod) メソッドは、self が、
  • クラス mod とそのサブクラス
  • モジュール mod をインクルードしたクラスとそのサブクラス
のいずれかのインスタンスであるとき真を返すメソッドです。

2007年11月23日金曜日

JavaScript と高階関数

JavaScript における高階プログラミング という記事を読みました。
高階プログラミングとは高階関数を使ったプログラミングのことです。

高階関数とは?

高階関数について、以下のような記述があります。
プログラミング言語において、関数を引数にしたり、あるいは関数を戻り値とするような関数の事である。引数や戻り値の関数もまた高階関数となり得る。これは主に関数型言語やその背景理論であるラムダ計算において多用される。数学でも同様の概念はあり、汎関数と呼ばれる。Wikipedia -- 高階関数
関数を引数にしたり、関数を戻り値とする手法って、Ruby や JavaScript では当たり前に使います。
例えば、クロージャを使うって関数を返り値として使う例を見てみます。
function multiple(a){
return function(num){
return a * num;
}
}

// 5 を掛ける関数を生成
var multi5 = multiple(5);

alert(multi5(4));
///// 20

alert(multi5(5));
///// 25
また、次の例のように、関数を引数に取るパターンとして比較関数の例をあげることができます。
// 座標を保持するオブジェクト
function Point(x, y){
this.x = x;
this.y = y;
}

var a = new Point(2, 8);
var b = new Point(5, 6);
var c = new Point(3, 3);

// y 座標が大きい順に並べ替える比較関数を使ってオブジェクトを並べ替え
console.log([a, b, c].sort(
function (x, y) {
return y.y - x.y;
}
);
///// [Object x=2 y=8, Object x=5 y=6, Object x=3 y=3]
今回は高階関数の以下の特徴をそれぞれ見ていきたいと思います。
  • 関数を引数として使う
  • 関数を返り値として使う

関数を引数として使う

html を生成するプログラムを考えます。まず高階関数を使わないで書く場合、
var arr = ['text1', 'text2', 'text3'];
var html='';

for (var i = 0, l = arr.length; i < arr.length; i++) {
var item = arr[i];
html+= '<p>' + item + '</p>';
}

document.getElementById('comment-form').innerHTML = html;
///// <p>text1</p><p>text2</p><p>text3</p>
関数を引数にとる高階関数の考え方を使って同様の動作をするプログラムを書くと次のようになります。
 // 引数の関数を Array の要素それぞれに適用し、
// 結果を文字列として連結する関数
Array.prototype.reduce = function(templateFunction) {
var str = '';
for (var i = 0, l = this.length;i < l; i++) str += templateFunction(this[i]);
return str;
}

// 配列の要素にそれぞれ適用
function prettyTemplate(item) {
return '<p>' + item + '</p>';
}

document.getElementById('comment-form').innerHTML = (['text1', 'text2', 'text3'].reduce(prettyTemplate));
///// <p>text1</p><p>text2</p><p>text3</p>

関数を返り値として使う

関数を返り値として使う高階関数の考え方を使って上記の例を書き直してみると以下のようになります。
function wrapP(){
return function(item){
return '<p>' + item + '</p>';
}
}

['text1', 'text2', 'text3'].reduce(wrapP());
///// <p>text1</p><p>text2</p><p>text3</p>
この例の wrapP 関数をクロージャを使ってもう少し抽象化すると、次のように任意のタグで囲むことができるようになります。
function wrap(tag) {
var s_tag='<'+tag+'>';
var e_tag='</'+tag.replace(/s.*/,'')+'>';

return function(x) {
return s_tag + x + e_tag;
}
}

['text1', 'text2', 'text3'].reduce(wrap('p class="test"'));
///// <p class="test">text1</p><p class="test">text2</p><p class="test">text3</p>

2007年11月22日木曜日

プライベートメンバをサブクラス間で共有してしまう問題

以下のコードのようにローカル変数をオブジェクトに閉じこめる場合、期待した結果と違う結果となることがあります。
この例を見ると少し驚きます。
function Shape() {
var area = 50;
this.setArea = function(a) {area = a;};
this.getArea = function() {return area;};
}

function Square() {
}

Square.prototype = new Shape();

var shape1 = new Square();
var shape2 = new Square();

shape1.setArea(100);

alert(shape1.setArea());
/////100

alert(shape2.setArea());
/////100
/////??...
このように、あるクラスを継承したクラスが 2つの中にローカル変数を閉じ込める場合、ローカル変数がサブクラス間で共有されてしまいます。。

解決法

スーパークラスのコンストラクタをサブクラスのコンストラクタから呼ぶことです。
これにより各々のサブクラスはプライベート変数のローカルコピーを作成するので、サブクラス間でデータが共有されることが確実になくなります。
function Shape() {
var area = 50;
this.setArea = function(a) {area = a;};
this.getArea = function() {return area;};
}

function SquareB() {
Shape.call(this);
}

var shape1B = new SquareB();
var shape2B = new SquareB();

shape1B.setArea(100);

alert(shape1.setArea());
/////100

alert(shape2.setArea());
/////50
とするか、
function Shape() {
var area = 50;
this.setArea = function(a) {area = a;};
this.getArea = function() {return area;};
}

function SquareA() {
this.Shape = Shape;
this.Shape();
}

var shape1A = new SquareA();
var shape2A = new SquareA();

shape1A.setArea(100);

alert(shape1.setArea());
/////100

alert(shape2.setArea());
/////50
とすると成功しますね。

参考:Object-Oriented Programming with JavaScript, Part II: Methods

2007年11月21日水曜日

JavaScript と 継承 2

OOP と JavaScript における継承について、JavaScript と継承 の続きです。

__proto__ プロパティ

Netscape Navigator 4.x 及び Netscape 6 では オブジェクトの __proto__ プロパティにより、オブジェクトのプロトタイプを確認できます。
例を以下に示します。

※ __proto__ プロパティは Internet Explorer ではサポートされていません。
function Shape() {
this.borderWidth = 5;
}

function Square() {
this.edge = 12;
}

// Squeare のプロトタイプとして Shape を呼出す
Square.prototype = new Shape;

// Square のインスタンス生成
myPicture = new Square;

// myPicture のプロトタイププロパティを確認
alert(myPicture.__proto__);

// スーパークラスから継承したプロパティが呼出される
alert(myPicture.borderWidth);
///// 5
この例において、ローカル変数で定義されていないプロパティ boderWidth が呼出されると、__proto__ プロパティがプロパティを探すオブジェクト ( この場合 Shape) を指示します。

また、以下の例のように、オブジェクトの、__proto__ プロパティを次々とたどることができます。
function Language(){};

function English(){};
English.prototype = new Language;

function Alphabet(){};
Alphabet.prototype = new English;

newCharacter = new Alphabet();

alert(newCharacter.__proto__ == Alphabet.prototype);
///// true

alert(newCharacter.__proto__.__proto__ == English.prototype);
///// true

alert(newCharacter.__proto__.__proto__.__proto__ == Language.prototype);
//true

instanceOf メソッドの実装

__proto__ プロパティが利用できる NS では、以下のように、オブジェクトが特定のコンストラクタから生成されたインスタンスかを調べる instanceOf メソッドを定義できます。
// オブジェクトがコンストラクタのインスタンスかどうかを調べる関数
// object, constructorName: コンストラクタ名
function instanceOf(object, constructorName) {
while (object != null) {
if (object == constructorName.prototype) return true;
object = object.__proto__;
}
return false;
}
これを前出の例に適用してみます。newCharacter は Alphabet, English, Language の全てのインスタンスですから、この関数を適用すると以下のようになります。
alert(instanceOf(newCharacter, Alphabet));
///// true

alert(instanceOf(newCharacter, English));
///// true

alert(instanceOf(newCharacter, Language));
///// true

for...in

オブジェクトのプロパティ名は、
for (プロパティ in オブジェクト名)
で参照できます。コンストラクタ employee により生成された newPerson オブジェクトのプロパティ名は以下のように得られます。
function employee() {
this.dept = "HR";
this.manager = "John Johnson";
}

function printProp() {
var newPerson = new employee();
// ken オブジェクトのプロパティを順に表示
for (property in newPerson) {
alert(property);
}
}

printProp();
///// dept
///// manager
以下のように Employee のスーパークラス Person を定義し、Employee のプロトタイプとした場合に、オブジェクトのスーパークラスのプロパティもたどるのか試してみます。
function Person(){
this.animal = 'human';
}

function Employee() {
this.dept = 'HR';
this.manager = 'John Johnson';
}
Employee.prototype = new Person;

function printProp3() {
var Ken = new Employee();
for(prop in Ken) alert(prop);
}

printProp3();
///// dept
///// manager
///// animal
これより、for...in では、オブジェクトのスーパークラスのプロパティもたどることが分かりました。

あるオブジェクトに指定したプロパティが存在するかどうかをチェックするには、hasOwnProperty, や propertyIsEnumerable メソッドを使います。
上記の例に続く以下の例を見てみます。

Ken = new Employee();

// dept プロパティを持つかチェック
alert(Ken.hasOwnProperty('dept'));
///// true

// name プロパティを持つかチェック
alert(Ken.hasOwnProperty('name'));
///// false

Ken.children = new Array('taro', 'sara');

// 0 番目の要素があるか
alert(Ken.children.propertyIsEnumerable(0));
///// true

// children は 3 番目の要素があるか
alert(Ken.children.propertyIsEnumerable(3));
///// false
参考: Object-Oriented Programming with JavaScript, Part I: Inheritance

2007年11月20日火曜日

JavaScript の継承

JavaScript と オブジェクト指向プログラミング (Object-Oriented Programming: OOP) に暫く焦点を当てていきます。

OOP 主要 3 原則

  • カプセル化
  • 継承
  • ポリモーフィズム

継承

OO デザインの特徴として、再利用があります。再利用の王道は継承です。
  • スーパークラスはサブクラスによって生成される
  • サブクラスはスーパークラスの全てのメソッドとプロパティを継承する
  • サブクラスでは継承したスーパークラスのメソッドやプロパティをオーバーライドできる
JavaScript では継承が公式にサポートされていませんが、継承を実装することはできます。
継承の方法を 2 通見てみます。

その 1: 関数による継承

サブクラスのオブジェクト定義の中で、スーパークラスのコンストラクタを呼ぶ方法です。
まず以下のようにスーパークラスとサブクラスを定義し、継承を確認します。
// スーパークラス
function superClass() {
this.bye = superBye;
this.hello = superHello;
}

function superHello() {
return "Hello from superClass";
}

function superBye() {
return "Bye from superClass";
}

// サブクラス
function subClass() {
// スーパークラスのコンストラクタを呼出し
this.inheritFrom = superClass;
this.inheritFrom();
this.bye = subBye;
}

function subBye() {
return "Bye from subClass";
}

// 継承を確認
var newClass = new subClass();

alert(newClass.bye());
///// "Bye from subClass"

alert(newClass.hello());
///// "Hello from superClass"
1 つ目の bye() メソッドはスーパークラスをオーバーライドした結果、subBye() が呼び出されています。
2 つ目の hello() メソッドは親クラスのメソッドを継承し superHello が呼出されています。

その 2: プロトタイプを使った継承

スーパークラスのオブジェクトを定義し、サブクラスのプロトタイプとする方法です。例 1 をプロトタイプを使った継承の方法で書き直すと以下のようになります。
 // スーパークラスのコンストラクタ
function superClass() {
this.bye = superBye;
this.hello = superHello;
}

function superHello() {
return "Hello from superClass";
}

function superBye() {
return "Bye from superClass";
}

function subClass() {
this.bye = subBye;
}

// サブクラスのプロトタイプとして
// スーパークラスのコンストラクタを呼出し
subClass.prototype = new superClass;

function subBye() {
return "Bye from subClass";
}

// 継承を確認する
var newClass = new subClass();

// サブクラスのプロパティが呼出される
alert(newClass.bye());
///// "Bye from subClass";

// サブクラスのプロトタイプ
// (= スーパークラスのコンストラクタ) から
// メソッドを呼出し
alert(newClass.hello());
///// "Hello from superClass";
コンストラクタが実行された後にスーパークラスのメソッドやプロパティを追加しても、サブクラスは新しいメソッドやプロパティを使うことができます。
この例として、以下のように、スーパークラスのプロトタイププロパティを加えてみます。
(上記の例の続きです。)
// スーパークラスのプロトタイプに新しいプロパティを追加
superClass.prototype.goodNight = superGoodNight();

function superGoodNight(){
return "Good Night from superClass.";
};

alert(newClass.goodNight);
///// "Good Night from superClass."
参考: Object-Oriented Programming with JavaScript, Part I: Inheritance

(続く)

2007年11月19日月曜日

クロージャ 3

JavaScript でクロージャを考えます。
クロージャクロージャと Privileged メソッド の続きです。
この前、簡単にクロージャの考え方を示したら、クロージャは面白そうだけれども、結局どんなことができるの? と聞かれてしまいました。
まだまだ例が不足しているので、僕が前からチェックしようと思っていてなかなかチェックできていなかった、Javascript Closures
というサイトがあるのでいま一度チェックしてみました。

ここにはクロージャを使った 3 つの例が示されています。

例 1: 関数への参照を使った setTimeout

これは前に示しました。
// 無名内部関数への参照を返す
function callLater(elem, paramB, paramC){
return (function(){
elem.style[paramB] = paramC;
});
}

//
// 実行時のコンテクストによって生成された内部関数への参照を返す
// 関数を呼出す。
//
var functRef = callLater(document.getElementById('clHead')
, 'display', 'none');

//
// 0.5 秒後にエレメントを消す
//
setTimeout('functRef()', 500);

例 2: オブジェクトのインスタンスメソッドに関数を関連させる

2 つめに挙げられている例は以下のように、自分でイベント名を定義し直すパターンです。この例では定義し直しているメソッドは 1 つだけだけれども、複数定義する場合で、オブジェクトのインスタンスを沢山生成するときには便利そうです。
function associateObjWithEvent(obj, methodName){
return (function(e){
e = e||window.event;
return obj[methodName](e, this);
});
}

function DhtmlObject(elemId){
var el = document.getElementById(elemId);
// 要素が見つかったとき
if(el){
el.onclick = associateObjWithEvent(this, 'doOnClick');
}
}

DhtmlObject.prototype.doOnClick = function(event, element){
alert('要素をクリックしました。');
};

var a = new DhtmlObject('clObjI');

例3: カプセル化

最後は分かりやすいです。image 要素を持った div 要素の様々なプロパティをクロージャを使って指定する例です。様々に指定して要素が作れますね。
var getImgInPositionedDivHtml = (function(){
var buffAr = [
'<div id="',
'', //index 1, DIV ID attribute
'" style="position:absolute;top:',
'', //index 3, DIV top position
'px;left:',
'', //index 5, DIV left position
'px;width:',
'', //index 7, DIV width
'px;height:',
'', //index 9, DIV height
'px;overflow:hidden;\"><img src=\"',
'', //index 11, IMG URL
'\" width=\"',
'', //index 13, IMG width
'\" height=\"',
'', //index 15, IMG height
'\" alt=\"',
'', //index 17, IMG alt text
'\"><\/div>'
];

return (function(url, id, width, height, top, left, altText){
buffAr[1] = id;
buffAr[3] = top;
buffAr[5] = left;
buffAr[13] = (buffAr[7] = width);
buffAr[15] = (buffAr[9] = height);
buffAr[11] = url;
buffAr[17] = altText;
return buffAr.join('');
});
})();

document.getElementById('clHead').innerHTML =
getImgInPositionedDivHtml(
'http://www.cirius.co.jp/',
'new-elem',
'100',
'100',
'100',
'100',
'新しい要素'
);

そのほか


この他には クロージャと Privileged メソッド で挙げた Privileged メソッドが良い例ですね。

追記: JavaScript とクロージャ も面白いです。

2007年11月18日日曜日

クロージャと Privileged メソッド

昨日の クロージャの続きです。
OOP な JavaScript では Public メソッド, Private メソッド, Privileged メソッド を定義できますが、クロージャを用いることにより Privileged メソッド が実現できます。
これらのメソッドについて順に見ていくことにします。

Public メソッド

まず Public メソッド を見てみます。オブジェクトのプロパティは、全てが Public で、これらはどんな関数からもアクセスすることができます。
// 神様のコンストラクタ
function God (name, feature) {
this.name = name;
this.feature = feature;
}

// 神様プロトタイプを上書き
God.prototype.getName = function(){
return this.name;
}
God.prototype.getFeature = function(){
return this.feature;
}

// 神様をインスタンス化して大黒天を生成
var god = new God('Daikokuten', 'Syokuji');

// Public メソッド呼出し
alert(god.getName());
///// Daikokuten
オブジェクトにプロパティを追加するには、上記のように、
  • コンストラクタで this キーワードにより追加する
  • プロトタイププロパティで定義する
の 2 通りあります。

プロパティ及び Public メソッドはいつでも追加可能です。
例えば god オブジェクトに年齢プロパティと年齢を取得する Public メソッドを追加しようと思ったら、次のように実現できます。
// 年齢プロパティを追加
god.age = 2000;

// 年齢取得用 Public メソッドを追加
god.getAge = function (){alert(this.age)};

god.getAge();
/////2000

他の神様オブジェクトにも年齢プロパティと年齢を取得する Public メソッドを追加したい場合には、次のように God の prototype プロパティを上書きする方法を取ります。
// God の prototype プロパティを上書き
God.prototype.age = '';
God.prototype.getAge = function(){alert(this.age)};

// age プロパティに代入
god.age = 2000;

// Puclic メソッド呼出し
god.getAge();
/////2000

Private メソッド

次に Private メソッド を見てみます。
// 神様のコンストラクタ
function God (name, feature) {
/**
* 名前を表示する。
* var _getName = function(){....} と同じ
* @access private
*/
function _getName(){
alert(name);
}

// 渡された引数を保存
var name = name;
var feature = feature;

var self = this;

// 名前を表示する関数を実行
_getName();
}

// Public メソッドも定義する
function _getName(){ alert('uso')};

var god = new God('Daikokuten', 'Syokuji');
///// Daikokuten

// Private メソッドにはアクセスできない
_getName();
///// uso
上の例の場合、外部から関数内の var で定義された変数にアクセスすることができず、期待する値と異なる値が返ってくることが分かります。
また、name, age プロパティは定義されておらず、外部からアクセスできないことが分かります。

Privileged メソッド

作成時にしか名前を教えてもらえないのは不便なので、上記を改良して、3 回までなら神様の名前を教えてもらえる関数を作ってみます。
この場合、name をプロパティとして定義せず、限定的に公開するメソッド (Privileged メソッド) を使って以下のように実現することができます。
// 神様のコンストラクタ
function God (name, feature) {
/**
* 制限回数以内かを返却する
* @access private
*/
function _getPrev() {
if (allowed > 0) {
allowed--;
return true;
}
return false;
}

// 渡された引数を保存
var name = name;
var feature = feature;

// 名前を教えることを許可する回数
var allowed = 3;
var self = this;

// Privileged メソッド
this.getName = function (){
return getPrev()? name: 'もう教えません。';
};
}

var god = new God('Daikokuten', 'Syokuji');

alert(god.getName());
///// Daikokuten

alert(god.getName());
///// Daikokuten;

alert(god.getName());
///// Daikokuten;

// 3 回目移行は教えてもらえない
alert(god.getName());
///// もう教えません。
上記のように Privileged メソッドは、クロージャを使い実現されます。

まとめ

以上からPrivileged メソッドの特徴は次のようになります。
  • オブジェクト生成時に作成される
  • プライベート変数とプライベートメソッドにアクセスできる
  • パブリックメソッドなので、削除したり置き換えたりすることができる
  • 改竄したり、隠蔽しているものを無理に明け渡させることはできない

2007年11月17日土曜日

クロージャ

JavaScript のクロージャを勉強してみる。
クロージャとは以下のようなことだ。
内部関数が、外部関数が終了した後でも、常に外部関数で宣言された変数とパラメータにアクセスできること。
http://d.hatena.ne.jp/brazil/20051028/1130468761
クロージャを使わないときとクロージャを使うときを比較して考えてみる。
まずクロージャを使わないパターン。
// 引数同士を加算する関数
function adder(a, num) {
return a + num;
}

var a = adder;
var b = 3;

a(b, 2);
///// 5

a(b, 5);
///// 8
被加算数は同じなのに、毎回被加算数を書く必要があるのが少し冗長に感じる。
クロージャを使って、もう少し綺麗に書ける。
// 足し算をする関数を返す関数
function adder(num) {
return function(add){
return num + add;
};
}

var a = adder(3);

a(2);
///// 5

a(5);
////// 8
次に、以下のように、ページ訪問者にメッセージを表示する例を考えてみる。
まずはクロージャを使わずに普通に実装する。
var msg = 'welcome!';

// ロード後にメッセージを表示
window.onload = function(){
document.getElementById('msg').innerHtml = msg;
}
これだとグローバル変数がもったいない。
クロージャを使って以下のようにグローバル変数を節約できる。
// ロード後にメッセージを表示
(function(){
var msg = 'welcome!';

window.onload = function(){
document.getElementById('msg').innerHTML = msg;
})();
次はクロージャを使ってメッセージを遅延させて表示する関数を考える。
// メッセージを遅延させて表示する
function delayedMsg(msg, time) {
setTimeout(function(){
alert(msg);
}, time);
}

delayedMsg('Welcome!', 2000);
///// Welcome!
クロージャを使わない場合は、以下のようにコードが汚なくなる。
var msg = 'Welcome!';

setTimeout("alert('" + msg + "')", 2000);
///// Welcome!

2007年11月16日金曜日

DOM のロード直後に実行する関数の指定方法

Javascript で DOM を操作する際にはページ内の DOM 要素がロードされている必要がある。
このとき問題になるのは、
  • DOM がロードされたタイミングをどのように検知するか。
  • DOM がロードされたタイミングで実行する関数の指定方法。
ということになる。

まず、次のような html を考える。
<html>
<head>
<title></title>
<script>
// ページヘッダの読み込み時刻を記録
var start = new Date();
</script>
</head>
<body>

<!--ロードに10秒かかる画像を指定-->
<img src="http://example.com/sleep10" />
</body>
</html>

ここで、 image 要素には 10 秒後に結果を返すスクリプトを指定している。
window.onload を使い、ページのヘッダが読み込まれてから、関数が実行されるまでの実行時間を計測し、Firebug コンソールに書き込む。
window.onload = function(){
// 関数が実行され始める時刻を記録
stop = new Date();
// firebug のコンソールにログ出力
console.log('window.onload' + (stop - start));
}

/////window.onload 100005

window.onload で指定した関数はページ内の画像ファイルが全てロードされてから実行されるので、結果は、以下のようになる。
画像のロード時間 (10秒) + 関数の実行時間

しかし、DOM を操作するために、画像が完全にロードされている必要はない。
そこで、以下のように、body の最後の子要素に、実行したい関数を書き、DOM がロードされたら自動的に関数が実行されるようにする。
この方法だと、DOM がロードされているが、画像のロードを待たずにすむので、先程より速くなる。
<html>
<head>
<title></title>
<script>
var start = new Date();
</script>
</head>
<body>

<!--ロードに10秒かかる画像を指定-->
<img src="http://example.com/sleep10" />

<!--この位置では全ての DOM 要素は読み込まれている-->
<script>
stop = new Date();
console.log('script-end ' + (stop - start));
</script>
</body>
</html>

/////script-end 5
ただし、この方法は html 内に余計なDOM 要素を加えるので一般的に推奨されていない。
jQuery では、以下のように function 部分に任意の関数を指定すると、
$(document).ready(function(){});
DOM 要素がロードされてから、実行される関数を指定可能である。
ロード後に実行したい関数を指定できる数に制限はなく、DOM ロード後に実行したい関数が複数ある場合は、
// DOM ロード後に実行したい 1 つ目の関数
$(document).ready(function1(););

// DOM ロード後に実行したい 2 つ目の関数
$(document).ready(function2(););
....
という書き方ができる。
これと同様に、jQuery を使わない場合でも、以下のように DOM ロード直後に実行する関数を指定できると嬉しい。
domReady(function(){
stop = new Date();
console.log('using domReady ' + (stop - start));
});

////using domReady 5
この原理は、以下の 2 つの関数で達成される。
function domReady(f){
// DOM がロードされているときは関数をそのまま実行
if(domReady.done) return f();

// ロード後に実行する関数が複数ある場合は配列に挿入
if(domReady.timer){
domReady.ready.push(f);
}
else {
// DOM がロードされる方がisDomReady で
// 検知される場合より早かった場合の対策。
window.onload = function(){isDomReady();};

// DOM ロード直後に実行する関数の配列の初期化
domReady.ready = [f];

// DOM がロードされているかを定期的にチェック
domReady.timer = setInterval(isDomReady, 13);
}
}

/**
* DOM がロードされているかをチェックする。
*/
function isDomReady(){
if (domReady.done) return false;

// ページ内の DOM 要素がロードされているかをチェックしている。
if (document && document.getElementsByTagName &&
document.getElementById && document.body) {

clearInterval(domReady.timer);
domReady.timer = null;

// 予約された関数を順次実行
for(var i = 0, l = domReady.ready.length; i < l; i++) {
domReady.ready[i]();
}

domReady.ready = null;
domReady.done = true;
}
}

jQuery などのライブラリを使わない場合で、DOM ロード直後に実行する関数を指定したい場合に使えます。

2007年11月5日月曜日

OpenSocial を紐解く


日本では mixi 、海の向こうでは Facebook と、Social Networking はまさにピークを迎えているようにも思える。
一方で開発者視点で見ると発展の余地があり、Google を中心とした OpenSocial という API 群が公開された。

OpenSocial とは何か


OpenSocial について、Google code で公開されている OpenSocial のドキュメント を見ていく。API 群の見出しは以下である。
The web is better when it's social.

これを踏まえて、ドキュメントを読んでいく。

The web is more interesting when you can build apps that easily interact with your friends and colleagues. But with the trend towards more social applications also comes a growing list of site-specific APIs that developers must learn.

Social な WebAPP により、Web の世界はますます面白くなる。
一方で、この流れにより、開発者は API の仕様を Web APP ごとに覚え、APP を作成しなければならない。

そこで、Social Networking な Web APP に公開される API の仕様を OpenSocial として標準化していくことで、開発者の負担を減少させることができる、ということだ。

OpenSocial provides a common set of APIs for social applications across multiple websites. With standard JavaScript and HTML, developers can create apps that access a social network's friends and update feeds.

この文章からOpenSocial は以下のようなものであることが分かる。
  • ソーシャルネットワークそのものではない。
  • Javascript と html により、開発者にソーシャルネットワークにおける中心的な機能、及び中心的な情報へのアクセスを提供する汎用的な API 群 (Common set of APIs) である。
OpenSocial の特徴として前出のページで列挙されている特徴は以下の 2 つである。
  • Many sites, one API
  • Server Optional
    • OpenSocial は Google Gadget の技術を使用しており、開発されたサードパーティ制の APP を Google を始め、好きなサーバにホスティングさせることができる。

OpenSocial が提供する API


OpenSocial API Documentation によると、OpenSocial の API群を使うにあたり、
  • Client-side で javascript を用いる方法
  • Server-side で Rest スタイルの dataAPIs を用いる方法
の 2種類の方法がある。
Client-side: Javascript による API
以下の情報にアクセスできる。
  1. プロフィール情報 (user data)
  2. 友達情報 (social graph)
  3. 活動 (things that happen, News Feed type stuff)
OpenSocial のトップページで利用されている上図は、SNS 空間から、上記の情報を API により抽出しているイメージだと思われる。
Server-side: Atom Pub (GData API) を用いたリソースの操作
Server Side では以下の 3 つの API が定義されている。
  1. The People and Friends data API

    • クライアント APP は Atom Pub または GData APIs を使い、プロフィールや友人関係の閲覧・編集ができる。

  2. The Activities data API

    • クライアント APP は Atom Pub または GData APIs を使い、"action" を閲覧、発行できる.
    • ここでいう "action" とは例えばユーザがいつコンテンツをアップロードしたか、とか作成したか、といった情報のことである。

  3. The Persistence data API

    • クライアント APP はクライアント APP 特有の key, value の組み合わせを閲覧、発行できる

※本記事は以下を参考にしています。
OpenSocial - Google Code
Google Announces the OpenSocial API
たけまる / OpenSocial Protocol

上記以外の関連リンクは以下にまとめてみました。
Haida's clips OpenSocial

2007年10月29日月曜日

oAuth の調査

oAuth という認証・認可のプロトコルに興味があり、調査している。

以下で認証と認可という言葉を使うので、まずここで整理する。
認証 (Authentication) と認可 (Authorization) は違う。

認証(Authentication)
そのユーザーが自分の物であると主張するIDに対して、そのIDが確かにそのユーザーの物であるということを保証すること

認可(Authorization)
認証されたIDを受け入れ、サービスに対して適切な権限を与えること

である。

oAuth というプロトコルをマッシュアップサイト作成時に使ってみることを考える。
プレイヤーは以下の 4種類。

1. End User
リソース所有者。Consumer にリソースを提供
2. Protected Resource
End User が Consumer に公開するリソース
3. Consumer
リソース処理者 (マッシュアップサイト)
4. Service Provider
リソース管理者 (マッシュアップされるサイト)

マッシュアップ時に問題になるのは、以下のことである。

Service Provider のリソースを利用するため、API を叩くとき、End User のユーザ ID とパスワードによる認証が必要である。多くの場合、そのアイパスは Consumer が管理することになる。
⇒ Consumer の管理リスク + End User のセキュリティリスクが高い。

このため、目標としては、

1. End User は Service Provider のサイトで認証したい。
2. Consumer は End User が Service Provider により認証されたユーザであることのみ知りたい。
3. End User は Consumer に自身が許可したリソースのみ認可したい。

ということになる。
この目標を達成してくれそうなのが、oAuth なのである。
ここで、oAuth による認証・認可フローを追ってみる。

1. End User は Consumer に Service Provider の Protected Resource 取得を依頼
2. Service Provider は Consumer に 401 (Unauthorized) + Request token
3. Consumer は Request token を End user に渡す。
4. End User は request token を使い、Service Provider と認証
5. Service Provider は End User に Access token 返却
6. End User は Consumer に Access token を渡す
7. Consumer は Access token を使い Service Provider に Protected Resource の取得を依頼 (⇒ OK!)

以上の過程で、上記の目標は達成可能である。
ここで、
  • Consumer は End User のログイン情報に介入していないこと
  • 4、 7 より oAuth の過程には認証も認可も含まれること

  • に注意して欲しい。

    後者より、oAuth は認証、認可どちらかに分類されるというより、リソースへのアクセス制御プロトコル、という位置付けが適当だろう。
    oAuth の標準化と実装が進むと、ネットの世界でますます面白いことができるようになると思っており、とても期待している。

    ※本記事では以下を参考にしました。
    OAuth Core 1.0 Draft 4
    OAuth - リソースへのアクセスを代行するプロトコル
    WebAPI のアクセス制御に使える OAuth という仕様
    OAuthは熱いかも?な件に関して
    OAuth の Auth は認証?認可?

    2007年10月28日日曜日

    パーティショニングによるデータベースのパフォーマンスチューニング

    パーティショニンングによるデータベースのパフォーマンスチューニングを勉強した。

    パーティショニングが必要な理由


    MySQL では DB 上のデータ量が増加するとパフォーマンスが低下する。
    以下が原因。

    1. MySQL では 1度アクセスされたデータやインデックスは効率化のためにバッファにキャッシュされる。
    2. データ量が増大すると、メモリ上のキャッシュサイズでは不足。
    3. ディスク I/O が増大し、パフォーマンス低下へ。

    テーブルや DB を分割(パーティショニング)し、アクセスされるデータがメモリ上に収まる状態をキープすることで対策する。
    パーティショニングは 2 アプローチが考えられる。

    1. アプリケーション側で実装
    2. MySQL のサポート機能を用いて実装


    アプリケーション側でのパーティショニング実装


    レプリケーションは参照系の負荷分散にはなるが更新系の負荷分散の解決にはならない。
    ⇒ DB のパーティショニングで解決。パーティショニングアプローチには以下の 3種類が考えられる。

    1. データの鮮度でパーティショニング
    直近のものは参照頻度が高い。直近のものを保持するテーブルを用意する。
    (バッチで順に古い DB へデータを移行)

    2. データの種類でパーティショニング
    ブログ記事はサーバ A, コメント記事はサーバ B みたいな感じ

    3. 論理的なデータ構造でパーティショニング
    アルゴリズムを決めてユーザごとにユーザテーブルを決定するなど (テーブルサイズが小さくなる)。

    MySQL のパーティショニング機能での実装


    MySQL 5.1 では β 版だがパーティショニングがサポートされている。

  • コンパイル時に -with-partition オプションをつける

  • ルールを設定して分割させる。
    • データの値の範囲で分割 (100 以上は A みたいな感じ)
    • データの値別に分割 (2,4,6 は A, 3,5,7 は B みたいな感じ)

    パーティショニングを実装したときの問題点


  • Join ができない。
  • ⇒ 複数回 SQL を発行して解決。O/R マッパを使用してプログラムの見通しを良くすること。

  • 全体での新着表示ができない。
  • ⇒ 全体テーブルを用意。Gearman などの非同期処理で全体テーブルを随時更新。

    2007年10月6日土曜日

    Twitter via QuickSilver

    以下、対象は Mac ユーザです。

    今年の主役の twitter ですが、
    twitter へ Quick Silver から post できます。
    結構便利なのと、参考 URI が英語サイトなので簡単にやり方を残しておきます。

    参考 URI は以下です。
    tweet -update twitter via quicksilver

    1.上記サイトから、 Tweet.scpt をダウンロード
    2. ダウンロードしたスクリプトを以下に移動( Actions ディレクトリがない人は、Actions ディレクトリを作成します。)
    ~/Library/Application Support/Quicksilver/Actions/Tweet.scpt
    3. Cmd+Ctrl+Q で QuickSilver を再起動。
    4. 必要に応じて、Tweet.scpt へトリガーキーを設定してください。 ( 参考 URI の中の人は Cmd+Opt+Ctrl+T としているみたいです。)
    5. ~/.twitter を編集し、パスワードを入力
    6. QuickSilver で Tweet.scpt を実行し、update したい内容を入力して、実行
    7. Tweet Sent と出たら成功。

    これでトリガーを使えば、 twitter へ簡単にポストできます。

    ちなみに僕の twitter は planets です。

    追記
    QuickSilver は日本語が使えないので、日本語を post したい場合は、post 内容を QuickSilver にコピペしないと駄目なようです。

    注意 以下がインストールされていることが前提です。
    Growl
    Ruby
    Rubygems
    Twitter Rubygem

    ruby をインストールしていない人は
    port install ruby
    で ruby をインストールしてから、
    sudo gem install twitter
    でインストールできます。

    また、port で ruby をインストールしている人は、Tweet Script 中の ruby のパスを ( 3 箇所 ) 変更します。
    /usr/local ⇒ /opt/local

    Rest スタイルと web 設計を考える

    web サービス設計や API 設計にあたって、今後は 「Rest」 という設計スタイルが自然とキーワードになってくると思います。
    僕はなかなか Rest が理解できなかったのですが、ここ 2 ヶ月くらい、Rest スタイルを意識するようになってから、色々と見えてきたこともあり、一旦自分なりに Rest を整理してみました。

    以下はある勉強会で使った資料です。

    Restful Web Services

    特に苦労したのは、Rest とは何かを理解してもらうのに何から説明したら良いか、ということです。
    個人的には URI の理解が第一歩だと思い、資料の順番となりました。

    Rest は仕様でなくスタイルであるが故、これは自分なりに理解した Rest であり、異論もあると思います。そんな方のフィードバック大歓迎です。

    Rest を理解するポイントは以下だと思います。

    • Rest とは、設計「仕様」ではなく設計「スタイル」である、ということを理解する。

    • リソースの概念を理解する。

    • URI の認識と URI 設計のポイントを理解する。

    • HTTP メソッドとレスポンスコードを理解する。

    • リソース間のつながりを理解し意識する。

    • 自分で API を設計してみる。

    • フレームワークと Rest 設計について考察する。

    上を見て興味が沸いてきた人は、Rest 入門 を読むと良いと思います。このブログは僕が Rest に興味を持ったきっかけでもあり、今改めて読んでみても思うところが多いです。
    特に、 Rest が「仕様」ではなく「スタイル」である、ということを認識できたのはこのブログのおかげだと思います。

    また、邦訳は出版されていないけれども、以下の本が Rest スタイルを理解するのに最適だと思います。

    2007年9月21日金曜日

    San Jose に移動

    3 日間 San Francisco で主に観光しました。

    SF MOMA に行きました。※MOMA: The Museum Of Modern Art
    Roy De Forest という画家さんを知っていますか? 僕はこの人の絵にやられた。

    Roy De Forest

    Country Dog Gentlemen この絵が有名かな。


    昨日、CalTrain に乗り San Francisco を出て、現在は San Jose に近い Santa Clara にいます。

    こちらでは午前中は作業、午後は外出、というスケジュールです。

    土地柄なのか、すっげー集中できる。


    スケジュール立てには、GoogleMaps が活躍しています。

    大まかな地理と詳細な地理がひとつのインターフェースから取得できるのが便利 !


    例えば、

    1. 行くところを全部マップ上にメモ。
    2. その位置関係から宿泊場所を探索。
    3. 付近の交通を調査して移動。

    という風に使っています。


    2007年9月17日月曜日

    SF 到着

    サンフランシスコは現在午前 5時。
    ちなみに起きたのは 3時。
    当たり前だがルームメイトは普通に寝ている。

    どうも僕の生活リズムが早過ぎるらしい。

    サンフランシスコに到着したのが昨日。
    ここに来ると無性にレッチリを聴きたくなる(彼等の本拠なのだ)。
    きっとジャニスとかもフィットするはずだ。

    予想外のことが 2 つあった。

    * 寒い。
    * 予想以上に格差社会

    「カラっとして暑い」を予想していたので、冷涼な気候に戸惑った。
    セーターがないと辛い。

    また、道で地図を見ていようものなら、近付いてきて教えてくれる人が沢山いる。
    親切な人だ、と思って聞いてしまったら終了。
    その場で 5$要求される。

    彼等は職を持たず、こういった観光客を見つけては、それを元に飯を食べているのだ。
    彼等は言う。

    "Because we can't eat."

    僕は 1回はまったが、それ以降は 2度とこの手にははまらないよう、

    地図を頭に叩き込む + 行動目標を持って歩く。

    の大原則を改めて意識している。
    見知らぬ土地へ行ったら、準備段階で地図を頭に叩き込むことは鉄則だが、甘かったようだ。

    また、サンフランシスコに到着して、いきなりダウンタウンに迷い込んだ。
    ダウンタウンの状況は NewYork よりひどい。
    観光地と思って予想していなかったけど、街のやりきれない匂い、道に屯している人の数、これらは New York の比ではない。一方で途方もなく大きなリムジンがユニオンスクエアを走る。

    そんな初日だった。
    今日は、MOMA の方か、Berkeley に行く。

    3 日程サンフランシスコで 「休養」 + 「土地に体を慣らす」後、San Jose に移動して 4 日過ごす予定。宿をまだ予約していないな。

    P.S.
    そういえば本屋で Ruby in nutshell を購入。洋書だが Matz が書いているし、日本ではやたら高騰しているので購入。
    後は、David Heinemeier Hansson の Rails 本とかも見た。(購入していない。)
    Ruby Cookbook も洋書の方がよさげだったな。

    2007年9月15日土曜日

    2007年9月7日金曜日

    iPod の誘惑

    僕の RSS Reader には、friends というタグがある。
    自分の友人の書いたエントリが更新される度に入ってくるわけだけれど、長い間会っていない友人の日記が、いつの間にかとても良い文章になっていたりして、励みになる。
    今朝もそんな感じで今日記を書いている。

    さて、Steve Jobs が 新 iPod (iPod Touch) の発表をしましたね。
    相変わらず apple の製品はソウルフルだ。

    新 iPod Touch は iPhone への繋ぎだろうし、既に iPod は持っているから購入は待とう、というのは頭では分かっている。
    それでも、まだ迷わせるくらいタッチスクリーンというインターフェースの魅力は強い。
    それに、WiFi に対応しているということは、世界の入口にもなるわけでしょう。
    ライフスタイルを変えてしまうような強力な匂いを感じる。

    僕はたまに iPhone を触らせてもらうけれど(海外から輸入した人とかいるので)、初めて iPhone 上の写真を タッチスクリーンで拡大縮小した瞬間に、何かが崩れました。
    あれは革命。

    ということで、誘惑に何日耐えられるでしょうか。

    2007年9月3日月曜日

    例外処理の捉え方

    少し古いエントリーだけど、

    例外処理=プロとアマの違い

    を読んで、なるほど、と思った。

    良いソースには必ず丁寧な例外処理が記述されている。
    そして、プログラムで最も面倒なのが、例外処理でもある。

    これだけ趣味プログラマーが増えてきても、ソフトウェア業界がなくならない理由の 1 つに、例外処理の責任と実装が保障される最も簡単な方法がお金であることが挙げられる。

    ろくに例外処理も書かれていないソースには、市場価値はない、ということか。

    2007年6月17日日曜日

    Google Developers Day に行って参りました.

    5月31日に、Google Developers Day に行って参りましたのでレポートします。少し前の話ですが。

    10時から20時まで、丸1日GoogleDayでした。1000人くらい技術者が来てました。


    Google Developers Day 2007


    写真を沢山撮影しました。(モバshot☆にあります。)

    また、詳細や資料がこちらで閲覧できます。


    まず午前中の様子からです。


    基調講演 by Greg Stein


    まずは、Googleで、Engineering Managerとして、オープンソースの促進をするグレッグスタインがキーノートを務めました。この方はApachの議長でもあります。モバshot☆や、下の方にも写真がありますが、長髪のグレッグは、異様なオーラを発揮していました。しかし落ち着いた、聞きとりやすい英語でプレゼンターとして一流。

    オープンソースと、グーグルにとってのその大切さを丁寧に説明しました。

    Googleのソースも8割以上は公開して良い、と言い切り、自分たちがソースを公開していくことで、ウェブの世界を変化させてきた、という自負と、

    これからもそうでありたい、というオープンソースへの意気込みはすごい説得力でした。午前中のハイライトでした。


    ゲストスピーチby はてな CTO 伊藤 直也


    GoogleのAPIを用いたはてなのサービスの紹介でしたが、既存サービスの紹介でしたので、インパクト薄かったです。

    ただ、はてなの伊藤氏曰く、GoogleのAPIの優れている点は、


  • 個人で作成するのには難しい規模である。

  • オープンである。

  • プログラマブル (開発者が使ってみよう、という気になりやすい)。

  • 速く、安定している。

  • の4点。こちらはラボでもAPIを作成しようとしているので、参考になりました。


    Google最新情報 byGoogle シニア プロダクト マネージャー


    すぐに話題になったGoogleGearGoogle Mappletの紹介がありました。

    個人的にはMappletで色々開発ネタが浮かんできたので面白かったです。


    この後、昼飯。(当然用意してありました。。。)

    そういえば、バランスボールが会場の近くに転がってました。


    有名なバランスボールが。。


    午後からは以下の4つのセッションに参加しました。

    これらの様子も前述のこちらで確認できます。


    GoogleMaps API Introduction by Chirs Atenasio


    GoogleMapsは普段からコード書いたりしているので、知っていることが多かったです。皆さんも知っているでしょうから割愛します。プレゼン資料がこちらにアップしてあります。

    フォームにコードを書き、すぐに走らせる、というデモの見せ方は非常に参考になりました。

    僕もデモの方法が課題の一つですので。


    KML -Geographical Format For Earth & Maps by Bruno Bowden


    KMLセッション


    Google EarthのKMLを実際に編集するデモから始め、KMLを使用して情報をEarth上に反映する方法がテーマでした。

    印象に残ったのは、ユーザに情報を登録してもらうプラットフォーム作成に力を入れている部分です。

    モバイルにおける位置情報取得、絵文字のプラットフォーム作成が最近のテーマでもあります。

    ユーザに情報を登録させる方法については、ノイズ除去、データ形式が同じく課題です。

    GoogleEarthにおけるデータ形式は、 OGC, GML という標準化機構に添う形にしたい、と言うことのようです。


    Intro go Google Data APIs: Mashing up Google Calendar,Spreadsheets and more! by Ryan Boyd


    Googleの様々なAPIを公開していますが、様々なサービスで共通のAPIを使うことができるようになっています。これをGoogle Data API(GData API)と呼んでいるようです。

    GData APIは、Blogなどでよく使われている、Atom Publishing Protocolに対して拡張を行ったREST-basedなAPIで、全文検索、Tagによる検索、更新時間に関する検索などが、共通のAPIで実現できています。

    また、アウトプットの形式も、XML, JSONなどを指定でき、様々なフォーマットで結果を受け取ることが可能です。

    色々なAPIを公開していこうとしている中ですので、参考になりました。


    Software Engineer in Google by Ukai Fumitoshi


    Googleのアプリケーションはとにかく安定していて信頼できるという評価ですが、その開発手法を知りたく思い参加しました。

    印象としてはやるべきことをやっている、ということです(これがなかなかできないのです)。

    技術者として優秀な人が多いのは勿論ですが、いくつか印象に残った開発の工夫を列挙します。


    ドキュメンテーションについて。


    エンジニア間で共有するDesignDocというドキュメントを作成する。

    ドキュメント化は最低限で良いが、以下は必ずドキュメント化する。


  • Why?--設計の背景、目的

  • How?--設計の方法

  • Who?--メンバー

  • セキュリティ、プライバシーについての考察。

  • テスト、モニタプランについて。

  • 開発方針


  • 自分たちで作る(オープンソースは基本別のディレクトリツリーで)

  • パフォーマンス重視(より良いアルゴリズムを!)

  • スケーラビリティ(並列化する)

  • 信頼性(MTBF3年)→1000台あると1日1台は壊れる。

  • テスト(リリース前は必ずユニットテストを書く)

  • Coding


  • C++, Java, Python

  • Sanzall

  • Javascript, ActionScript

  • リリース前のレビュー


  • あらゆるコードは一つのレポジトリで管理し、全エンジニア間で共有している。

  • バグの混入を防ぐために、他のエンジニアがコードをレビューする。

  • 記述スタイルを統一するためのリーダビリティーレビュー。

  • (ここを通過しないコードはリリースさせない。)


    情報共有について


    創造的である為には情報は共有されなければならないという前提。


    共有されるべき情報と共有方法


  • データベースIdea、バグ

  • 進捗: 「Weekly Snippet (今週の進捗、来週の目標を書く)」, blog

  • Document : Design Doc, Wiki, Docs & SpreadSheet (複数人で編集できるため。)

  • ソースコード: Perforce により、自由に。

  • コミュニケーション: IM, Mailinglist, 昼飯, 休憩時間

  • TechTalk: 1回4時間程度の技術会が毎日3〜4回行われており好きに参加しているらしい。

  • 一部屋に3〜4人の開発者によるグループ開発。

  • 共有されてはならない情報


  • ユーザ情報、プライバシーデータ

  • エンジニアの評価方法


    以下が主な評価軸となるようです。


  • 4半期ごとの目標シートと成果報告。

  • 評価は個人、チーム、会社など他面的なレベルで。

  • Code Review, Discussion, Snippets, Weekly Report, Google Resume

  • 同僚の評価。

  • 開発者に求められる態度


  • 自主的にやることを見つける

  • 知識やスキルを身につける。

  • 上からの命令を待たない。

  • 直すべきものを見つけたら、チームの枠関係なく、直す。

  • 変化についていく。

    レセプションパーティ


    セッション後に、レセプションパーティーが18時からありました。

    Google技術者と話すまたとない機会でした。今日セッションした方6人くらいと話しました。MountainViewから来た方が多かったけれど、日本で働く外国人の方もいらっしゃいました。英語は楽しいけど緊張します。

    「今日のアルバム作ってるんですよー」って言いながら、それぞれの方の写真を撮って、位置情報つけて、モバshot☆にアップロードして、登録するところまでをデモをしたりもしました。特にUSのモバイルはGPS対応してないので、興味津々(?)に見てくれました。

    写真の様子はモバshot☆でご覧ください。日本で働いている技術者の方にはモバshot☆のurlを紹介しました。早いとこコミニュティ機能をつけると使ってもらえそうですね。

    下は基調講演のGregStein氏。優しい。


    Greg Stein 氏。


    モバshot☆をGoogle技術者に紹介していたら、「マプレットに対応してくださいよー」って言われましたけど、これって、すぐやれる上に、やったら普通に話題になりそうですね。週末にやってみよう。


    全体の感想


    Googleはモバイルに今年間違いなく力を入れようとしています。

    但し、位置情報を使用したモバイルコンテンツに関しては、そもそも本社で位置情報携帯が使用できませんので、まだまだなようです。

    絵文字のプラットフォームを整備したり、位置情報コンテンツを作成したり、地道な活動をすると、かなり優位になりそうです。


    また、品質を落とさない工夫は上記に詳細に述べましたが、さすがだなぁ、と感じました。


    以上になります。そんな濃い〜1日でした。


  • 2007年5月3日木曜日

    セッション

    先日知り合ったドラマーにお誘い頂き,伝手でセッションに行ってみた.
    初対面の人だらけだが,大学の上手いサークルに属する方々なので,ワクワクして行った.
    当然の様に全員が上手だったが,特に今日はフュージョン系の方々だったせいか,普段あまり馴染みのない音使いが新鮮だった.新しい感覚がより一層興味を刺激する.

    今日印象に残ったのは,次のような場面だった.
    キーボードの人がE♭→Dmという進行でセッションを開始した.
    僕はそれをGm→Dmだと勘違いしてそこに乗った.
    勘違いは後で音を確認して分かったのだが.

    E♭とGmは1音だけ,半音ずれているので,間違えて聴いてしまったのだが,この捉え方の違いで,音を出した結果は全然異なってしまう.
    僕の取り方だとキーGmのマイナーキーでセッションしてしまうことになる.この進行はありがちの進行だし,マイナーキーなので何となく暗い.一方で本来のE♭キーだとそもそもメジャーキーだしコードの進行的にもちょっと面白い.
    セッションを普通にやっているとマイナーキーやありきたりの進行が多くなりがちなので,これは新たなヒントになりそうだ.曲を展開させるときにも使えるな.

    今日のセッションでは「こんな音使いありなんだ」,というギタリストに出会うことができた.また新たな刺激を頂けたことは素直に嬉しい.

    2007年4月30日月曜日

    セッション

    今日はジャズ畑の人たちとセッション。
    モードよりのジャズなら折り合いがつくと思ってコミットしてみた。
    一緒に演奏してくれた方々には心から感謝します。

    それにしてもジャズメンは上手い。
    引き出しは豊かだし、センスが良いし、音楽に対する楽しみ方を多く知っている。
    自分もワンモードセッションならいけるが、これだけだと聴いていて飽きるだろう。

    Jimi Hendrixのように、自由、かつエモーショナルに。
    と思いながら弾いている。
    彼からの影響はそこまでで良いと思っていて、もっと様々な音使いを知りたい。

    しかし、知らないモードが沢山ある。
    様々な音の使い方を咀嚼して、それをフィーリングに消化させる。
    単に使い方を覚えただけでは駄目で、自由かつエモーショナルな演奏をしようと思ったら、新しい音使いが口から出るレベルが必要だ。
    セッションは場の空気にダイレクトに反応したり作り出していくことが求められるから尚更だ。

    次回への改善点としては、
    周りに反応することが多く、自分から流れを作り出す方が疎かになっていたので弱気にならないこと。
    もっと引き締まったセッションにする為、ジャズに習って、テーマを予め作ってからセッションをすること。

    明日と明後日もセッションの予定がある。
    セッションを通して、間の使い方とか、音の使い方のアイディアをふくらまそう。
    連休中は曲も作ろう。

    帰りにディスクユニオンに皆で行った。
    最近ロックばかりだったが、久々にジャズを聴きたくなったな。

    2007年4月23日月曜日

    ボイシング

    ジョージ・ハリスンが、ビートルズのメンバーに誘われた理由が、多くのコードを知っていたから、というのは有名な話だ。John Lennon 曰く、
    結局ジョージを仲間に誘ったのは、彼が僕らよりもコードを沢山知っていたからだった。彼にはコードを随分沢山教わったな。新しいコードを覚える度にそれを使って唄をこしらえた。
    多くのコードを知っていた、というよりも、多分色々なボイシングを知っていた、という話だと思う。(何しろコードは24種類しかないのだし。)

    このギターのボイシングは、センスが出る。ライブに行くと、コードをどんな方法で抑えてるのか、というのは気になることのひとつだ。例えば、Cコード一つとっても、色々な押さえ方があり、その派生型は沢山ある。ただ、僕の場合、ボイシングが気になるのは、気持ちのいい響きを出す、気持ちの良い押さえ方を知りたい、というのが理由だ。

    僕は、色々なギタリストが、何気ない顔をしながら、細かくボイシングを変化させて、素晴らしい響きを作り出していることを知り、それらを真似るようになった。そして、それぞれ押さえ方には意味があることに気付いた。意味を作るのは、コード進行だったり、その曲の雰囲気だったりして、音楽的に意味がある。だから、それらを弾いてみると音楽的に気持ちがいい。

    多分そのどれもが、一度試してみれば音楽観を変えるのに十分だと思う。彼らが何でギターを長時間弾いていられるのか、その答えの一つが見えてくる。単純に弾くにも聴くにも気持ちが良いのだ。
    今日、スタジオでセッションをしている途中、Cm(13)を発見した。これも意味のある流れで使うと、気持ちが良い。

    2007年4月22日日曜日

    音楽を高音域で捉えること

    マイルスの自叙伝を最近読み返す機会があったらか、「音楽を高音域で捉えること」という言葉が突然頭に引っ掛かってきた。気になってこの言葉を探してみた。こうある。

    「まだテクニックが未熟で音楽をあまり高音域で捉えられないこともあって、ディズみたいに高い音では吹けなかったが、彼がやっていることは、すっかり分かっていた。俺はいつも音楽をしっかりと、確かに中音域で捉えていたんだ。」

    この文章の周辺を読み返してみると、若い頃のマイルスは高い音に弱く、無意識の内にコードと同じ音域で吹くことが多かったらしいことも分かる。

    今日改めて気付いたが、僕も高音域の方が弱い。
    中音域なら鳴っている音の音名が確実に分かる。しかし、高音域になってくると半音の違いが怪しくなってくる。ソロも高音域でのフレーズが出てこないことが多い。
    逆に言うとこの辺に注意すると、もっと音域を有効に活用してギターを弾けるかもしれない。
    音楽を聴いていても、新たに発見することがあって楽しくなりそうだ。

    そう言えば Hendrix や Fruscianteも後期になるにつれて高音域を良く使うようになってるな。

    2007年4月18日水曜日

    セッション

    セッションを週1回やるようになってからそろそろ1ヶ月になる.
    2ヶ月くらい前から,ちょうどバンドでの音出しを再開して,ライブを1回やった.
    その当たりから,昨年末にギターを一度止めて失われた,
    ギターの感覚が大分戻ってきたので,セッションをすることにした.
    このセッションでは自分の中ではルールを決めていて,
    「100%その場で作ったフレーズでやる」.

    始めは3人でやっていた.
    ギター,ベース,ドラムの編成.
    そのときは僕が大体コードとか曲の感じを決定することが多く,自分から出てくる音も
    少し意味のあるものになってきたと感じられかなり楽しかった.

    それから最近音楽が好きな同僚がいたので試しにセッションに誘ってみた.
    彼はギタリストである.
    ちょっと音出しをしただけでリズム感,センスとも抜群で,一緒の音だしができることに半端ない歓びを感じる.
    しかも自分とは違うタイプのギタリストである.
    僕はどちらかというと単音を弾く方が好きだが,彼は和音を弾く.
    これは面白い.

    ただギタリストが2人になったときのセッションは難しい.
    自分の音域と被る音域で弾くわけにもいかないし,音色も気をつける必要がある.
    和音が鳴っている分,音の選択の幅も狭まる.

    こうなってきたときのセッションこそ,自分の力量が問われる感じがする.
    この手のセッションは自分の主張を通すだけでは上手くいかない.
    3人のセッションだと延々とソロを弾くことができるし,それだけでも場はもってしまう.
    しかし,4人で満足感のあるセッションにしようと思ったら,それでは駄目だ.
    場の空気,和音,流れ,それから皆の気分を感じながら音楽を作り上げていくことが必要だ.

    あるフレーズを誰かが弾き,それに全員が乗っかる,という風に始めるのだが,
    始め20分くらいは大体上手く行かない.手探りが続く.
    でもここで音出しを止めないのがポイントの気がする.
    どっかでつき抜けて気持ちのいい状態が見つかる.
    これがセッションの醍醐味かもしれない,と気付いてからセッションがとても楽しい.

    ただ,今日は正直あまり上手くいかなかった.
    今日の課題は,
    ・音の選択が難しい.(そもそも和音のテンション音が多いので)
    →和音を感じたら,素早く鳴らしていい音と駄目な音を判断する必要があるが,その判断の精度を上げる.
    ・その場だけでメロディを弾かないで,流れを作りながらメロディを弾く.
    ・ワンコードになりがちなので,展開を促すように弾く.

    来週までに改善しよう.
    ただ、上手くできないことも含めてとても楽しい.

    2007年2月11日日曜日

    What is the most important part in music?

    Today, I slept very well.
    This week, I was very busy and I didn't sleep in a bed but slept on the floor.
    So I was very tired today.
    I thought I needed to play guitar and compose some songs,
    but I couldn't feel trying it because of my daily stress.

    Then I decided to see a movie.
    I wanted to get inspired from it for playing music.

    I love very much the atmosphere and evolution of the story of movies directed by Jim Jarmusch.
    For example, I love 'Dead Man'.
    In that movie, music written by Neil Young makes the movie very unique.

    Today, I watched 'Down by Law'.
    It was a kind of movie that showed the strange and wonderful human relationships.
    The atmosphere of this movie too, I did like very much.

    When I saw this movie, I suddenly had some questions.
    What the part is the most important in a movie?

    When I was young, I thought 'the ending' was the most important.
    And I thought it was too, in novels.
    In a sense, it is true.

    If we saw or read 'only' the ending of the story, it is not interesting.
    More to say, what's the meaning of the other part of a story?

    It is often said that one of the keys for good writing is to learn to recognize the approach of an ending.
    I mean, if we see or read the wonderful ending of a story, we grab it for skill up our writings.

    ...I think that kind of the idea is a bit of nonsense.
    The ending of the story is the results of 'before' or 'other' part of the story.
    We are impressed much in it, because we have known the narrative line of it.

    And I think, then, what the part is the most important in songs?
    It's true that 'sabi' is the most important part of a song.
    I sometimes listen to a song only for the 'sabi' and when it finishes,
    I mean, when I finish listening to the one chorus of the song, I turn to the next song.
    I think that kind listened to in that way is 'bad' or 'ordinary' song.

    When I think beautiful songs, I can sing the whole melody of them.
    I like them because I like their beautiful flow of the melody,
    chords which impress the melody, emotional rhythms, atmosphere of them, ... and so on.
    The song like that kind can't be split by any part like 'A melody', 'B melody'
    ... and it goes you may think.
    The part of the song has a meaning for other parts.

    Although it is true, it's not easy, rather difficult, to compose like that kind of a song.
    It can't be composed only by a session. It composed by the deeply thoughts and enthusiasm.
    So I think the ability of playing instruments and composing songs are not the same abilities of the music.
    Bud thing is that I often forget that point.
    When I saw the unbelievable technique, I sometimes think he is a good musician.
    The truth is that I think the technique is often a result of thinking extremely.

    It is often said that men think extremely but women can think as regards of whole of things.
    I mean, women's thoughts often take very fine balance.
    'Balance' is a keyword in this writing.
    I give you some examples.

    ・For me, cleaning the room is not so important.
    To clean the room, I 'only' need to make space for me. The thought goes one direction.
    ・When I see the works of the Picasso, I am very amazed at the fine balance of his painting.
    For me, it's not important whether the paintings are nearly like pictures.

    You may think it is an excuse of my technique, but for me, the technique is an excuse of thoughts.
    Although it's a difficult question that how much technique I need,
    I think recently the key of the answer is purpose of it.
    I don't think all of the techniques are bad.

    Let's imagine the answer when we are asked from someone the question:
    What the song is the most important for you?
    It's a technical one?

    Please let me know what you think.