2008/10/22

GoogleChrome と prototype.js

最近Prototype & script.aculo.usを買ってJSをかじりだしたのだが、GoogleChromeでサンプルコードが動かない。

$('...')でdivをとると、拡張メソッドが使えない。

なんでじゃーとPrototypeのMLを見たら同様の事象が出ていて、回避策(っぽいもの。Chrome無視しろとか)も書いてあった。これ

普通のブラウズはFirefoxだが、GMailとかちょっとしたときのChromeのすばやさとDebuggerは気に入ってるのだが、ちょっとがっかりだ。

2008/10/14

小ネタメモ

GoogleChromeを使ってると、DNSが更新されたのに反映されずに見えない場合がある。どうやら、DNSプリフェッチという機能が邪魔をしているようだ。その場合は、オプションからDNSプリフェッチを外して、Chromeを再起動してやると、新しいDNSでとってくるみたい。普段は高速化されていいのだが、どやって明示的に消せるのかわからなかった。困ったものだ。

RSpec on Railsでspec -Fsとかオプション設定は$RAILS_HOME/spec/spec.optに書く。デフォルトは

--colour --format progress --loadby mtime --reverse

2008/10/07

has_many throughのFixtureがつながらない

has_many throughなAssociationをもつテーブル用のFixtureを書いたが、関連先のデータがどうしても0件になる。

モデルはこんなの

class User < ActiveRecord::Base has_many :calendars, :through => :access_controls has_many :access_controls  ・・・ end class Calendar < ActiveRecord::Base has_many :schedules has_many :access_controls has_many :users, :through => :access_controls ・・・ end class AccessControl < ActiveRecord::Base belongs_to :user belongs_to :calendar  ・・・ end

Fixtureはこんなの

# users.yml user1 : name: user password: password nickname: user first_name: first_name last_name: last_name email: user@example.com # calendars.yml calendar1: id: 0 name: calendar1 public: true calendar2: name: calendar2 public: false calendar3: name: calendar3 public: false calendar4: name: calendar4 public: false calendar5: name: calendar5 public: false # access_controls acl1: user_id: user1 calendar_id: calendar1 control: <%= AccessControl::ALL %> acl2: user_id: user1 calendar_id: calendar2 control: <%= AccessControl::ALL %> acl3: user_id: user1 calendar_id: calendar3 control: <%= AccessControl::READONLY %> acl4: user_id: user1 calendar_id: calendar4 control: <%= AccessControl::UPDATE %> acl5: user_id: user1 calendar_id: calendar5 control: <%= AccessControl::NO_AUTHORITY %>

でもってテストコード

describe User do fixtures :users, :calendars, :access_controls it "should have 5 calendars" do user = users(:user1) user.calendars.should have(5).items end

その結果

1) 'User should have 5 calendars' FAILED expected 5 items, got 0

全テーブルをFindしてppしてみたら、access_controlのuser_idとcalendar_idが全て0になっている。でも、自動生成されるUserのIDは30万とか。そりゃ0件になる。

いろいろぐぐって見たら、AssociationテーブルのFixtureは_idをつける必要はないらしい。要はuser_idじゃなくて、userにしろと。

#access_controls.yml acl1: user: user1 calendar: calendar1 control: <%= AccessControl::ALL %> acl2: user: user1 calendar: calendar2 control: <%= AccessControl::ALL %> acl3: user: user1 calendar: calendar3 control: <%= AccessControl::READONLY %> acl4: user: user1 calendar: calendar4 control: <%= AccessControl::UPDATE %> acl5: user: user1 calendar: calendar5 control: <%= AccessControl::NO_AUTHORITY %>

で、めでたく動いた。なぜ0にするんだorz
悩ましすぎる。

2008/09/23

rspecっていいなぁ

ほんとにほんのちょっとだけ、チュートリアルにしたがってモデルでしか使ってないけど、、、「RSpecには夢があるっ」っていうのは同意。ここまで感心したソフトウェアはなかった。

語彙が、ここまで思考に影響を与えるかというのを再認識させられた。

そしてプログラムをとことんまで自然な英語にしようという心意気。Railsで一番こころをうたれたのもそこだけど、さらに上を行く感じだ。

プログラムじゃなくてほんとに仕様を記述している。そしてそれが仕様であり、実際動く試験になるのだから素晴らしい。すごい綺麗。

spec -fsの結果をみると心躍る。まさしく仕様書!

客がit 'ほげほげがぴよぴよ'とspec書いて中を埋めていけば、設計が終わる世界がくるといいなぁ。

BDDというかちゃんと仕様を決めてとりかかる。Spec Driven Development。あれ?すごい普通な気がする。いかに仕様がきちんときめきれてなかったという裏返しなのか?

itブロックの中でデータというかそのコンディションを用意するまでがメンドイというか冗長になりがち。何とかならないものか。

モデルは開発者よりで、すごいストンと落ちるんだけど、客が気にするのってもっと上位な見た目とか振る舞いなんだよね。そこがどこまで記述できるか。そこを見極めたい。そして客がかける要求(Requirement)とSpecの間を埋められたらすごい面白いと思う。

その要求にはコレだけのSpecがいるのでおいくら万円とか。

少なくともSpecがどれだけ落としたらちゃんとCodeに落とせるか、いいかの良い指標になりそうな気がする。

とにかくRSpecは楽しいから使っていこうと思う。

2008/09/21

Rails 2.1 に rspec を入れる。

どうもRSpec on Railsの入れ方だと2.1に対応していないバージョンが入るらしく、DEPRECATION WARNINGがでる。

こっちのを入れるとエラーがでない。要Git

Rails 2.1ならば以下ので入れる。

  1. script/plugin install git://github.com/dchelimsky/rspec.git
  2. script/plugin install git://github.com/dchelimsky/rspec-rails.git
  3. script/generate rspec

使い方はRSpec on Railsと変わっていないようだ。

PostgreSQLにTCP/IP接続する

Windows側からUbuntu上のPostgres8.3.3にpgAdminでつなごうと思ったらつなげなかった。

デフォルトだと、TCP/IPでつなげないらしい。そーいえばUnixDomainSocketがどーのとなっていたな。

ということで設定。

  1. /etc/postgresql/8.3/main/postgresql.confをエディタで開く
  2. #listen_addresses = 'localhost'のコメントアウトを外して保存
  3. /etc/postgresql/8.3/main/pg_hba.confをエディタで開く
  4. host all all 接続元IPアドレスとマスク trustを追記
  5. sudo /etc/init.d/postgresql-8.3 reload

古い記事が多くて困るのだが、-iオプションはもういらないらしい。あの手の解説記事には作成日と更新日をつけるべきだ。その点Blogは日付が必ずつくのでよい。ただ、一連の解説記事がばらばらになり、一覧性が悪いという欠点がある。そこはCMSに軍配が上がる。

pgAdminから接続するときは

  • 名前:任意
  • ホスト:サーバのIP
  • Port:Postgresのポート(デフォなら5432 postgresql.confで変更可能)
  • SSL:必要(デフォだとonになっている)
  • DBメンテナンス:Postgresの管理ユーザ(通常はpostgres)
  • ユーザ名:DBのユーザ
  • あとは良しなに。

UbuntuのSubversionを1.5にする

Windows側のSubversionを1.5.2にしてしまったがために、railsのpluginをUbuntu側で操作しようとすると、Subversionのバージョンが古いとか怒られた。

ということで、UbuntuのSubversionをアップグレードしようとしたが、普通だと1.4のパッケージしか入らない。

あまり詳しくないのだが、hardy-backportsとかいうところに1.5.1のパッケージがあるようだ。

Synapticを開いて、リポジトリにここに書いてあるURLを追加する。

deb http://archive.ubuntu.com/ubuntu hardy-backports main universe multiverse restricted

再読み込みしてくれとダイアログがでるので、言われるままに再読み込みし、subversionで検索。最新バージョンが1.5.1になっているのでチェックしてバージョンアップ

なんとなくバージョンアップに成功。script/pluginでも怒られない。

よくわからないものは触るべきではないのだが、とりあえず。

TortoiseSVNのオーバーレイ

VMWare上のUbuntuにプロジェクトをおいて、Samba共有かけてホストから操作しているんだけど、そのときTortoise SVNのオーバレイ(Commit済みはチェックマークとかのアイコン)が表示されなかったのでメモ。

理由は単純で、Tortoise SVNの設定でネットワークドライブでオーバーレイを表示しないようになっていたから。

直し方

  1. Explorerで適当なところを右クリック→Tortoise SVN→Settings
  2. Icon Overlays
  3. Drive TypesのNetwork drivesにチェックをつける。

2008/09/13

UbuntuのPostgresqlメモ

先日ubuntuにインストールしたPostgresだが、使い方がよくわからないので、調べたメモ

psql --versionで8.3.3だったので、マニュアルはこれ参照。

インストール手順だとmake installのあと、initdbとかいろいろやっているけど、apt-getした場合はすでに終わっている。というかDBが立ち上がっている。

psコマンドで出てくる引数から、次のような設定になっているみたい。

  • initdb先:/var/lib/postgresql/8.3/main
  • 設定ファイル:/etc/postgresql/8.3/main/postgresql.conf

起動はinit.dのスクリプトとrc4dにあるスクリプトっぽい

/etc/init.d/postgres-8.3 start | restart | stopでOK

RedHat系ばかり使っていたからDebian系の構造がいまいちわからない。

rails+postgresql-prで使おうと(rake db:create:all)したらエラー

No such file or directory - /tmp/.s.PGSQL.5432

ubuntuのこのファイルの出力先が/var/run/postgresqlになっている。
上記設定ファイルの「unix_socket_directory」を'/tmp'にすればよい。

※database.ymlのhost:に/var/run/postgresqlを指定すればよいとも書いてあるんだけど、うちでは動作せず
と思ったら、db:migrateはこっちが効くようだ。めんどい。

FATAL C28000 MIdent authentication failed for user "office" Fauth.c L1003 Rauth_failed

権限が足りないらしい。
/etc/postgresql/8.3/main/pg_hba.confにDomainSocketのアクセスを追加
とりあえず動かすにはlocal all all trustとか追記すればよい。

今はauto vacuumなんてあるんだなぁ。

2008/09/10

ubuntuでruby開発環境を作る

作ってみたのでコピペ。慣れると20分くらいかも

ubuntuは初めて触ったけどEeePC買って入れてみたくなった。

今回はVMWare上にubuntuをGuestOSとして立てて開発環境を作ります。
HostOSはWindows Vista
VMWareは導入済みとする。うちはPlayerではなくServerのほうを使っている。

Ubuntuをいれる

  1. ここから仮想マシンをダウンロードする。(2008/09/09現在 8.04が最新。来月8.10がでるっぽい)
  2. 任意のフォルダに展開して、Ubuntu.vmxをダブルクリックして開く。
  3. メモリは512ぐらいあればいいかも?足りなかったら調整して。
  4. GuestOSを起動
  5. ユーザ情報とキーマップを適当に設定。
  6. ログインできたら、システム→システム管理→アップデートマネージャでアップデート
  7. GuestOS再起動

Ruby

ポートを待てないので最新版をソースから入れます。

  1. システム→システム管理→Synapticでzlib1g-devとlibssl-devを入れる。
    (これがないとrubygemsが入らないのとrailsが起動しない)
  2. RubyのDLページから最新版のURLをコピー(2008/09/09現在 ruby 1.8.7-p72)
  3. wget
  4. tar jxf ruby-1.8.7-p72.tar.bz2
  5. cd ruby-1.8.7-p72
  6. ./configure
  7. make
  8. sudo make install

でruby -vでバージョン情報が出ればOK

RubyGems

  1. RubyGemsから最新版のURLをコピー(2008/09/09現在1.2.0)
  2. wget
  3. tar zxf rubygems-1.2.0.tgz
  4. cd rubygems-1.2.0
  5. sudo ruby setup.rb

Gems

Rails 2.1.1とPostgreSQL接続用のGemをいれる。

Postgresなのは今回開発のターゲットがそうだから。MySQLが嫌いだからではないとおもう。

あんまり詳しい使い方を知ってるわけではないのでWeb情報頼り

  1. sudo gem install rails postgres postgresql-pr

Subversion

Subversionもいれる

  1. システム→システム管理→Synapticでsubversionをいれる。

PostgreSQL

  1. システム→システム管理→Synapticでpostgresqlとpgadminをいれる。
  2. sudo passwd postgresで管理ユーザのパスワード設定

必要なDBユーザは次のようにして作ります。

  1. su - postgres
  2. createuser -P hoge_development
  3. Enter password for new role: 面倒なのでパスワード無し
  4. Enter it again:
  5. Shall the new role be a superuser? (y/n) y

これであとはRailsコマンドなりで作れると思います。

他のEmacsとかZshとかScreenは適宜おこのみで。

補足

依存関係が足りない

rubyのmake前にopensslを入れ忘れたりするとエラーになる。

そのときはapt-getしたあとrubyのソースディレクトリで

  1. cd ruby-1.8.7-p72/ext/openssl
  2. ruby extconf.rb
  3. make
  4. sudo make install

で良いみたい。

Rubyの再インストール

上記の依存関係の直し方2:再インストール

  1. make clean
  2. make
  3. sudo make install

activerecord-postgresql-adapter

postgresだけだと動かずにactiverecord-postgresql-adapterをいれろといわれるけど、そんなのないので postgresql-pr を入れるといいみたい

2008/08/08

ListとObjectOutputStream

なんか苛まれている挙動。ListをもっているオブジェクトをObjectOutputStreamで送ろうとしてもデータが足りない。

import java.io.*; import java.net.*; import java.util.*; public class Server { public static void main(String[] args) { ObjectInputStream in = null; ObjectOutputStream out = null; ServerSocket ss = null; try { ss = new ServerSocket(1234); while (true) { Socket s = null; try { s = ss.accept(); in = new ObjectInputStream(s.getInputStream()); Test t = null; try { while ( (t = (Test)in.readObject()) != null) { System.out.println(t.toString()); } } catch(EOFException e) { System.out.println("Disconnected"); } } finally { if (out != null) { try { out.close(); } catch(Exception e) {} } if (in != null) { try { in.close(); } catch(Exception e) {} } if (s != null) { try { s.close(); } catch(Exception e){} } } } } catch (Exception e) { e.printStackTrace(); } finally { if (ss != null) { try { ss.close(); } catch(Exception e) {} } } } }

import java.io.*; import java.net.*; import java.util.*; public class Client { public static void main(String[] args) { ObjectInputStream in = null; ObjectOutputStream out = null; Socket s = null; try { s = new Socket("localhost", 1234); out = new ObjectOutputStream(s.getOutputStream()); Test t = new Test("test1"); t.addTest2("test2-1"); System.out.println("Building Test1 :" + t.toString()); out.writeObject(t); out.flush(); List<Test2> l = t.getTest2s(); l.add(new Test2("test2-2")); System.out.println("Building Test2 :" + t.toString()); out.writeObject(t); out.flush(); t.addTest2("test2-3"); System.out.println("Building Test3 :" + t.toString()); out.writeObject(t); out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (Exception e) {} } if (s != null) { try { s.close(); } catch (Exception e) {} } } } }

というクラサバがある。で、送りたいデータは

import java.util.*; import java.io.*; class Test implements Serializable { List<Test2> test2s; private String name; public Test(String name) { this.name = name; test2s = new ArrayList<Test2>(); } public void addTest2(String s) { test2s.add(new Test2(s)); } public List<Test2> getTest2s() { return test2s; } public String getName() { return name; } public String toString() { StringBuffer buf = new StringBuffer(); buf.append("Test : name => " + name + ", "); buf.append(" test2s => ["); for (Test2 t : test2s) { buf.append("{" +t.toString() + "}, "); } buf.append("]"); return buf.toString(); } } class Test2 implements Serializable { private String name; public Test2(String name) { this.name = name; } public String getName() { return name; } public String toString() { return "Test2 : " + name; } }

というListをもった内容。

で実行結果が

クライアント側

Building Test1 :Test : name => test1, test2s => [{Test2 : test2-1}, ] Building Test2 :Test : name => test1, test2s => [{Test2 : test2-1}, {Test2 : test2-2}, ] Building Test3 :Test : name => test1, test2s => [{Test2 : test2-1}, {Test2 : test2-2}, {Test2 : test2-3}, ]

サーバ側

Test : name => test1, test2s => [{Test2 : test2-1}, ] Test : name => test1, test2s => [{Test2 : test2-1}, ] Test : name => test1, test2s => [{Test2 : test2-1}, ] Disconnected

サーバ側にtest2-2, 2-3が届かない。うーむ。。。

どうやら、ObjectOutputStreamが一度シリアライズしたものをキャッシュとして持つようだ。

out.flush()で書き込んだあと、out.reset()でストリームを初期化してやると、正常に送信できた。

APIだけだと分かりにくい。Java オブジェクト直列化仕様

2.1 ObjectOutputStream クラス
クラス ObjectOutputStream は、オブジェクト直列化を実装するためのものです。このクラスは、すでに直列化されたオブジェクトセットなどのストリームの状態を維持します。そのメソッドは、直列化するオブジェクトのトラバーサルを制御して、指定されたオブジェクトと参照するオブジェクトを保管します。

reset メソッドは、ストリーム状態を再設定して、構成時の状態に戻します。 ・・・中略・・・これは、オブジェクトの内容やオブジェクトを再送信しなければならない場合に有用です。
ってちょこっと書いてあったからなんとなくやってみたら当たった。

解決に徹夜したのでメモ。

2008/06/02

docomo 906シリーズで無線LAN対応の続き

ホームUってサービスらしい。

概要を見る限り家のルータにホームU用無線LANのアンテナを立ててドコモ網へルーティングするのか。そうか、そうしないとiモード網のコンテンツ見れないしなぁ。

パケ料は無料なのか。家にパソコンがないとかそういう人にはいいの・・・か?+1000円ならパケホーダイフルのほうが外で見れてお得感があるんだが。P906だと7.2M HSDPAだし。

なんかの布石なのかなぁ。戦略が見えないが、スマートフォンみたいな使い方するようになったら家で有料無線LANやってられんと思うんだけど。

メインはパケットよりVoIP対策なのかね。でも今のとこN906iLしか対応機がないのか。ふむぅ。

とりあえず、それよりポケットUが気になる。

ホームサーバにおいたマルチメディアコンテンツがケータイ用に自動変換して見られるとは。すげぇ。こりゃ、SONYとかAppleとかと提携したらwktkなんだが。

もうiTunesに登録したAACをMP3に変換してWindowsMediaPlayer経由でWMAに変換して携帯に転送なんて面倒なことがいらないとかなったら便利だなぁ。やらなそうだけど。つかMacまた対象外かよ!

何やかんや騒がれた公衆送信権の問題とかクリアになってるのかね。これ。ギョーカイの人たちが騒ぎそうだなと思ったが。

とりあえず今後の動向が楽しみなサービスではあります。

そういやP906のホットモック触り忘れた。スペック見る限りはあんまり変わらんが、905iS程度なのだろうか。

2008/05/31

管理画面

管理画面がどうなってるのが非常に気になる。

ユーザ画面よりも管理画面と付き合うことが長いので。

とくにグルナビの沿線検索とか、Yahooのカテゴリとか。

グルナビの沿線だと、例えば新宿駅はJR、京王線、東京メトロ・・・と複数の会社があって、その中でも、中央線、山手線、総武線・・・と違う路線がある。さらに、東口、南口、西口、北口・・・と出口もいっぱいあって大変。

モデルの時点でいろいろな切り口があるし、スキーマに落としたときとか、それを実際に使うUIがどうなってるのかすごい気になる。

駅だけで何千とあって、山手線の沿線は新宿と、代々木と、原宿と・・・と検索して、さらには順番はこうとか。

うーん、サービスの本質でないし、更新頻度と作るコスト考えるとSQLでUpdateで良いじゃんと思ってしまうなぁ。

逆にお店を最寄新宿で登録したいときにどうやって登録するんだろう。「新宿駅」が山手、中央、京王、丸の内、etcに紐づくモデルということかなぁ。

検索結果が新宿(東口)1km圏内とでるということは、駅とお店に緯度経度を持たして、マッピングしているということか?

Yahooのサイトとカテゴリはどう紐付けるのだろうなぁ。ツリー構造をフラットにしてドロップダウンだとあの量だと使いにくそうだ。
ポップアップさせてカテゴリ検索画面を出すのかなぁ。

と思ったら各カテゴリの画面に登録リンクがあった。なるほどね。

どうもシステムよりから考えてしまうなぁ。使うシーンを考える癖をつけなければ。

2008/05/20

APIのユーザビリティ

ファクトリー ファクトリー ファクトリーでAPIのユーザビリティについて書いてあって非常に興味深かった。

Microsoftが実際にやっているらしい。C#のライブラリが使いやすい理由の一つにこんな理由があったとは。

最近Javaの冗長性が無駄かどうかでReader系の話があったが、あの当時オブジェクト指向といえば、SmallTalkやら、C++やら、アカデミックな世界から現場の一般人がオブジェクト指向を使い出したころ(だったような気がする)であって、使いやすさよりも純粋な(?)オブジェクト指向を貫こうとした結果だったんじゃないかなと。

FileもStreamにする抽象化とか、そのStreamでエンコーディングを指定したいならInputStreamReaderでReaderでラップすることによって文字列として扱うとかそれはそれで綺麗なつくりだと思う。綺麗なつくりと使いやすい抽象化は別であって、このAPIのユーザビリティという観点になるんだろうなぁ。最近のLLからの流れはまさしくJavaと違うTasteをもつ人なんだろう。

この記事で言っているとおりTasteは時代によって/使う人によって移り変わるので、UnmanagedCodeみたいない低レベルも使えつつFile.openで開けるみたいなラッパーを提供しているC#の設計もなるほどとうなずける。

しかし、このAPIのユーザビリティという観点は面白い。Commonsとかのライブラリ設計にも是非取り込んで欲しいし、自分の仕事で拡張性を考えるときの一つの観点として使いやすさという項目も考えたいなと思った。

# どうでもいいけど、Refrectionとか、動的定義は黒魔術だと思っている。
# 一撃必殺でライブラリとか閉じた範囲で使う分には良いけど。
# ある程度の規模の開発でみんながみんな使うのは混乱の元だと思う。

2008/05/19

CGMとか

CGMって最初はテキスト系サイト(懐かしい侍魂とか)HTMLをかけたりCGIをおいたりできる一部の人が使えたものから、MTとか誰でも簡単にBlogができて文章による表現がひろまって、携帯BlogやらTwitter、最近はYoutubeとか動画になって、さらにはニコ動で半リアルタイムにコメントによって感情を表せるようになった。

結局、CGMって個人の感動とか思いを伝えたい!っていう欲求からきていて、技術の進歩で表現の範囲が広まってきてはいるけど、まだ難しい。

たぶん今の軸は2個あって、表現の軸(テキスト→動画)、時間軸(家に帰って→携帯でとったシャメとコメントを投稿、Twitter、2chとかニコ動の祭などのリアルタイム性)なんだろうなと。

ちゃんとクリエイティブなのとかMAD制作とかは一般人には難しいので、今の最先端だと動画を起きた瞬間に投稿できるのが一番簡単で手っ取り早いということになる。

でも、感動した瞬間を撮るというのはあらかじめ準備しておくのは難しいわけで、あとからBlogに書いたりしても、本人自身忘れてたり、メディアの限界で伝えきれなかったりと難しい。テキストなら文才がなきゃ無理だし、動画でもピンポイントじゃないと編集技術がいるとか。

そこでネガティブにしか使われないドライブレコーダみたいな感じなのを個人に装着しておいて、常に記録しておいて、ここだと思った瞬間を別保存、うpできる仕組みが欲しいなと。ADVのバックログ、回想シーンみたいな。

そうすりゃ文才がなくとも個人の自叙伝ができあがり、感情をダイレクトに共有できるし、カロリー計算も家計簿も一瞬にしてできあがるスーパーだめ人間製造装置がげふんげふん。

とりあえず今日の散歩の途中で歩道の花が満開ですごく良い香りがしたので共有したかったのだが、いい写真がとれずそれを言い表す文才もなく書き綴れないのが非常に悔しかったということで。

レバレッジ英語勉強法

レバレッジ英語勉強法を読んだ。

勉強法の部分よりもその前段階の部分メンタルブロックを外すというところが心に残った。

失敗を恐れるあまりにできないということ。特に見に覚えがあるのが、中・高・大学と勉強してきて中途半端に知っているがために、これはおかしいよなぁとか、ネイティブみたいに完璧じゃないからといって恥ずかしく思ってしまい一歩を踏み出せないというのは、英語だけじゃなく日常どこにでもある罠だ。

例えばBlogのエントリーでも、セミナーで質疑応答でも、こんなのみんな知ってるかもしれないし、何を馬鹿なことを聞くんだろう?と思われてないかとか。そのあとの懇親会でもこんな話して、何を(ryとか気付けば無駄におびえてるような。

授業でも○か罰しかない教育しかなくて、子どものころから失敗を許されないがために、失敗を極端に恐れるようにいつのまにかなってるなぁと。そんなのはぜんぜん失敗でもなんでもないし、そもそも馬鹿なことだなんて思ってないはずなのにね。

そういえば最近売れてる人の本とかBlogでも失敗を怖がらないことが重要とみんな言ってるな。

(一方でアイデアに対して批判これとか、不機嫌な職場だと最近鬱っぽい話が多くてうなずけるので転んだあとの対処法を書いたら売れるんじゃないかなとか思った。最近のジュンク堂はコンピュータコーナーにも鬱病と対策が置いてあったり。)

こないだKREVAがヒップホップの魅力は「これでいいのか感」とかいってたが、何事もこれでいいんだと出していくのが重要だなと思いました。この本では欧米では平凡な意見でも言ったもん勝ち的な雰囲気があるとかなので、メンタルブロックを壊すべく完璧を目指さず楽観的にエントリーを増やしていくかなと書いた次第。

英語の勉強方法のほうは、自分の好きな/得意な範囲をやれという、最近巷で話題(?というかみんなこうじゃないのか?)の遅延評価勉強法だと思った。でもそれをアウトプットする対象の講師もその分野に強い人にするというのはExtremeでいいなというか、富豪的発想だなぁと思いつつも、そこまでやるからこそ効果があるんだなと。結構英語だけでなく勉強になった一冊でした。

英語は勉強すれどもアウトプットの場がないのが個人的な悩み。日常使うのはリーディングだけだし、スクールは高いし、重要だけど緊急じゃないに落ちて先送りな日々。

2008/05/17

docomo 906シリーズで無線LAN対応

906シリーズがもうでるのか。

NTTドコモの「906iシリーズ」は無線LAN搭載、初夏発売で高速通信と低料金を実現へ

かってサイトはどういう経路で通信することのなるのかなぁ。
今まではiモード網を経由するからIP縛りで携帯アクセスのみとかしてたサイトがあるけど、家庭網からならわざわざゲートウェイ経由して網を逼迫させる必要ないし。

まぁ、携帯からのアクセスに縛ってるサイトの理由もわからないんだけど。 ユーザビリティの観点でいえばUAで表示内容切り替えればいいだけだし、(絵文字がメンドイが)PCからしょぼい画面をみられても困らないんじゃないかと。

今後はAndroid採用だし、HSDPAで7.2Mでるし、中途半端なFlash多用とかやめて、とっとと携帯サイトって区分を捨てちゃえば良いのにって思う。親指で完結する携帯サイトの使い勝手というのは捨てがたいんだけど、そこは搭載ブラウザでなんとかできそうな気がする。

2008/05/07

RubyでExcelのWorkSheetを追加する。

rubyでExcelの操作をしていてWorkSheetを追加したいと思った。

普通に追加するなら

book.Worksheets.Add

で追加できるのだけど、末尾に追加したい場合がある。

その方法は Ruby win32ole 拡張モジュール覚え書き(5)に載っているようにハッシュでAfterに引数渡せばいいんだけどもうまく動かない。

どうやら、Before, Afterに指定するのはインデックスではなく、Sheetのインスタンスみたいだ。

ということで、シートを末尾に追加して、名前を変えたりするには

lastSheet = book.Worksheets(book.Worksheets.Count) book.Worksheets.Add({"After"=>lastSheet}) newSheet = book.Worksheets(book.Worksheets.Count) newSheet.Name = "追加したシート"

という感じになるみたい。

2008/03/30

建設とSI

建設とソフトウェアって何かと比較されることが多い気がするけれども、談合消滅後の建設業界で何が起きているかに書いてあることはそのままSI業界でも起きている気がするなぁ。

2008/03/28

スーツとか

「誰が書いても同じコード」が大事なことなのか

「誰が書いても同じコード」になることが重要で、それを実現するために、ドキュメントをいっぱい書かなくてはいけない
といった人がいるらしいが、SIerが必要としているのは「誰が書いても同じコード」が必要なんじゃなく、彼らが求めているのは「担保」なのだ。

良い品質のものを、決められた価格で、決まった期日までに提供する。所謂QCDとか言われているあれを守るために、どうすればよいかという担保が必要なのだ。

良い品質というのが曲者で、何を持ってよい品質とするか?これが問題。出来上がったものと、客が求めてるものが違えば品質が悪い→作り直し→納期とコスト超過→マズーとなる悲しい商売だ。

品質が悪いといっても検収されれば良いが、最近の開発期間の短さや金額の少なさから、ゴールが明確に決まってないのに突っ走ることが多いため、仕様なのかバグなのかで揉めることが多い。最悪は訴訟沙汰。

一般的に受注側のほうが立場が弱いため、仕様が決まってなかったにもかかわらず、客の機嫌損ねて仕事こなくなるのが怖いので、バグということでごめんなさいしちゃってデスマーチと化すことが多いんだけども。

と、横道にそれたけれども、本題にもどすと、この曖昧な品質ってやつを明文化してこれはバグじゃなく仕様だと自分自身を守るためにドキュメント化という定量化する作業が重要になってる。

あらかじめ文言の一言一句、画面のフォントサイズの一つ一つ、ドラッグしたときに出てくる妙な反転一ついちいちコミットメントをとらないと品質が悪いと怒るお客さんが大手SIの対象にしている範囲だったりする。とかISOとかめんどくさい基準が必要だったり。。。

そんなわけで、誰が書いても同じコードになるぐらいのドキュメントを書いてお客さんにコミットメントをとる結果が、プログラマをアーティストじゃなくコーダにするわけで。

さらに大手SIerだと内製しない(内製の単金が折り合わないとか、配賦の関係で内省できないとか)ので、開発ベンダの進捗報告から定量的に報告しなきゃいけないわけで、定量化するためにも基準値が欲しいし、下請けが受託開発だと個々の開発者にアクセスできないし、PMがすごい人じゃない限り、中の人で判断はできないのです。

あと最悪コードを書き直せばいいといってるけど、そこで書き直すコストを誰がもつのよ?となる。

そこが求めている機能が実装されていれば、多少変な挙動してもそんなのカンケーネーと済ませる、というかなおせば良いじゃんっていうギークとスーツの違いなんじゃないかな。

ギークが考えている技術的な問題と、スーツの考えているビジネス的な問題がちょっと違っているんだと思う。というのはちょっと語弊があるな。ビジネス的に問題ないのに問題だとするクレーマースーツが多いのか。

たぶんそれぞれの立場でなんで担保がとれないんだと怒られて自己防衛に走りまくりなんだろうな。

あそこで必要なのは個々の生産性でも、お客さんが提供してユーザが満足するサービス内容でもなく、お客さん(の担当者)が自己満足するために必要な、ソフトを構築するために必要な担保をするためのドキュメントなのだ。

そこが日本の?SIerの悲劇なんだと思う。

本来はお客さんが展開するサービスがユーザを満足させて儲かることだったり便利になることが目的なはずなんだけど、プライマリじゃない限り一個上の親受けを満足させるのが目的になってたり、プライマリでもお客さんを説得できないと残念な結果になったり。

自分でサービスを展開して自分で責任を取ってなんとかしようってして欲しいけど、なかなかそういうふうにはならないみたい。

アジャイルで欲しいものを言いながらつくればいいんじゃね?って思うけど、そうはうまくいかない。SIって構造とか、商習慣的に難しい。予算だったり。バーターだったり。政治的あれこれだったり。

上のサイトを見てて思うのは米してるのがギークだけで、スーツな視点の人がすくねぇなぁと。

つーわけでスーツな視点でビジネス的には問題ないですとお客さんを説得できなきゃSIerはやってらんないっていうかオマンマの種を自社で直接提供してない限り開発の幸せも来ないわけですよ。と嘆きながら最近スーツな俺が酒を飲みながら言ってみる。

2008/03/11

MySQL

書かれちゃったら書くしかないじゃん。

法律屋じゃないあくまで個人的な考えなのであてにしないように。あとで訴えられてもしらないよ;p

個人的にMySQLとMySQLクライアント(Java屋なのでJDBCコネクタとしよう)は別物だと思ってる。

MySQLを利用するってのはMySQLをDBとして利用する。つまり、DBMSとしてデータを格納するプログラムとして実行する。これはこれで単体のプログラムとして完結している。

MySQLのソースを改変してYourSQLとかMeineSQLとか作ろうって場合は別だが、MySQLサーバ自体を取得し、配布、使用することはGPL的にはなんら問題ないはず。(こっからもう前提が違うのかねぇ)

問題はMySQLにレコードを追加するためのインターフェース、つまりMySQLクライアントを利用したプログラム、例えば一般的な受託開発のWebアプリとか(非GPL)(以下自プログラム)を開発・提供する際にGPLにする必要があるかということだ。

LinuxはカーネルはGPLだが、システムコールの部分はGPL対象外とされているらしく、そのためLinuxのシステムコールを呼び出すアプリケーションは非GPLでも問題ないらしい。ApacheとかASLだし。

MySQLはこのシステムコールに当たるクライアントがGPLだから、MySQLにアクセスするプログラムはGPLに従う必要があるように思える。

しかし、GPLに準拠しなければならないのは自プログラムがGPLの元プログラムの「派生物」である場合である。よってここで重要なのは、MySQLクライアントを利用したプログラムが「派生物」にあたるのかどうかだ。

自プログラムがMySQLクライアントの派生物でないならば、MySQLクライアントを利用する自プログラムはGPLである必要はなく、MySQLを(ライセンスを買わずに)GPLで利用しても問題ないはず。

「派生物」の定義がGPLでは明確にされてない。(LGPLではライブラリについて定義されているが。)一般的に「派生」と言ったときには、元の「翻案」を改変したものを指すらしい。つまりMySQLクライアントには一切手を加えず利用しているだけの(基礎としているのではなく一部として利用している)自プログラムはMySQLクライアントを利用しているだけで「派生」ではないと言えるのではないだろうか。

ということでMySQLをDBとして使う普通のWebアプリケーション開発・提供はライセンス買わなくてもいいんじゃねー?と思うんだけど、こことかこことか何が何でも商用ライセンス買えってなるんだよね。

結論としては、ぐだぐだめんどくせーから金で解決できることは金で解決しちゃえば良いんじゃねー。と思うわけです。1本5万らしいです。

きっとそれがMySQLのさぁーくせんなんだな。

法律屋の見解を聞いてみたい。

ところでMySQLの例外条項にはASLならOKみたいなことが書いてあるけど、コネクタをラップしたライブラリを(例えば独立なライブラリと見せかけるためにO/Rマッパとして作って)ASLライセンスで配布して、それを非GPLなプログラムが利用する場合はどうなるんだろね。あぁこれがPHPの組み込みMySQLドライバか。

それにしてもここでMySQLを利用したプログラムを公開・配布している場合ライセンス買えになるけど、オプションとしてMySQLを使えるよってのはどうなんだよ?と。ActiveRecordとか。

ホスティングサービスで提供してるMySQLを使ってサービス提供する場合はホスティングがかね払ってるからGPLじゃなくてもいいのか?とか。

結局よくわかりませんでしたorz

#ホントこういう文書の読みにくさは異常。

#俺の読解能力が足りなすぎるだけじゃないよね?

2008/01/31

collection_selectとvalidate

collection_selectでリストを作って、選択されていないときにエラーにしようと思った。

Model

validates_presence_of :area_id

View

<%= collection_select :prefecture, :area_id, @areas, :id, :name, {:prompt => '選択してください'} %>

そしたら選択しない時にnil.mapしてるとエラーになった。ぐぐったら、createで@areasを定義してないと。

なるほど、submitしたときにcreateメソッドが呼ばれて@areasはもう無いのか。

ということでcreateメソッドのsave!で成功しなかったときに@areas = Area.find(:all)で設定してあげたら無事バリデーションエラーが表示されましたとさ。

まだまだ簡単なところでつまづくなぁ。

2008/01/29

migrationで999を超えるとどうなるのか。

ふと気になったのでやってみた。

for i in `seq 1 1000`; do ./script/generate migration test${i}; done bash: seq: command not found

osxってseq入ってないのか orz

coreutilsってのに入っているらしいというのがわかった。

これをいれるとGNUのツールが「g」というプレフィクス付きで使えるようになるらしい。(gがつくのはOSのコマンドとかぶらないためとか)

sudo port install coreutils

気を取り直して、

for i in `gseq 1 1000`; do ./script/generate migration test${i}; done ・・・ create db/migrate/999_test999.rb exists db/migrate create db/migrate/1000_test1000.rb

1000オーバーでもいいんだ。

とりあえず、もう一つつくって、1001で

rake db:migrate ・・・ == 999 Test999: migrating ===================================================== == 999 Test999: migrated (0.0001s) ============================================ == 1000 Test1000: migrating =================================================== == 1000 Test1000: migrated (0.0001s) ========================================== == 1001 Test1001: migrating =================================================== == 1001 Test1001: migrated (0.0001s) ==========================================

とりあえずOK

2008/01/03

JRuby1.1 on Rails

JRuby1.1とGlassFishでJRuby on Railsをやってみた。

Rubyの最新版をビルド

  1. NetBeans 6.0(Full)をダウンロード
  2. Versioning -> Subversion -> Check outを選択。
  3. Repository URLにhttp://svn.codehaus.org/jruby/trunk/jrubyを入力する。User、Passwordは空欄でOKでチェックアウト。
  4. OpenProjectするか聞かれたらするほうで。
  5. ProjectsにJRuby trunkが追加される。
  6. build.xmlのjarターゲットを実行

これでビルドされる。cmdでPATHを通して

>jruby -v Ruby 1.8.5 (2008-01-03 rev 5128) [x86-jruby1.1b1]

JRuby設定

  1. Tools -> Optionsで設定画面を開き、Rubyタブを選択。
  2. Ruby Interpreterに先ほどチェックアウトしたJRubyのbin\jruby.batを指定してOKボタン
  3. Tools -> Ruby Gemsを選択する。
  4. 以下のGemを追加
    • rails
    • ActiveRecord-JDBC
    • activerecord-jdbc-adapter
    • activerecord-jdbcmysql-adapter

ActiveRecord-JDBC周りはmysqlでJDBCを使わない場合はいらないらしい。

サンプルプロジェクト作成

今回はRails2.0.2のテストとしてこれを作ってみた。

  1. Projectsを右クリックしてNew Project
  2. Ruby -> Ruby on Rails Application
  3. 以下を設定。
    • Project Name: todo
    • Database:mysql
    • Access Database Using JDBC:チェックしない
    • Add Rake Targets to Support App Server Deployment:チェックしない

    最後のチェックを入れるとGoldSpikeというJavaとRoRを連携させるプラグインがインストールされるが、古いとエラーになるみたいなので最新版をあとでチェックアウトする。

    ※後述のWarを作るターゲットでprivate method `makedirs' called for File:Classというエラーがでる

  4. Projectsでtodoプロジェクトを右クリックしてRun Rake Task→db→create→allを選択。

    これでDBが作成される。rootのパスワードが設定されている場合は先に、database.ymlのコンフィグをやっておく。

  5. Projectsでtodoプロジェクトを右クリックしてGenerateを選択
  6. 以下を設定してOK
    • Genereate:scaffold
    • Model:Todo title:string body:text done:boolean due:datetime
  7. Projectsでtodoプロジェクトを右クリックしてMigrate Database→To Current Versionを選択。
  8. Projectsでtodoプロジェクトを右クリックしてrunを実行する。Webricでとりあえず動くかを確認する。

GlassFishへのデプロイ

いよいよWarにしてGlassFishに配置する。

まずはJavaEE-RoRの連携プラグインであるGoldSpikeをインストールする。

  1. コマンドプロンプトでこのプロジェクトディレクトリに移動。
  2. jruby script\plugin install http://jruby-extras.rubyforge.org/svn/trunk/rails-integration/plugins/goldspike/

    Revision 862以上ならばバグが修正されている。
  3. 動作確認のため以下のコマンドを実行する。

    jruby -S rake -T ・・・ rake war:standalone:assemble # Assemble the files for a standalone ... rake war:standalone:create # Create a self-contained Java war rake war:standalone:run # Run the webapp in Jetty

    というwarを作成するTaskがあればOK

  4. config/war.rbというファイルが追加されているので、maven_library 'mysql', 'mysql-connector-java', '5.0.4'のコメントをはずす。
  5. controller/application.rbにある

    protect_from_forgery #:secret => '043d72660fe6fea5e591c289d7751eae'

    の#でコメントされている部分から#をはずし、'043d72660fe6fea5e591c289d7751eae'の中身を変更する。

    これはRails2から導入されたCSRF対策用の設定。secretの設定値はランダム値がいいらしい。これをやっていないとNewリンクをクリックしたときにActionController::InvalidAuthenticityToken in Todos#newというエラーがでる。

  6. Projectsでtodoプロジェクトを右クリックしてRun rake task -> war -> standalone -> createを選択する。
  7. しばらくほうっておくとプロジェクトディレクトリ直下にtodo.warが生成される
  8. Production環境で実行されるので以下のコマンドでDBにmigrateしておく。

    jruby -S rake db:migrate RAILS_ENV=production

  9. Servicesタブを選択する。ServersからGlassFishを右クリックしてStartをする。
  10. ServersからGlassFishを右クリックしてView Adminconsoleを選択する。
  11. AdminCosoleがブラウザで開くのでログインする。
  12. Deploy Web Applicationを押す。
  13. Locationに生成したWarを指定してOKを押す。
  14. http://localhost:8080/todo/todosにアクセスする。

これでアクセスできるはず。

GlassFishに載せてしまうと通常のRailsのようにはファイルが簡単に更新できなくなるので手元でWebricとかで開発して運用はGlassFishみたいな使い分けが必要だなぁ。