Category Archives: Programming

[IM]バリデーションの実装を再考する

INTER-Mediatorではかなり以前にバリデーションの実装はしたものの、完全ではない状態だったのですが、このところ、手を入れるに従って、いろいろ不具合…というか、「考慮が薄い」ポイントが目立ち始めましたので、改めて、議論を進めたいと考えています。

まず、バリデーションは、「入力チェック」とも言われます。いちばん、根本的なことは何かというと、「正しくない値をデータベースに保持しないようにしたい」という要求があると考えています。「正しくない」の基準は、アプリケーションによって変わりますが、「NULLである」ということかもしれませんし、「正しいメールアドレスのフォーマットではない」ということかもしれません。その場合に、データベースに記録しないようにするということがあります。データベース絡みとなると、いろいろ複雑な問題が出てきますので、これを後回しにして、まずは、アプリケーション利用者レベルからの見方を考えてみます。

開発者や管理者がバリデーションを必要とし、実装しますが、Webアプリケーションフレームワークは、バリデーションに関連したユーザーインタフェースを構築し、ユーザーを惑わせない仕組みの提供が望まれます。そもそも、アプリケーションで、どようにバリデーションが絡み合うのか、5W1H的にまず考えます。

  • When:正しくない値が入力されたとき
  • What:開発者や管理者が望ましくないと考えるデータを検知する仕組み
  • Where:入力可能なコンポーネント
  • Who:ユーザーが生成すると考える
  • Why:単純なミス、さまざまな誤認、テストあるいはインスペクション
  • How:キータイプ、あるいはコピー&ペーストなどのユーザの操作

以上の分析からは、バリデーションの検知と通知が大きな目的であることが出てきます。しかし、一部に例外があって、フィールドの初期値がバリデーション違反という場合もあります。そのとき、上記のWhoは「システム」ということになってしまいます。この初期値が違反している問題は、厳密にはデータベースの定義が正しくないで終わってしまいますが、非常に複雑な事情が絡むので、後ほど議論します。

バリデーションの検知は、INTER-Mediatorではすでに実装しています。onchangeイベントが発生したときに、フィールド単位でのチェックを行います。フィールドをまたがった判定用にも、コールバックされるメソッドの定義があります。最近になって、初期値が違反しているときでもバリデーションが働くように、onblurイベントでも判定をするようにしました。これら、さまざまなニーズはあると思われますが、タイミングと仕様が確定していれば、対処できる範囲かと思います。

一方、バリデーション違反の通知は、さまざまなバリエーションが考えられます。そういうニーズも状況も多様な状況では、プログラムを組んで対処というのはもちろん柔軟な対応ができていい部分ですが、一定の範囲を宣言的な記述でまかなうことで、プログラムを書くことを減らす意図のあるINTER-Mediatorではなんとかしたかったところです。そこで、フィールド単位のバリデーションが違反したら、「ダイアログボックスを表示して促す」「近辺に赤字等でメッセージを出す」という仕組みを定義ファイルの設定だけで実現しました。そして、イベント発生時に違反が検知されれば、雇用な動作をして、フィールドからフォーカスがはずれないようにしました。

しかし、ここまででも、すでに議論のポイントはいくつもあります。

  • バリデーションはいつ行うのか?
    • キータイプごと?
    • カット&ペーストするごと?
    • データベース更新前?
    • 複数のフィールドに対して「書き込み」ボタンがあれば、それを押したとき?
    • ポストOnlyモードとデータベース更新時は動作を違う必要があるのか?
    • 現状は、定義ファイルで指定可能なのはデータベース更新前のみ。
  • 違反通知をどのように行うのか?
    • 現在は、ダイアログボックスとページ上への文字の追加
    • 新しいページを表示したい?
    • 何が間違えたのかをもっと詳しく表示したい?
  • バリデーションに違反したら、その後にどのような操作を期待するのか?あるいは期待されるのか?
    • そのままでいいのか?
    • どこまでロールバックするのか?
    • どこまで既定値的な値を設定するのか?
    • 違反したレコードは削除しなくていいのか?
    • 違反してもレコードは作るのがいいのか?
    • 現在は、そのままにしつつ、正しい値を入力しないとそのページの他の作業をできなくしている。

あらゆるバリエーションに対する答えを用意するのか、それとも、主要な手法以外はプログラミングをしてもらうのか、その辺りが議論のポイントになると思います。いずれにしても、問題を書き出すことは必要でしょう。

データベースエンジンには通常バリデーションの仕組みは含まているので、本来はそちらを使うべきという議論があるでしょう。SQL言語での定義時に記述するため、「難しいから敬遠している」という向きもあるかもしれません。一方、なぜ、フレームワークがバリデーションをサポートするかというと、データベース側でのバリデーション処理は、違反時の状況の取得や、そこからの適切なユーザーインタフェースの構築、さらにやり直しなどの処理の組み立てなど、単純ではないプログラミングを要求されます。また、その対処方法も、データベースごとに違う可能性もあるので、むしろ、フレームワークの内部でバリデーションをサポートした方が、動作上作りやすいということもあるわけです。データベース側のエラー検知は、レイヤーを上下するワークフローをうまく組み立てるようなプログラミングを必要としますし、その結果、アプリケーションサーバーとデータベースということなるソフトウエア間の連携ということも必要になります。結果として、データベースに頼らない方が、フレームワーク内部で完結するため複雑さの一部を回避でき、加えてデータベースごとの事情に左右されないというメリットを生みます。

その結果、データベースのスキーマ定義にバリデーションルールが入らないことになり、それによる大きな問題は、初期値がバリデーション違反という状況で、ユーザーの操作に入ることがあります。これをどこの段階で、不正とみなし、どのような方法で排除するか、これが定まらないと、実装が揺らぎます。

ということで、とりあえず、頭にあることを書き出しておいて、議論を進める手掛かりにしたいと思います。

Appleの新言語Swiftは普及するのか?

もちろん、月日を経ないと結論は出ませんが、今時点では今後普及すると考えます。その理由を考えてみました。

まず、「開発言語の大きな変更」というのは、Mac OSからMac OS Xへの移行時にありました。その成り行きは非常に重要です。Mac OSは、CあるいはC++が主要言語だったと言えますが、Mac OS XはOPENSTEPからの名残でObjective-Cが開発言語になることが、当初NeXTとAppleが合流したときの事実でした。しかし、既存のMac OS開発者からは支持は得られず、AppleはMac OS Xの正式リリースが近づく頃にJavaに対応しました。1999〜2000年頃は、Javaが登場して4年程度の頃で、エンタープライズ分野で使われ始めるなど、ある意味では注目が集まっていた言語でもありました。また、その頃は、Flash vs Javaという構図でもまだ微妙に拮抗していた時期です。Appleは「Javaだとみんな納得してくれるだろうし、他のプラットフォームの開発者にもアピールできるだろう」と考えたのかもしれません。しかし、現実はそうではありませんでした。技術的な問題と、心理的な問題があったのです。

おそらく、いちばんの見込み違いは、これまでNeXTの世界でObjective-Cで開発して来た人たちよりも、Javaだから参入しようと思った人たちの方が少なかったからでしょう。いまでこそ当たり前のOS Xですが、移行時は「Mac OS Xは失敗してMac OSに戻すだろう」みたいな発言を堂々と公言する人たちも多く居たので惑わされたのでしょう。WWDCに当時参加していた人は、Mac OSへの逆戻りはあり得ないことは理解していたと思います。しかし、プラットフォーム外の人はそうした変な噂にも惑わされて、言語以前にMac OS X自体への注目がされなかったのでした。この点が大きく、AppleもMac OS X発売直後くらいからObjective-Cにフォーカスし、Java対応は順次縮小して現在に至ります。

技術的な側面でも、Javaでは参照渡しという仕組みがないと言えばなく、Objective-Cで培われたAPIに微妙にマッチしていませんでした。そして、メモリモデルが異なる2つの言語では、思わぬ落とし穴がどこかにあって、「なぜか動かない」という箇所に当たってしまうこともあり、安心して使えなかったことも事実です。また、Javaは遅いという世間の意識にもマイナス方向の力が働きました。

そして年月が経過しました。魅力的な製品iPhone/iPadで稼働するアプリケーションを作りたいために、それまでAppleに見向きもしなかったたくさんの人が、Objective-Cの学習をしたのです。これは、Mac OSからOS Xへの移行時とはすでに状況が違います。Appleは、OS Xリリース前のJava対応の混乱から、「他の世界のプログラマに魅力がある」ということよりも、「今現在プラットフォームにコミットしている人たちの満足度」がより重要であるということを学習しているのだと思います。

しかし、Objective-Cへの不満はいつもどこかでつぶやかれていました。そこで、まず取り組んだのが、複雑なメモリ管理へのテコ入れであり、ARC対応です。同時に、ブロック対応した点でも、コンピュータの世界の基準に追いつくことをしたということです。そして、今回のSwiftがあります。iPhoneアプリを作りたいことで、Objective-Cを学習するような人なら、Swiftの学習をすることくらいはさほど難しくないと言えます。しかも、文字列を+でつなげられるわけで、JavaScriptなど多くの人たちがObjective-C以外で経験して来た言語に近い訳です。Objective-Cが理解できるプログラマなら、Swiftは理解できるでしょう。しかも、?によってよりシンプルに記述できるとか、プロパティがオブザーバブルといったより良い特徴も目立ちます。

さらに、「すでに有名である言語である必要はない」という意識も、Appleには現在のObjective-Cプログラマの増加から出ているのでしょう。既存の言語、ruby/Python/JavaScript等ではない理由としては、すでにコミュニティがあって色が付いた言語だと、その世界のしきたりに引っ張られるのですが、「新言語」と言い切ってしまえば、Appleは独自にその中身を構築できるのです。これは、もちろん、Appleにとって有利に働きますし、そういうことでないと、Cocoaとの完全な統合はできないと言えます。Javaのときの技術的な問題に対する対処も、Appleの手中に最初からあるということです。

Mac OS X初期の頃と違い、たくさんの開発者がすでにコミットしている上では、新しい言語は十分に受け入れられるだろうと判断したのでしょう。また、iOSのアップデートがきわめて順調である点も追い風になるでしょう。これから開発するアプリケーションは、iOS 8以上対応という決定がなされるのがおそらく普通かと思われます。そうなら、思い切ってSwiftでやるぞという結論になる確率も高いということです。

そういうことで、Swiftは昔のJava for Mac OS Xのようにはならないと思います。OSのバージョンアップのスピードを考えれば、来年のWWDCの頃にはSwift率はけっこう高くなっているのではないでしょうか。半々くらいになるかな?(数字は出したくないのだけど〜笑)また、プログラミングと言えばいまだに「言語の理解」という間違った意識がありますが、実際には「フレームワークの理解」ということの方がよほど大変です。SwiftになってもCocoaの諸概念を理解して利用するという点では、Objective-Cと違いはありません。現在のiOS開発者にとっては、「ちょっと書き方が変わる」くらいの話であり、今までがんばって学習してきたCocoaの知識は十分に活かせるし、むしろそれらが必要なのです。Appleはきちんとレールを敷いた上で、新しい言語を持ち出したのです。

講義でのペアプログラミングの使いどころ

今年度のJavaの講義では、ペアプログラミングを導入して、演習に取り組む時間を比較的多く取ってみました。そして、必須課題として、その感想を聞きましたが、総合的に良かったあるいはどちらでもないというのが33%、残りの67%は「よくなかった」という感想でした。理由は知らない相手や、理解度の違う相手との演習は思った以上に神経を使うということで、それほど効果的ではないという感想でした。全員に利点とデメリットも書かせましたが、ほぼ、同じような答えで、よくなかったと感じた人たちも利点がある点は理解しています。なんかうっとおしからいやだ…ということではなく、きちんと理由を考えさせた上で、総合評価させています。

1つあるのは、友達関係にない相手と組ませることになるのは、確かに大変かもしれません。とは言え、講義運用上どうしてもそれは必要になります。レベルが違う人と組むのは、それなりに悪い事ではないと思うのですが、「課題を行う」というまじめな学生達のゴールにとっては足かせと感じたのかもしれません。ただ、他人がどう考えるのかということが理解できる点は良かった点として挙げられていました。

今年度は比較的多くペアプロをやりましたが、来年度は、限定的にやろうかと思っています。アジャイルのプラクティスは、形のないソフトウエアを作るプロセスを進化させるいちばん有力な手法だと感じています。ただ、プログラミングの初心者でできそうなプラクティスはペアプロではないかというのが当初の考えです。しかしながら、まずは基礎力をつけてレベルを比較的揃えてからやるというのが重要なようです。また、講義全体の進行度合いとはある程度独立した課題を与えるひつ模様もあると感じました。つまり、講義の流れは追えている学生もいれば、遅れている学生もいるということで、そこで一様でなくなる可能性があるということです。来年度は、「ペアプロの日」つまり、ペアプロで課題だけをやる日を1回か2回確保しようと思っています。

ようするにペアプロが機能する状況を、講師が作った上で、させないといけないという当たり前の結論なのですが、現場の開発と教育の現場の違いはまさにそういうところではないかと感じました。

[IM]レポジトリから取り出した結果で開発する

INTER-Mediatorはgithubでソースを公開しています。それとは別にサイトには特定のバージョンのファイルもアップロードしています。バージョンを固定し、フレームワークに手を入れないという前提なら、サイトからのダウンロードした結果をアプリケーションにコピーして使っていただいていいのですが、検証したりあるいはアップデートを取り込みたい場合、それだとファイルコピーを自分でしないといけなくなります。

非常に割り切った言い方をさせていただくと、サイトにある各バージョンのダウンロードファイルは、「それなりにアップデートしている」というアピールのものであると言っていいかと思います。githubにあるものと、サイトにあるものは若干違っていて、後者の方はJavaScriptのソースを一体化しつつYUIで圧縮かけたものですので、若干は動作効率は高いものです。

お勧めするのは、通常の開発は、レポジトリから取り出したもので進めておき、実際にアプリケーションを配備するときに、特定のバージョン向けにビルドしたものに置き換えるということになります。もちろん、それらの相違点に注意は必要かもしれません。また、そうした作業がしやすいように、Ver.3.11をリリース後にレポジトリの内容を大きく変更しました。gitの使い方はいろいろ難しいですが、gitを全く知らない方も、ともかく以下のようにしてみてください。

まず、あるフォルダに作成するWebアプリケーションのファイルをまとめておくとします。そのフォルダを作ります。以下は、Documentsの下にmywebappフォルダを作りました。

Dec 1, 2013, 14.44.15

次に、githubのINTER-Mdiatorのページに行きます。アカウントを持ってサインインしていただくのがいいのですが、なくてもソースのダウンロードは可能です。ここで、中央右付近にあるbranchがmasterになっているのを確認してください。ブランチのmasterがその時点でのコンプリートなソースです。そして、右の方にあるHTTPS clone URLをコピーしておきます。URLが薄く見える右のボタンをクリックすれば、コピーできます。

Dec 1, 2013, 14.45.25

そして、ターミナルを開いてください。次のように作業をします。#以降はコメントです。ファイルパスはもちろん、ご自分の作られているフォルダ構成に従って指定をしてください。

cd ~/Documents/mywebapp  # Webアプリケーションのフォルダをカレントにする
git clone https://github.com/msyk/INTER-Mediator.git  # サーバからレポジトリを複製する

これだけでOKです。すると、mywebappフォルダに、INTER-Mediatorフォルダが作られます。このINTER-Mediatorフォルダがフレームワーク本体となります。この階層に、たとえば、index.htmlファイルやら、アプリケーションのhtml/phpファイルを作って行けばOKです。後はこれをサーバにコピーして稼働を確認します。

Dec 1, 2013, 14.47.28

ここで、レポジトリからクローンしたINTER-Mediatorを参照するには、定義ファイルのcontext.phpはたとえば、次のように記述をします。

<?php
require_once('INTER-Mediator/INTER-Mediator.php');
IM_Entry( .... );
?>

なお、サンプルファイルは、INTER-Mediatorフォルダ内のSamplesフォルダにあります。

もし、レポジトリ側に新しいソースコードが加わっていれば、以下のようにコマンドを入れれば、最新版を取得できます。INTER-Mediatorフォルダをカレントにして、git pullとすればいいです。

cd ~/Documents/mywebapp/INTER-Mediator
git pull

念のために説明しておきますが、pullは最新版に更新するという使い方は非常に稀で、正しくは別のレポジトリの修正を取り込むという意味合いがあります。ソースコードをメンテする上では単なる更新ではないのですが、ソースを利用する側の方から見れば更新コマンドと思っていただいて概ねいいかと思います。もし、自分でフレームワーク側のソースを修正された場合には、単純ではありませんので、ここではソースは参照だけでタッチしないという前提で、説明をここまでとします。

gitには実に多彩な機能があり、ここまでに説明した手順はほんとうにその一端でしかないのですが、これだけを知っていれば、とりあえず大丈夫かと思います。もし、フレームワーク側の修正結果をコミットしていただけるなら、それなりにコマンドを打ち込むか、あるいはアプリケーションを使うことになるかと思いますが、取り出すだけなら上記の手順以上はほとんどないと思います。

gitを使った場合の質問がある場合は、FacebookのIMのグループで質問を出してください。

プログラミング講義の演習でペアプログラミング

けっこう長い年月、大学で文系の学生を中心に初心者向けのプログラミングの講義とExcelを中心としたアプリケーション利用の講義を受け持っている。プログラミングの方は以前は自分の書籍、そして改訂が追いつかなくなってからはその内容を書き換えて作ったテキストで教えている。ずっとJavaを教えているがJava言語を教えるのは学校の方針なので変えられない。ほとんどの学生は、おそらくエンジニアにならないと思うし、ここまでにプログラミングについての何かの講義を受けたことは前提にしていない。プログラマ養成という目的はなく、「世の中にはこういう世界もあるものだ」と思ってくれればいいくらいの講義であり、以前は受講者はすごく少なかった。もう1つ講義を持っていて、そちらはExcelを中心にしているが、数年前まではExcelの講義の方はまだ受講者は多かった。しかし、なぜかちょっとその傾向が変わっている。比較的まじめにJavaの勉強をする学生が増えて来た。情報処理試験を受ける人がその学部でも多いということを別の先生からも聞くが、もしかしたらスマホブームみたいなこともあるのかもしれない。

毎年同じように淡々とやってきたのだが、数年前にExcelの講義よりもJavaの講義を最後まで受ける人の方が多くなってきて、ちょっとやり方を変えるべきかと思うようになってきた。少しレベルを上げて、繰り返し基本をやるのをやめたりとかしてきたが、今年から「ペアプログラミング」を演習に取り入れるようにしようとした。講義は半分は解説しながらプログラムを打ち込んだりして、残りの半分は演習に充てている。去年までは基本的に1人ずつでやっていた演習を今年はペアプログラミングにしようとした。しかし、いきなり最初から人と組むのはどうかと思い当初は1人での演習とした。つまり、ベースになる知識がいくらかでも浸透しないと会話が成り立たないと考えたのである。今日は4回目の講義で、今回の演習でペアプログラミングやってみたのだが、結論を言うと正解だった。学生の表情がきわめて明るく、また、相談しながら何かをやることでの達成感があるのか、「できたー」と声を出す学生は1人や2人ではなかった。記録のため、その状況をブログに残すことにする。

  • 先週までで基本型を説明した。今日は文字列についての章で、+、length、substring、そしてStringBufferのinsert、appendくらいしか教えてない。それらでできるプログラミングとしては基本的なレベルの演習を与えた。
  • ペアプログラミングという言葉を使ったが、アジャイルとは何かみたいな話は一切していない。説明したのは「1台のパソコンを代わる代わる使って演習をやりなさい」という程度、また、適当に打ち込む側を代わることと、横から見ている人は「言葉で茶々を入れる」ということを強調した。問題ごとに代わるペアもあったが、「随時必要に応じて代わる」点を強調しておいたので、主体的に関わる側に随時切り替わるペアもあった。
  • チームをどう作るか迷ったが、講義は学科や学年をまたぐものであって、あまり同一学科の同一学年が集まっておらず、学生同志はほとんど面識のない様子だったので、単純に座席の近い者でペアを組ませた。人数が奇数だったのだが、1名のみTAが茶々入れ役をした。
  • ほぼ全員が、明るい表情で演習を続け、また、お互いに話をすることで、講義にありがちな重苦しい雰囲気は一気に吹っ飛んだ。通常の演習よりもリラックスができたのだと思われる。また、演習問題が出来上がった事は声や表情等に出るのだが、一人でやるよりも達成感があったのではないかと想像できる。また、問題の解釈をディスカッションしたり、うまく行かないポイントを会話するのを聞く事で、どういうところを迷っているのかもある程度は観察できる状態だった。
  • 問題に関する質問がほぼなかった。通常は演習中に、TAが走り回ってサポートしているが、サポートの必要がなかった。つまり、2人で演習にかかれば疑問点は解決できるということのようだ。
  • 終わってから作ったプロジェクトを作業していないPCでログインしている人に渡すように指導をしたが、そこで悩むことの方が多かった。この点についてはあまり指導しないでおいたので、仕方ない面はある。たぶん、次回からUSBメモリが必要だと気付く人もいただろう。また、下手なことをするよりもプログラムをメールで送り合った方が楽という点も気付くペアはいた。いずれにしても、ここは随時指導を加えるポイントである。

そういうわけで、ペアプログラミングってどうだろうかと慎重にスタートしてみたが、たぶん、これは学生も教師もやりやすい手法のようだ。特に、学生同志で、それぞれ上下関係が薄いという場合には問題なくワークしそうだ。学年の違いもまあ、あの年齢になるとそんなに気にならないのだろうか。ペアを今後どのように作るかちょっと悩ましいところもあるが、固定化しないでやるのがいいのか、あるいは固定化させるべきか考えないといけない。だが、いずれにしても、ペアプログラミングによる演習は積極的に取り入れて良さそうだ。

OME never die! と言いたいけれど…

<a href=”http://msyk.net/ome”>OME</a>を一生懸命やっていたのは、1999〜2004年くらいかな。ちょうど、<a href=”http://msyk.net/cserver/mdo.html”>MDOnline</a>の頃に重なります。その後も、だましだましOMEを使ってきました。相当だましたので、OS X Lionでも使えてはいますが…。ちょっとかなりきつくなってきました。それでも、never dieと言いたいのですが、かなり苦しいかも(苦笑)。

まず、「再開」の機能により、ウインドウの残り方が今ひとつよくないのか、落ちることしょっちゅうです。まあ、データを書き込んでいないし、所詮テキストファイルなので悪影響はまったくありませんが、あまりいい感じではなく、特に、command+Wでアプリが落ちるのはちょっと面倒です。コンパイルしなおそうとしているのですが、これがなかなかやっかいで、まだうまく行っていません。そこはだましだましなところですね。

そして、ついにというか、やっと気づいたというか、11月11日を境にiCloudのメールの受信ができなくなっていました。できないのをやっと気づいたというのは、iPadでもメールを読んでいるからです。fetchmailコマンドでme.comのメールってなんでだめなんだろうか? 認証のエラーが発生します。

仕方ないので、Mail.appでiCloudメールを受けるようにしました。

そこでふと考えたのは、Mail.appをfetchmail代わりに使うことです。メールソースをAppleScriptで書き出して、メールの整理はOME側でやればいいじゃん!ってことで、近々に取り組むつもりです。

電子メールというきわめてレガシーな仕組みが今だ、同じように残ると同時に混沌さは年々増す感じもします。昔から、電話をいちいち録音していないのと同じように、メールだって、しばらくすると「捨て」でいいとも思ったりもしますが、なぜ、テキストファイルで残したいのかというモチベーションを思い出し、もうひと頑張りしようと思います。つまり、OMEはメールの整理・ストレージに移行するということです。

さて、どうなることやら。