特集
“IT 勉強会スタンプラリー”で行く、全国コミュニティ探訪 第5回
Windows Phone Arch(大阪府・大阪市)
(2012/12/14 12:01)
“IT 勉強会スタンプラリー”に参加する勉強会を訪ねる本企画。第5回となる今回は、12月5日に大阪市にあるフェンリル(株)の会議室で開催された“Specialist presents WindowsPhoneArch#4”に参加した。
“IT 勉強会スタンプラリー”とは?
“IT 勉強会スタンプラリー”とは、日本各地で開催されるプログラミングやインターネット技術に関する勉強会に参加してスタンプを集めるイベント。3月31日から開催されており、開催期間は来年の3月31日までの1年間。参加費は無料で、イベントに加盟する勉強会に参加してスタンプの台紙をもらえばだれでも参加できる。
各コミュニティは北海道から九州に至るさまざまな地域で活動しており、取り扱うジャンルも、プログラミング言語、フレームワーク、データベース、開発技法など、非常に多岐にわたる。自分の知識や能力を伸ばしたい人や、同じ話題を語り合える仲間を探したい人、会社や業界の垣根を超えた人脈を作りたい人にはもってこいのイベントと言えるだろう。
Windows Phone Archとは?
“Windows Phone Arch”は、Microsoftのモバイル端末向けOS“Windows Phone OS”にフォーカスした勉強会コミュニティ。“Arch”という名前は七色の虹の架け橋をイメージしており、開発者・デザイナー・ユーザー、アプリ・サービス・クラウドを繋げる架け橋となってWindows Phoneの可能性を示したいという思いが込められているという。
一般的な勉強会でみられる、発表者(スピーカー)がスライドを使ってスピーチを行うという1対多のセッション形式だけでなく、特定のテーマを設けてみんなで挑戦する“ハッカソン(hackathon)”や“アイデアソン(ideathon)”といった実践的な形式も積極的に取り入れているのが特長のようだ。
今回行われた“Specialist presents WindowsPhoneArch”もそのような試みのひとつで、Windows Phone開発における機能や技術からひとつだけ選び取り、その道のスペシャリストを招いて指導を受けながら少人数で学習するハンズオン(手を動かして学ぶ、体験型)スタイルをとっている。
頻度は月に1回程度で、今回が4回目の開催。テーマは“Reactive Extensions(以下、Rx)”と呼ばれる拡張ライブラリを利用したWindows Phoneアプリの開発で、yone氏(@yone64)が講師を務めてくれた。
勉強会に参加する前に
ハンズオンスタイルの勉強会では実際に開発を行うため、事前に開発環境を準備しておく必要がある。今回は、以下の2つをあらかじめインストールしておくように指示されていた。
- Windows Phone SDK 7.1
- NuGet
なお、「Windows Phone SDK 7.1」はWindows 8に対応していないため、代わりに「Windows Phone SDK 8.0」を利用することになる。「Windows 8」ではなく「Windows 8 Pro」が必要になるほか、CPUが仮想化支援機能“SLAT”に対応していることなどが条件となるので注意しよう。
筆者のノートPCは「Windows 8」だったので、週末を利用して「Windows 8 Pro」へのアップグレードと「Windows Phone SDK 8.0」のインストールを行ったが、エミュレーターが起動するかどうかチェックするのを忘れていた。そのため、勉強会会場でエミュレーターが起動しないというハプニングに見舞われ、その場で実機によるデバッグ環境を準備する羽目に陥った。このようなトラブルはセッションの進行を妨げることにもなりかねないので、事前の準備には万全を期したいものだ。
“Reactive Extensions”を使ったプログラミングに挑戦する
Rxとは、“リアクティブプログラミング(Reactive Programming)”というプログラミング手法を利用した拡張ライブラリ。Windows Phoneでは標準でこのRxが含まれているため、“Microsoft.Phone.Reactive”と“System.Observable”の2つを参照に加えるだけで利用できる。
リアクティブプログラミングとは、「時間や外部の入力とともに変化する値や計算を、ユーザ自身がプログラムするのではなく、システム(言語自体やライブラリ)がユーザからは見えないところで反応(reactive)してくれるというもの」(yone氏)。
変数をなくしてみよう
たとえば以下のコードを考える場合(行頭の数字は行数、“:=”は代入、“*”は掛け算を表す)、
1 b := 1; 2 a := b * 10; 3 b := 2;
一般的な命令型プログラミング(Imperative Programming)では a の値は2行目でも3行目でも 10 と変わらない。
一方、リアクティブプログラミングでは値の変化に反応(reactive)し、前もってそれに関連付けられたほかの値も自動的に更新される。つまり、先の例で言えば、2行目の a は 10 だが、3行目では 20 となる。お馴染みの表計算ソフト「Microsoft Excel」では、セルの値が変化すると、関連するセルの値も自動的に再計算され、新しい値へと更新されるが、それとよく似ている。
この“反応”の仕組みを実装するのはかなり手間がかかるが、Rxはそれを“オブザーバーパターン”(プログラミング設計における“型”の一種)で実装しており、比較的容易に扱うことができる。
ハンズオンで最初に出された課題「ボタンを押すとカウントアップされる処理を記述しなさい」は、そのメリットが体験できるようになっている。この課題を普通に解くと、以下のようなコードになるだろう。
namespace PhoneApp1 { public partial class MainPage : PhoneApplicationPage { // コンストラクター public MainPage() { InitializeComponent(); } private int count = 0; // 値をメンバー変数へ保存 // メソッド:ボタンが押されたら……() private void button1_Click(object sender, RoutedEventArgs e) { // 変数に1を足してボタンのテキストとして表示 button1.Content = ++count; } } }
さらに以下のようにラムダ式を利用して記述すれば、クラスのメンバー変数とメソッドを使わないで記述できるだろう。
namespace PhoneApp1 { public partial class MainPage : PhoneApplicationPage { // コンストラクター public MainPage() { InitializeComponent(); int count = 0; button1.Click += (sender, e) => button1.Content = ++count; } } }
C#の記述としては、ごくごく一般的なものだ。これをさらにRxを利用して記述すれば、“count”という変数すら消すことができる。
namespace PhoneApp1 { using Microsoft.Phone.Reactive; public partial class MainPage : PhoneApplicationPage { // コンストラクター public MainPage() { InitializeComponent(); Observable.FromEvent<RoutedEventArgs>(button1, "Click") .Scan(0, (x, y) => ++x) .Subscribe(x => button1.Content = x); } } }
かえって長くなってしまったが、すべての処理がたった1つの文で書けてしまった。Rxでは、このように“状態”を外部の変数へ保存せずにすむ。「ボタンをクリックするという操作」全体をデータの配列とみなし、それを加工するメソッドをどんどん繋げて処理を施していくイメージだ。コードは長くなるが1つにまとまっているので、変数やメソッドを飛び飛びに参照するより処理の意味がつかみやすくなっている。
最後のほうは少し難しくなったが、理解が遅れている人のフォローをしながらゆっくりステップバイステップで丁寧に教えてもらえるので、それほどハードルが高いとは感じなかった。わからないことがあればその場で質問して疑問を解消することもできる。
イベントの合成
Rxが優れている点は、これだけではない。.NET Framework 3.5で追加された機能“LINQ”と組み合わせることでいくつもの“反応”をデータソースとして扱い、クエリ関数によって合成やフィルタリングなどが容易に行えるのも大きなメリットと言える。
2つ目の課題「Rxでドラッグ&ドロップを実装する」は、その例。ドラッグ&ドロップでオブジェクトを移動させる処理を記述するには、以下の3つのイベントを横断して処理する必要がある。
- MouseLeftButtonDown:マウスの左ボタンが押し下げられた
- MouseMove:マウスを移動中である
- MouseLeftButtonUp:マウスの左ボタンが上がった
さらに、状態を保存する2つの変数が必要になる。
- ドラッグ&ドロップ中かどうか(マウスの左ボタンが押し下げられているかどうか)
- マウスカーソルの位置情報を管理
しかし、Rxならば変数が消せる上、3つのイベントを1つの“ドラッグ&ドロップイベント”に束ねて1つの文で記述することができる。
namespace DragDrop { using Microsoft.Phone.Reactive; public partial class MainPage : PhoneApplicationPage { // コンストラクター public MainPage() { InitializeComponent(); rectangle1.MouseDownAsObservable() .Select(e => { rectangle1.CaptureMouse(); return e; }) .SelectMany(e => rectangle1.MouseMoveAsObservable()) .TakeUntil(rectangle1.MouseUpAsObservable().Select(e => { rectangle1.ReleaseMouseCapture(); return e; })) .Scan((e1, e2) => { var dY = e2.GetPosition(null).Y - e1.GetPosition(null).Y; var dX = e2.GetPosition(null).X - e1.GetPosition(null).X; this.rectangle1.SetValue(Canvas.TopProperty, (double)rectangle1.GetValue(Canvas.TopProperty) + dY); this.rectangle1.SetValue(Canvas.LeftProperty, (double)rectangle1.GetValue(Canvas.LeftProperty) + dX); return e2; }) .Repeat() .Subscribe(); } }
一見目が回りそうになるコードで、正直なところ、筆者もこのすべてを理解しているわけではない。何も参照せずにすらすら書くことなど不可能だ。しかし、実際にタイプしてコードを入力すると、おぼろげながら何がどのような役割を果たしているのかがわかってくるような気がする。
RxはこのようなGUI操作のほかにも、Web APIの利用などへ応用することが可能。サーバーとのやり取りをイベントの流れ(シーケンス)とみなせば、先ほどのドラッグ&ドロップの例のように記述できるわけだ。最後にはyone氏が“ATND”のAPIを利用してデータを取得するサンプルを解説してくれた。
Rxはもともと非同期プログラミングのための追加ライブラリとして開発されたが、C#そのものに非同期プログラミンを容易にする言語拡張が加えられ(async/awaitキーワード)、その地位は若干低下している。しかし、イベントの合成などといったRxならでは機能は魅力的。従来の馴染みのあるプログラミングスタイルから抜け出すことには苦痛が伴うが、その見返りは非常に大きいと感じられた。
みんなで体験を共有する
ハンズオンスタイルのよいところは、体験できるという点にある。それも仲間と一緒に。大勢で同じ課題に取り組む一体感は、通常のセッション形式の勉強会ではなかなか得られないだろう。
筆者は本職のプログラマーではないため、参加するまでは周りに追いついていけるか非常に不安だった。しかし、それも杞憂に終わった。わからないところはその場で講師やほかの参加者に質問できるし、全員が課題をクリアできるまで待ってくれるので落伍してしまうことがない。
またRxを学習するという目的以外にも、「Visual Studio」の意外な使い方を知ったり、ほかの人のプログラミングスタイルを垣間見られるなど、発見の多い勉強会だった。
なお、次回は“TouchDevelop”を利用したWindows Phone開発がテーマであるとのこと。窓の杜でも特集で取り上げたホットな話題でもあるので、興味のある方は参加してみてはいかがだろうか。