2008年11月24日月曜日

第13.8回Grailsコードリーディング(その4) Grails本気の入門~2時間でいけるところまでライブコーディング!?をまとめてみました



でもって、この辺で「製造元の情報は表示はするけど、編集とか新規登録は一定の人間にしか触らせない」ということを実現するために、認証機能を付けてみます。


25.Acegiプラグインを入れる。
Acegiについては、第5回GCRの山本ざっくりメモを参照してください。
当日は、ver.0.3でやりました。
・Acegiのインストール

$ grails install-plugin /ダウンロードしたディレクトリ/grails-acegi-0.3.zip

・下記二つ実行

$ grails create-auth-domains
$ grails generate-manager

そうすると、grails-appの中に、いろいろ出来てきます。
でも今回は一切触りません。あるユーザ権限を持つユーザのみが??を操作できるというような感じにします。



この辺で、いちいちrun-appの度にデータがクリアされるのが面倒なのでDataSource.groovyをちょっとだけ書き換えて、登録したデータが残るようにします。

development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop','update' //create-dropからupdateに変更
url = "jdbc:hsqldb:file:devDB;shutdown=true"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDb"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:file:prodDb;shutdown=true"
}
}


Acegi-pluginを入れたところからは、Grailsインストール+簡単な認証付きアプリをサックリ作成して動作確認。を参考にしてください。

今回の場合、Companyを触れるユーザと触れないユーザを分けたいので、
roleを「admin」「user」と2つ作って、適当な2人のユーザを作って、それぞれに割り当てます。最後にRequestmapで、/company/**をadminだけにすると、userのroleしか持ってないユーザは、そのページに行こうとしても「権限ないよ」と言われます。

で、適当なプロジェクトですけど、Morphに上げますので、そこで動作を見てください。



この辺で、TagLibをちょっと。というか、scaffoldしたときの日付表示が英語っぽいので、表示を逆にしたTagLibが社内にあったので、こっそり流用。山本師曰く、順番逆にしただけ、らしいです。
どこかにソースを上げておくと思うで、興味がある人はそこで見てみてください。
item.groovyの中のreleaseがDateなので、これを日本人が見てわかりやすいようにしてみます。
で、ここで、GSPがないと書き換えられないので、generate-allして、views/itemの下に、create.gsp
list.gsp
show.gsp
edit.gsp
を書き出します。


grails generate-all item



create.gspとedit.gspの下記をちょりっと修正します。

<!-- <g:datePicker
name="release"
value="${item?.release}" ></g:datePicker> -->
<ex:datePicker name="release"
precision="day"
years="${2000..2050}"
value="${item?.release}">
</ex:datePicker><br/>



こんな感じです。


もうひとつ、表示している方のshow.gspもちょりっと直します。

<!-- <td valign="top"
class="value">${fieldValue(bean:item, field:'release')}</td>
-->
<td valign="top" class="value">
<g:formatDate date="${item.release}"
format="yyyy/MM/dd" /></td>




これで、なんとなく違和感があったところが修正されました。

これぐらいで、一回Morphにアップしようと思います。
http://mkawa.morphexchange.com/
ここだと、URLにgcroneがつけられない?ので、HOMEとかクリックすると、出ません。適当にURLを変えてみてください。一通りできます。
ユーザも制限かけてないので作れます。

第13.8回Grailsコードリーディング(その3) Grails本気の入門~2時間でいけるところまでライブコーディング!?をまとめてみました



と、こんな感じでふとお客さんを見ると、多分「?」です。自分の仕事にはまだ合致していない模様です。
だいたい、「Company:1」って、まずそこで違和感ありますよね。なので、ドメインクラスにちょっと細工します。多分、これは最初からやっておいた方がいいと思います。

22.ID表記されているところを見やすくしてみます。
それぞれのドメインクラスに下記のように追記します。
Item.groovy

class Item {

static belongsTo = [company:Company]

String name
String spec
Long price
Date release

static constraints = {
name(blank:false)
spec(maxSize:4000)
price(max:10000L)
company()
release()
}
String toString(){ //ここから追記
return name
}
}

Company.groovy

class Company {

static hasMany = [items:Item]

String name
String note

static constraints = {
name(blank:false)
note(maxSize:4000)
}

String toString(){ //ここから追記
return name
}
}

toString()を使って、そのままnameを返す、ということをしています。
こうすると、下記のように、ちゃんと名前を返してくれるようになります。returnのところには、Groovyで色々かけるので、計算させたりとかもOKです。ドメインクラスとして持たせておいた方がよいものは、ここでやってしまうのも手です。
・商品を登録するところ(セレクタに「ニューキャスト」と出ている)


・商品情報を表示したところ(companyのところに…)


・製造元情報を表示したところ(Add Itemのところに「南天のどあめ」と出ている)




これでなんとなく「へー」から「なるほどね」と、ちょっとお客さんとプログラマが近づいた感が出るかもしれません。
ここで、もう一発、ぐっと近づけるために、フィールド名を日本語で表記させてみます。

23.i18n-templatesを使って、日本語表記にしてみる。
ですが、ここはなんとGCR当日に偶然にも上原さんが書いていたので、そっちを参考にしてください。
■[Grails]好きなGrailsプラグインシリーズその1 i18n-templates
★ちなみに、僕のは今Grails自体が1.0.3なので、grails install-plugin i18n-templateをしたときに、1.0.4を拾ってきてしまいます。そうすると、例えばcreateを開くと、create.jpsとか無いよ、って言われましたので、前に拾っていた1.0.3のPluginを入れると正常に動作しました。途中でPluginを入れ替えたけど特に問題ないのはなぜ?
ちなみに、今回の表記を変更したものはこんな感じです。
grails generate-i18n-messages item及びcompanyで吐きだしてくれたもの

home=Home
create=Create
edit=Edit
update=Update
delete=Delete
delete.confirm=Are you sure?

# Item messages
item.create=Create Item
item.edit=Edit Item
item.list=Item List
item.new=New Item
item.show=Show Item
item.created=Item {0} created
item.updated=Item {0} updated
item.deleted=Item {0} deleted
item.not.found=Item not found with id {0}
item.id=Id
item.name=Name
item.name.blank.error=Property [Name] of class [Item] cannot be blank
item.name.nullable.error=Property [Name] of class [Item] cannot be null
item.spec=Spec
item.spec.maxSize.error=Property [Spec] of class [Item] with value [{2}] exceeds the maximum size of [{3}]
item.spec.nullable.error=Property [Spec] of class [Item] cannot be null
item.price=Price
item.price.max.error=Property [Price] of class [Item] with value [{2}] exceeds maximum value [{3}]
item.price.nullable.error=Property [Price] of class [Item] cannot be null
item.company=Company
item.company.nullable.error=Property [Company] of class [Item] cannot be null
item.release=Release
item.release.nullable.error=Property [Release] of class [Item] cannot be null

# Company messages
company.create=Create Company
company.edit=Edit Company
company.list=Company List
company.new=New Company
company.show=Show Company
company.created=Company {0} created
company.updated=Company {0} updated
company.deleted=Company {0} deleted
company.not.found=Company not found with id {0}
company.id=Id
company.name=Name
company.name.blank.error=Property [Name] of class [Company] cannot be blank
company.name.nullable.error=Property [Name] of class [Company] cannot be null
company.note=Note
company.note.maxSize.error=Property [Note] of class [Company] with value [{2}] exceeds the maximum size of [{3}]
company.note.nullable.error=Property [Note] of class [Company] cannot be null
company.items=Items
company.items.nullable.error=Property [Items] of class [Company] cannot be null

書き換えたもの

home=Home
create=追加
edit=編集
update=更新
delete=削除
delete.confirm=本当に消しちゃうの?

# Item messages
item.create=商品の新規登録
item.edit=商品情報の編集
item.list=商品リスト
item.new=新規登録
item.show=商品情報の表示
item.created=商品 {0} を新規登録しました!
item.updated=商品 {0} を更新しました!
item.deleted=商品 {0} を削除しました…
item.not.found=商品ID {0} は見つからないぞもし
item.id=Id
item.name=商品名
item.name.blank.error=商品名は入れてくれないと登録できませんよ。
item.name.nullable.error=商品名は入れてくれないと登録できませんよ。
item.spec=詳細情報
item.spec.maxSize.error=ゴメン…詳細情報は、4000バイト以上は入れられないんだ…
item.spec.nullable.error=詳細情報入れてよ
item.price=価格
item.price.max.error=価格は、10001円以上は、入れちゃダメなんだ…
item.price.nullable.error=価格はいれなきゃダメなんだよ。
item.company=製造元
item.company.nullable.error=製造元はどこですか?無いわけ無いでしょ!
item.release=発売日
item.release.nullable.error=発売日はちゃんと入れてよね…もう…聞いてんの!
# Company messages
company.create=製造元の新規登録
company.edit=製造元情報の編集
company.list=製造元リスト
company.new=製造元の新規登録
company.show=製造元情報の表示
company.created=製造元 {0} を新規登録しました!
company.updated=製造元 {0} を更新しました!
company.deleted=製造元 {0} を削除しました…知らないよ…
company.not.found=製造元ID {0}?しらねえな…
company.id=Id
company.name=会社名
company.name.blank.error=会社名なしは、あり得ん!
company.name.nullable.error=会社名なしは、あり得ん!
company.note=備考
company.note.maxSize.error=ゴメン…言ってなかったかな。詳細情報は4000バイト以上は入らないんだよ…
company.note.nullable.error=詳細情報は入れてよね。
company.items=製造商品
company.items.nullable.error=商品がないけどいいの?よくないでしょ…

そうすると、下記のように日本語になってくれます。
上原さんも書かれてますが、僕はプロトタイピングのところで、お客さんのイメージできるものを作りたいので、とても重宝しています。そしてgenerate-allとかでViewを吐いた後も、使い続ければ、用語統一がしやすいです。
そうすると、こんな感じです。とりあえず商品登録で、バリデーションエラーを発生させてみました。

出来る限り柔らかくメッセージを書いたつもりでしたが、数行に渡って連発で怒られると、ちょっとヘコみます。気をつけましょう。



と、やっと、この辺でぐっと、また距離が近づくかもですね。

24.「あ、今更だけど、型番入れないといかんわ、ゴメン」
そうですね、そういうのにも対応してあげましょう。
じゃないと、ライブコーディングの意味ないですよね。
型番は大事なので、必須にしておきます。
Item.groovy

class Item {

static belongsTo = [company:Company]

String name
String modelNumber //追加
String spec
Long price
Date release

static constraints = {
name(blank:false)
modelNumber(blank:false) //追加
spec(maxSize:4000)
price(max:10000L)
company()
release()
}
String toString(){
return name + "(${modelNumber})" //ちょっと変更。商品名(型番)で表記されるように。
}
}




追加変更も簡単にできるんだ、と思わせつつ、本当は、この辺がGCRでも盛り上がりましたが、RoRのようなmigrateの機能がないというところ。ずーっと使い続けるには、上記のようにフィールドの変更があり得るので、そういったバージョンアップのときに、migrationして整合性を調整しつつ、永続的に使用できるようになってるといいのに、という話がありました。確かにそうなんだけどなあ、でも、大将山田さんも山本君もやろうと思えばできるでしょうね、って言ってたので、できるんだろうな。前のGroovyコンファレンスの後でもそういう話あったんだよなあ。実際どうなんだろうな。確かにインデックスの再構築とかいろいろあるんでしょうね。

と、一応こんな感じで、表示されます。ちょっと分かりやすいですね。


modelNumderというフィールドを追加したので、手動でi18n-templateのファイルに書き込んでもいいですが、もう一回、grails generate-i18n-messages itemをして、差分だけコピペして入れてもいいと思います。

その4へ続く

第13.8回Grailsコードリーディング(その2) Grails本気の入門~2時間でいけるところまでライブコーディング!?をまとめてみました

7.Grailsロゴの下に、ItemControllerというリンクがあるので、クリックするとItemListページが表示されます。


8.新規登録してみます。
メニューバーのNew Itemをクリックすると、新規登録ページが開きます。


適当に入れてCreateボタンをクリックすれば登録完了のページが表示されます。

※priceは入れないと、nullは許してないよ、っていわれますのでそれは後述参照で。


9.登録データの表示画面でEditをクリックすれば、再編集ページになります。
ここで編集してupdateボタンをクリックすれば、データは更新されます。deleteをクリックすればデータは削除されます。メニューバーのItemListをクリックすれば、登録したデータがリスト表示されます。デフォルトでは11件以上のデータを登録すると次ページに飛べるようなページネイトが表示されます。


ちなみにリストの各ヘッダをクリックすると、昇順降順がソートされます。
下記は、priceをソートしたところ。

ここまでで商品データの登録、確認、再編集、更新、削除、リスト表示が確認できます。



で、大抵この辺までで、最速なら5分ぐらいでいけるはず。
お客さんの反応は、まだ「へー」ぐらい。ここで乗ってくるのは、プログラムに興味がある人ぐらい。
「あのさ、エクセルのとき、名前は入力してないといけないとか、やってたな。
あと、1万円以上の商品は無いんだよね、まえ間違えちゃって怒られたよ業者にさ。
ああ、でも決まってないときもあるなあ。。。
それとこのSpecってのは、もっとたくさん文字はいるよ、こんなんじゃ収まらないねえ。」

10.次にバリデーション(フィールドの制約)を付けてみます。
nameは、商品名なので必須にします。
ドメインクラスのItem.groovyを開いて、constraintsを追加します。

class Item {

String name
String spec
Long price
Date release

static constraints = {
name(blank:false) //必須入力
spec(maxSize:4000) //textareaになる
price(max:10000L,nullable:true) //10001以上はだめだよ,nullでもいいよ
release()
}
}

ちなみに、このconstraintsに書いたフィールドの順番で、scafflodされたViewの中の表示・入力の順番が変わります。何も書いていないと、フィールド名のアルファベット順(name→price→release→spec)になります。
priceは、Integerにしてあると、10000だけで良いようです。Longだと10000Lと、明示してあげないといけないようです。



「この日付のとこさ、年月とか逆になってるよ。」
「それ後でやりまーす。その前に、商品って自社もあるけど、業者さんのもありますよね」
「ああ、そうそう。100社あるかないかぐらいだね。そうだよ、そこがパスワードかかってて変えられないんだよ、失礼なこった。」

11.製造元をComanyとしてドメインクラスを作ります。

$ grails create-domain-class company


12.会社名と、備考欄ぐらいの簡単なフィールドと、商品(Item)との関連付けを定義します。
折角なので、会社名は必須に、備考はテキストエリアにしてみます。

class Company {

static hasMany = [items:Item]

String name
String note

static constraints = {
name(blank:false)
note(maxSize:4000)
}
}

hasMany = [items:Item]とすることで、Companyには、itemsとして、Itemがいくつかぶら下がってますよ、ということになります。

13.商品(Item)にも、その関連付けを定義します。
Item.groovyに2行追加します。

class Item {

static belongsTo = [company:Company] //追加

String name
String spec
Long price
Date release

static constraints = {
name(blank:false)
spec(maxSize:4000)
price(max:10000L)
company() //追加
release()
}
}

同じ商品を、違う業者が製造していることはないので、1対多になります。



おっしゃ、ちょっとここまでで3分ぐらい経過しているかもしれないので、お客さんは「?」になります。そうならないように、「しゃべり」をこの辺で入れるのも大事です。
これで製造元の登録を見せよう、と思っても、ちょっとまった。
多分後ろから須江さんが「…Controllerが無いよ」とささやいてくれますので、落ち着いて次の行動に。

14.Companyコントローラーを作成し、Itemのときと同じようにscaffoldを定義します。

$ grails create-cotroller company


class CompanyController {
def scaffold = true
}


15.今まで作ったItemとCompanyがどんな感じになっているか、ここまでの動作を確認してみます。
もう一回run-appして、ブラウザを確認すると、新しいコントローラー(CompanyController)が出来ています。


16.製造元の会社を登録してみます。
CompanyControllerをクリックして、New Companyをクリックすると、新規登録画面が表示されます。


17.Createボタンで登録され、Show画面(登録した内容の表示画面)に切り替わります。


18.Editボタンをクリックしてください。編集画面が表示されますが、その中のItemsのところに、「Add Item」というリンクボタンが表示されています。


19.Add Itemをクリックすると、Itemの新規登録ページに切り替わります。


20.Createボタンをクリックして登録すると、Show画面になります。


21.ここにある「Company:1」をクリックすると、CompanyのID:1のShow画面になります。
ここで、「Company:1」に、「Item:1」がちゃんとぶら下がりました。
下は、Editボタンをクリックしたところです。


その3へ続く。。。

2008年11月20日木曜日

これは思わず見やすい

GCRの概略を書いておこうと思いつつ、コード載せるのが面倒でしかも見にくいなというところで、鰯のテクニカルノートさんのところを参照にしてみました。

これは見やすい!



class Company {
static mapping = {
table "T_COMPANY"
id generator:'sequence', params:[sequence:'company_id_seq']
}

String name
String description

String createdUser
String updatedUser

Date dateCreated
Date lastUpdated

static constraints = {
name(nullable:false)
description(nullable:false)
createdUser(nullable:true)
updatedUser(nullable:true)
}
String toString(){
return name
}
}


2008年11月19日水曜日

第13.8回Grailsコードリーディング(その1) Grails本気の入門~2時間でいけるところまでライブコーディング!?をまとめてみました

はぁ〜、終わりました。ってかもう三日たっちゃった。。。
書き出したら長くなってしまったのです。

Javaとか、Webアプリケーション開発の根本的な知識がない、よく分かってない人のために、よく分かってない人がライブコーディングをするというおかしなGCRをやって参りました。

Grails初心者でも簡単なWebアプリケーションをその場で本当に作れるのか、ということで、よく分かっている人がやっても意味がないとので、よく分かってない?私目がやらさせていただくことに。。。おいおい。。。

題材
商品管理っぽいものでやってみました。
商品には、製造メーカーが関連付いているイメージです。

僕なりのポリシー
お客さんのところで開発できるぐらいのレベルで考えているので、細かいところは抜きにして、ある程度形として目に見える、動かせるものを目指します。
なので、scaffoldオンリーでコントローラーには手をいれない方針でいきます。

Pluginを使う
せっかくなので、Grailsで公式リリースされているPluginを入れてみようということで、お客さんのイメージを視覚的に盛り上げるi18n-templates-plugin(表記を日本語にしてみるだけですが)と、管理者と一般権限でユーザに機能制限を与える等のユーザ認証機能を持たせてくれるAcegi-pluginを入れてみました。

TagLibを使う
日付表記がいっつも違和感があるので、社内で使ってるのを使ってみます。別にたいしたことはしてないそうです。日本人向けに表記順番を変えただけだそうです。

実際のGCRのときのPDFはほとんど「僕はプログラマではなくて、どっちか言うと営業っぽい感じですよ、何もできませんよ、でも1年ぐらいはやってますよ」っていう内容ですので、みてもしょうがないかもです。
ただ、ライブコーディングなので、これはやっぱりコミュニケーション、お互いの理解が必要だと思って前段で、まずたっぷり言い訳しておきました。

実際は、簡単なWebアプリケーションを作ってみただけなのですが、そのまま書いても普通のQuickStartと一緒になっちゃうので、ちょっと僕なりの脚色を加えてまとめてみました。

Grailsを使った簡単Webアプリケーション構築のターゲットのお客さんを想定してみる。
男性 40台前半 商品を卸している会社の課長ぐらい?
この男性は東京在住20年目だが、実は名古屋出身で、たまに名古屋弁が出てしまう、ちょっと乱暴な物言いだけど根はいい人で、付き合って2年ぐらい、という感じ。実在しません、あしからず。。。


エクセルでうちの商品の管理してんだけどさあ。A君がVBマクロっての?なんかよーわからんことしとって、そのままやめちゃったんだよねえ。

この前去年の探そうと思ったら一苦労したよ。どこにあるかわからねえから、電話しちゃったよ、A君に。ああ、教えてくれたよ。面倒くさそうに「あそこにあるんじゃないですかぁ」だってよ。今までどんだけ世話してやったかっての。虚しいねえ。。。

そんでもってパスワードかかってるのもあるし、開かねえときたもんだ。。。
ついでに「あくせす」だっけ?なんかデータベースっぽいのにしたらって、事務のねえちゃんが言うんだよ。前の会社はそうしてましたって。知るかってんだ、なあ。

でも、これがねえとさ、困ることもあるんだよねえ。いや、たまにだけどね。もともとちゃんと使ってねえしさ、だって何か触ってエラいことになったら、困るし。なんか良い方法ないかねえ。

あ、お金ならかけらんねえよ。だって、おまえこの不況だぞ。おお、そうだ、上司に愚痴ったらよ、なんとかシステムって会社のわけわかんねえ兄ちゃんを連れてきてさ、要件を教えてくださいってさ。なんだよ、こっちが聞きてえよ、何しに来たんだよってなあ。んでオレも真面目だからさ、一生懸命話した訳よ。したらおめえ、見積もりが来て腰抜けちゃったよ、1000万だと。最初に言えっつんだよなあ。まあせめて100万ぐらいとかさ、だいたい10人もいねえ会社で1000万円ったら1月分売上だぞ。社長に言ったら飛び降りちまうぞ。だからA君クビにしちゃダメだって言ったのに。それみたことか、だよなあ。

んなことしてばっかりだから、いつまでたっても忙しいばっかでさ、先がねえよ。
ホント、オレもケツまくるかなあ。。。

でもさ、いい商品もってんだよね。また新商品考えてみたんだよ、これこれ見て、すげーだろ、コレがなんと9,800円!ほら、欲しいでしょ、キタ?お友達価格で今ならなんと…


売られそうになるので一旦停止して、診断内容をまとめると、
・エクセルで商品を管理していた
・VBマクロを使って計算する部分を作った人がいなくなった
・ファイル管理ができてない
・パスワードを使って、触れる人を制限して安全に扱うべきデータもある
・操作に若干の拒絶反応あり
・システム屋に、やりたいことを全部いったら、見積もりが高すぎて無理
・全社員10人ぐらい、多分使う人は限られている。

こういうタイプのお客さんには、難しいことや金額的な話をしても意味がないので、
「イメージに合うかどうか分かんないけど、ちょっと今から作ってみますわ」と、ライブコーディングを始めてみる、という流れでいきませんか。いや、いきましょう。
多分この課長さんも1時間ぐらいは時間とれるだろうし、相談に乗って想像で話しするより、何か作った方が早くないですか、的なノリです。
でもって、このお客さんが「もしかしたら自分でもできるかも?」と思ってくれたら素晴らしいですね。

※アプリケーション名は、当日「Gcr One」と上原さんが命名してくれました。

1.gcroneというGrailsプロジェクトを作成します。

$ grails create-app gcrone

その後、cd gcroneで移動します。ちなみによく移動を忘れます。今回も。。。
※インストール、QuickStartとかはこっちをみてください。

2.商品データとして、Itemというドメインクラスを作成します。

$ grails create-domain-class item

実行すると、/gcrone/grails-app/domainにItem.groovyが作成されます。



で、お客さんに聞いてみる。「商品って、名前とその詳細と価格と、あと何が必要です?」
「ああ、発売日がないといかんね、商品名だけでわからんから」

3.商品データのドメインクラスにフィールドを定義します
エディタでItem.groovy開いて、商品名、スペック、価格、発売日のフィールドをそれぞれの型で作成します。

class Item {

String name
String spec
Long price
Date release

}

※priceはIntegerでもいいと思いますが、あえて失敗したいので。

4.とりあえずScaffoldしたいので
データ登録、編集、削除、リスト表示を確認してみます。
なので、まずその機能を与えるためのコントローラを作成します。

$ grails create-controller item

実行すると、/grails/grails-app/contollersにItemController.groovyが作成されます。

5.Itemコントローラーにscaffoldを定義します。
今作ったコントローラーItemController.groovyを開いて、
def index...のところを下記に置き換えます。

class ItemController {
def scaffold = true
}

※trueのところはItemでもいいですが、どうも挙動がそれぞれで異なるようです。詳細はまだ調べてなかったです。はい。

6.一回ブラウザでみてみます。
まずは何も考えずにgrails run-appでWebアプリケーションを動作させてみます。
立ち上がったら、http://localhost:8080/gcroneをブラウザで開きます。

$ grails run-app

正常に起動すれば、ターミナルにだらりと起動メッセージが出た後、最後に下記が出てきます。

Server running. Browse to http://localhost:8080/gcrone

成功すると、多分下記のような画面が表示されます。


その2へ続く。。。

2008年11月17日月曜日

JAGATセミナーしてまいりました

「オリジナルスクリプトを使った自動組版」というタイトルでJAGATさんでセミナーをさせていただきました。
WakuScriptについて言えば、初めての一般公開なので、分かりにくかったと思いますが、本来分かりにくいというか、ここまでの歴史を知らないと、なんでWakuScriptなのか分からないと思うので、そういうつもりでお話させてもらいました。

資料は、NCの本サイト(近日Ploneからコンフルエンスに差し替えます)に一応載っけてあります。ご参考に。

前の枠で、(株)フィットの藤原さん(お久しぶりでした)から自動組版についていろいろお話していただいたので、だいぶ省けました。ありがとうございます。マニュアルとか昔からやっていて、うわぁがんばってんなぁと圧倒されつつ、我々(tyama氏も同席)の方は、いつものように幾分まったりと…いやいや真面目に話ししてきました。

セミナーでもお話しましたが、我々は組版エンジンのメーカーではありません。作りたいですが、そんな時間と資本がありません。我々ができることは、Web開発の技術と、組版技術をどうつなげるか、つまりデータをどう扱うか、というところがテーマです。Web開発の技術といっても、WWWの世界だけの話ではなくて、企業内でもWeb技術を使ったイントラシステムとかあるわけで、全く違う世界の話ではありません。という我々も印刷・出版業界の中ですから。このWeb技術は、ユーザとユーザを繋ぐ、ユーザとシステムを繋ぐ、という点では、なんら敬遠する理由のない技術です。そして、とても面白い
こういう技術を使って、堅苦しく、そして大がかりなシステム構築をするのではなくて、楽しみながら、効率化やコスト削減などにチャレンジしてみてはどうかな、というのが言いたかったことです。

明日は、Grailsコードリーディングで、自分の番なので、今日失敗した?(してないよ)ライブコーディングをまたやって来ます。興味のある人は、月1回やってますので、http://groups.google.com/group/grails-jaに情報がありますので参考にしてください。

2008年11月12日水曜日

DTP作業効率の向上努力と品質の関係

うちだけなんでしょうか。。。

新人君が作成した図版が校正を通らずにそのままお客さんのところに行ってしまって、初校戻りのゲラが真っ赤っかで戻ってきました。
本人も落ち込んでいるわけですが、問題はどこにあるんでしょうか、ちょっと考えてみました。

この話が持ち上がったときに出た言葉は、だいたい次のようでした。
1.まず、「これでいいですか」と聞かなかった図版作成者が悪い
2.図版作成者に頼むときに、ちゃんと指示しなかった作成依頼者が悪い。
3.仕上がった図版データをちゃんと見ずに貼り付けた組版オペレータが悪い
4.内校を飛ばして、納品してしまった営業が悪い

僕が思うのは、これは、印刷事故に匹敵する制作業務における重大な過失であります。
印刷事故をここでは印刷された後に発覚する間違いとします。これはこれであってはいけないことですが、印刷物として残りますので、「注意して作業します。。。」という反省文も付いて事故報告書として扱われると思います。
しかし、制作を生業の中心としているうちにとっては、制作作業中におけるこういった問題の方が重要度は高いです。なので敢えて過失と言っています。

誰が悪いとかいう問題ではなく、会社全体の問題です。

この問題が引き起こしたものは時間的損失信頼低下です。
制作業務は、作業工賃でご飯を食べさせてもらっているわけで、作業時間を如何に削るか、つまり如何に効率よく作業するかが重要です。
ページ単価の中には、一定水準の品質を保つための料金が含まれているわけで、その単価に見合う時間でやる努力をしなければいけないわけです。とんでもない品質を通常品質にするための修正時間、校正時間など含まれているわけがありません。むしろ通常品質からさらに品質を上げる努力をしなければいけません。

そこで、「うん、分かりました。効率よく作業をしなきゃ!」と考えたときに、「作業を分担すりゃいいじゃん」ということがアタマに浮かびます。

「あんたはこれやって」「オレこれやるからさ」

この言葉だけで、高い品質が保てるのは、
・かなりの経験と上級の技術を持っているオペレータ同士
・組版センス、デザインセンスを持っているオペレータ同士
・普段お互いの作業の仕方、仕上がり具合を熟知し合っているオペレータ同士
だけです。

こういう中でやっと、「効率化」というのが生まれるわけです。
効率化とは、マニュアルを作り、それ通りにすることが全てではありません。
作業がマニュアル化されたところで、それは基本線であって、効率化の大前提とする部分ですから、その上にある「品質を守る、向上する努力」を忘れてしまっては、何も意味がない、効率化なんて出来るわけがない、ということです。

「出来るオペレータ」の中では、何を作るときでも「高品質」が当たり前であり、そのためには、何が必要か、何をしてはいけないか、ということを今ままでの痛い経験や新旧の技術から知っています
効率よくやることが、品質を上げる、ということを知っているわけです。
もうちょっと違う言い方にすると、
品質を上げるためには、どうやって効率よくやるのがいいのか、ということを常に日頃考えている、ということです。

前述したように、制作作業は、作業工賃をいただく仕事です。すごい時間をかければ、ちゃんとできるかもしれません。でもそんな「すごい時間」にお金を払ってくれるお客さんはいません。だって、出来ない人、出来る人に、頼んだときに、お客さんは最終の仕上がりが同じであればいいわけです。出来る人が1時間でやった仕事を、できない人が5時間かかった、というとき、じゃあ出来ない人が多く工賃もらえますか、っていうと「そんなんありえへん」ですよね

よく言うんですが、制作作業というのは、「効率よく」やることが前提の仕事なんです。
でも、この「効率よく」が何のためかというと、「品質を上げる」ことなのです。

そうはいっても、社内では、技術の差、経験の差は必ず存在します。
市販の教則本だけでできるようになる仕事ではありませんし、ある部分だけをちょこちょこやって「おいらはDTPオペレータだぃ」と言うのもありえません。
教える側もそうです、基礎を教えたところで「よしもう一人前だな」なんてこともありません。

先ほどの仕事を始めるときのやりとりが、この差があるオペレータ同士でなされた時、どんなことが起こるでしょうか。

・頼んだ人のイメージと、仕上がりのイメージが「なんか」違う
・頼んだ方は、分かっていることを前提に渡したのに、「意外と」分かっていないかった
・「想像以上に」時間がかかっている

多分、こんな感じだと思います。
こういう状態では、効率化も図れないし、品質も上がることはありませんし、かえって品質の低下、時間超過などの問題を引き起こします。

じゃあ、仕事を頼むとき、頼まれるときにするべきやりとりの内容をマニュアル化して、実行しよう、というのもちょっと違います。そういう話し合いも必要だとは思いますが、それをやってしまうと、マニュアルが中心であり、この問題の解決が「マニュアルを作ること」に意識がいってしまい、「マニュアルが完成したらこの問題は解決だ」と、勘違いをしてしまいます。問題が発生する根本的な原因は、もっと違うところにあるはずです。

全く一緒の作業で出来る仕事であれば、そういったマニュアルの徹底によって、何も問題ないんですが、制作作業はそうではありません。

日々の仕事において、様々なタイプの作業が流れてきます。日々流れている仕事の中で、どのようにすればよいのでしょうか?

それは、常に、お互いが品質を上げる事を目的として、

・お互いの経験と技術を理解する
・お互いの組版センス、デザインセンスを理解する
・お互いの作業の仕方、仕上がり具合を理解する

ことができれば、制作作業という現場の中でコミュニケーションしながらお互いに成長を目指せる。これがDTP制作の仕事の中で最も重要なことであり、品質の向上、効率化が達成できるのでははいでしょうか。

つまり、品質を守る、向上するという、仕事をもらって作業するにあたって一番最初に考えないといけないことの上に、効率化があり、そしてそれを作り出すのは、それぞれの作業者が周りとの理解を深め、相乗的に技術の向上を図ることではないでしょうか。

そして、こういうことがあるからこそ、制作作業は、面白い仕事になるんじゃないでしょうか。

2008年11月10日月曜日

ヘルパー2級のセミナー修了証授与式

6月中旬から約4ヶ月ぐらいですか、16名の方が受講されて、11月10日無事修了証授与の運びとなりました。

それぞれの方々が一言ずつ感想を言う場面があったのですが、いろいろな境遇の中、それぞれの動機があって始められたわけですが、印象に残ったのは、「●●さんがいたから続けられた」というような言葉が多かったことです。
座学と、実習の両方をぎゅっと凝縮して行うわけで、それぞれの生活の中で、それを最後まで乗り切るのは大変だっただろうなと、本当に思います。朝早くから、夜遅くまで。そして体力も知力も使いながら。

みなさんそれぞれ、もう諦めようかな、本当にできるのかな、と思ったそうですが、他の人の頑張りが励みになり、なんとか全員で修了までいくんだという気持ち、それぞれがそれぞれを思う気持ちが合ったからだろうなと思います。

介護事業部では、またやりたいそうですが、体力が持つかどうか、というところらしいです。
もう、これは本体側の僕たちも全面協力します、というか、やらせて欲しい、と心に誓ってきました。

JAGATで11月17日にWakuScriptの話してきます

マニュアル・フリーペーパー制作の自動化で、正式に出てますが、ひょんなことから依頼を受けましたので、快諾させてもらいました。

テキスト&グラフィックス研究会のセミナー枠の中です。
2008年11月17日 15:00-16:00 「オリジナルスクリプトを活用した自動組版」というタイトルです。WakuScriptの産みの親のtyama氏も同行します

フィットさんも前枠でお話されるんですよね、そっちも興味あり。ひっさしぶり、覚えてるのかな。

主な内容は、どうなるか分かりませんが(まだ資料作ってないので)、だいたい以下かなと。
1.なんでWakuScriptが生まれたのか
2.これからの自動組版システムはどうあるべきなのか

といった、ところが中心になるかと。

簡単に宣伝だけしておくと、WakuScirpt形式のデータで投げると、出力させたい組版エンジン用に変換されて組版ができる、というもので、この業界待望の中間言語という扱いになります。ホントかどうかは見に来てください。
すでに2,3社で動いてたりしますので、現実的な話も踏まえてできるかなと思います。

製品というわけでもなく、概念的な意味合いが強い仕組みですね。はい。

GlassfishでGrailsアプリを動かしてみる

なんも無いとこから5分でGrailsをGlassFish v3 Preludeに・・を試してみたメモを参考に試して見ました。ホントに5分でできるんかい。

まず、Glassfishってなんぞや、の人は、
Sun,Javaアプリ・サーバー「GlassFish」新版でJava EE 6の機能を先取りを見てください。

「GlassFishはモジュラー・アーキテクチャを採用する軽量なアプリケーション・サーバー」だそうです。
うちの案件でも2件ぐらい納品されてるんじゃないかな。。。
自動ビルドとかHudsonでやって、こっちに連携とかさせてるんだよねえ、確か。。。
Hudsonを使ったアジャイルな開発入門を後で見てみよう。っていうかyossyがやってたな。。。試してみよう。

手順は、上述通りですが、確かに5分でできますね。

2008年11月2日日曜日

「組版」と「DTP」の違いについて考えてみる

最近研修生も来ていることだし、社内で飛び交う「組版」という言葉と、やっぱり「DTP」という言葉が、「組版」とイコールかと言われると、ちょっと違う気がするので、その違いについて考えてみようと思います。

「組版」という言葉の説明については、ウィキペディア先生に 任せるとしますが、この記事を書かれた方は、TeXユーザなのかな。DTP化によって、組版の基礎知識のない人間でもできてしまうことが、全体的な質の低 下に繋がっているというようなコメントが書いてありました。それもそうだと思うのですが、基礎知識ってなんだ、と考えてみると、基礎学習のためのマニュア ルのようなものを想像してしまうのですが、それを覚えればいいのか、というとそうでもない気がします。

僕たちの制作の仕事は、どちらかというと、いわゆるページ物が多いです。
チラシっぽいのも昔はやっていたのですが、どんなものでも仕上がりや、技術的なところに拘りを感じていたので、難しい、手間のかかるものは、うちに頼む、みたいな感じで依頼されることが多くなりました。その結果が今いただいている仕事です。
なんでかなあと考えてみると、もともと情報処理の発想から入っている点が挙げられると思います。

先生の言うとおり、「文字や図版などの要素を配置し、紙面を構成する」ですから、いわゆる手動写植機で、いろんな数値的な調整を行って「組まれた版の部品」を印画紙に焼いて、版下に貼り付けて紙面作りをしていました。
今考えてみると、すごい話ですよね。
当時いろんな企業さんの社内報を作ったりしていたのですが、縦4段組とか、そんな手法で普通に作ってたんですよね。

ここでの最大の効率化は、まずページには1行何文字で何段で何行入るのか、というような基本体裁を決めることで、その中に作るというルールが適用されていました。

そして、最大の効率化の立役者は、お客さんです。書く原稿が、きちんと原稿用紙のマス目に収められていました。ワープロもまだ普及していない時代の話ですが、ほんの16、7年前です。
この御陰で、まずそうそう大きな違いもなく、お客さんのイメージする仕上がりを初校段階から出すことができました。

だいたいこの時代では、三校責了ぐらいまでやれば、相当気を遣った校正が必要なものか、もしくは間違いが多いとか考えられますが、後者はまずなかったと思います。写植オペレータがそんなことをしていては、飯が食えないのをよく知っていたからです。

版下作業も同じで、新規でも在版で一部差し替えするときも、版下上に印刷されない薄緑の線で、版面が分かるようになっているところに、棒打ちした印画紙を定規を使って丁寧に切って、糊を付けて貼ってました。

ということは、手動写植機の作業が「組版」であり、版下の作業が「DTP」なのかな。
DTPって、デスクトップパブリッシングですよね。確か、少し傾いた「机」の「上」で、版下作業をしてました。

そして、電算写植の時代になり、版下の体裁を作って、そこに文字を流したり、作業をデータで保管できるようになりました。

こ れはまた凄い話ですよね。暗室に行かなくても、出力センターにフロッピーディスクを持って行くと、だーっと印画紙を出してくれるわけです。そして、初校の 段階は普通紙で出力しておいて、校正戻りの修正を版下を切り貼りするでもなく、データを直せばよくなったのです。これで版下作業は大助かりですよね。出た 物をがっつり貼り替えればいいのです。

ここで、組版と版下の作業が1台のコンピュータで、一緒にできるようになったということです。た だ、チラシとか、パンフレットとかなんかは、まだまだブロックごとに作って、版下作業で、ばりばり貼ってたと思います。だから、すべてを網羅するものでは なかった。いわゆる端物と呼ばれるものたちです。

そのぐらいからだと思うのですが、Mac登場です。先にデザインの分野や、画像処理の分 野で使用されていたと思いますが、ドロー系のソフトが出現したあたりです。そして、「書院」などのワープロもだいたい認知されたところで、今度は、PC上 で動くワープロソフトも出てきて、こいつぁ原稿書くのに便利だねえということで、企業内での文書作りのスタンダードになりました。多分もともとは企業さん よりも、学術系の方がその流れが早かったと思います。多分このころには、TeXは、印刷会社に頼まなくてもいいような仕上がりにできるぐらいの実力を、も う持っていた時代だと思います。
10年ぐらい前って、一人一台パソコンを持っている企業も少なかったはずです。ホントに早いですねえ。

そして、絵やイラストを描くとか、図表を作る、写真の加工などの分野で、積極的にMacを使うようになってきて、チラシなどの端物は、もうそっちの方が早いよねと。文字も打てるしさ、と。ただ、写研の文字は使えないけどねえ、みたいな。
この時点で今までとの違いは、体裁の設定など数値ありきで、置かれたときを想像する「組版」から、置いてから考える「DTP」との差が出てきたところです。
この方法は、端物なんかはイイかもしれないが、端物以外では、効率化を下げる一つの要因です。

そ うこうするうちに、QuarkやPageMakerなる英語圏の方々によって作られたページレイアウトソフトが来日しました。一番の違いは、写研を代表す る日本の組版機メーカーが出していたそれぞれの専用機の価格との差があったところにあると思います。安いけど、結構できるやん、と。

こ こまでのいろんな時代背景から、組版作業というものが、ある一定のルールによって始められるものではなく、とりあえずこんな形?みたいなノリで始められる ようになってしまったと思います。間違っても直せるんだ、いつでも変更が効くんだ、という大きな逃げ道を作ってしまいました。これが作る側の保険としてな ら良かったんですが、お客さんも、そして作り手側もそれによって、元原稿というか何を載せるのかという情報についての緊張感も薄くなり、初校を出してから 原稿作りを開始する、というような流れになってしまいました。

それは、それでいいと思う。でも、制作効率はかなり落ちます。回を重ねるごとにどんどん増えます。総合的に校正回数が、4、5校当たり前になっていると思います。
できるだけ早く、正確に、効率的に印刷物を作る仕組みを考えてきた「組版」という技術は、影が薄くなってしまって、なんだが早く、安くできそうだし、変更効くし(写植屋に怒られることもない)という、「DTP」という分野が日の目をみるようになった、と。

ということは、この制作方法をとるのであれば、時間がかかりますので、代金は総合的に上がるはずです。なので、機器にかかる費用が減った分、善し悪しあっても作業時間は増えるので、実はそこで制作代金はイコールになるべきじゃなかったかなと。
今 回は、制作代金について議論するところではないので、掘り下げませんが、もともと日本語組版は、日本人が大好きな効率よく仕事をしよう、という考えのもと で技術として確立しつつあったと思います。ところが、コンピュータ化によって、それがまったく違う方向へ向いてしまった、というのは、今日、日本が先進諸 国の中で、生産性が低い国であるという結果からも明確です。

だいぶ前に、Quarkが日本に入ってきたとき、ある人が「そんなもので組版をしたら、日本の印刷はダメになる」と言い放ったというのを聞いたことがあるんですが、もしかしたらそういう意味だったのかもしれません。
そして写研さんがあの素晴らしいフォントたちを開放しないのも、こういうところも含めた拘りであるとすると、それはそれで凄いなと思います。考えすぎかもしれないけれど。
写研さんの考え方としては、フォントに対する思いもそうだけど、組版するときのことをどこよりも考えていたと思いますので。

まとめに入りますが、「組版」と「DTP」の違いは、いろんな意味の効率を考えて最初から計算によって出た数値を使って組むのか、まずは置いてみて、そこから始めるのか、という、感覚、見た目をメインに考えるのか、ということなのかなと思えてきました。
前者は、情報処理の分野であって、後者はデザインの分野ですね。

ここまで書いて、だんだんどうでも良くなってきたんですが、
自動組版という言葉はしっくりくるけど、自動DTPというのは何かしっくりこない
というのは、ここなのかなと。

だ から、デザイン的な発想でDTPを効率化しよう、といっても、結局、今存在するアプリケーションがそういう発想で作られてはいないってことですね。もとも との発想、ルールによる組版ということに立ち返る、そしてお客さんの情報をちゃんと固定化させるお手伝いをする、というところを再認識した上で、制作プロ セスを構築していく、ということが自動組版にしろ、手動組版にしろとても重要です。

と、最近入った人たち向けの、ざっくりとした歴史でございました。
いろんな意見があると思いますので、一つの参考として。