FileMaker Server 19.4(Ubuntu)の稼働するLinuxでPHPも稼働させる

FileMaker Server 19.4.2.204が稼働するUbuntu Server 18では、デフォルトではPHPは入っていません。自分で入れれば動くのはわかっているのですが、いわゆる「インストーラ」はないので、色々うまく設定しないといけなくなります。一応、動かす方法はわかったので、忘れないようにここに書いておきます。

まず、PHPのインストールですが、Ubuntuの普通のパッケージだと7.2です。せめて7.4にしたいので、こちらのサイトを参考に以下のようにコマンドを入れました。レポジトリを追加して、PHP 7.4をインストールします。

sudo apt-get update
sudo apt -y install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt -y install php7.4

これだけだと、UbuntuでのサービスとしてのApache2を稼働させるとおそらくPHPは稼働しますが、FileMaker ServerのApacheは、独自の方法で起動しているので、そちらでPHPを認識させないといけません。

そこで、以下のようにコマンドを入れて、メインの設定ファイルを修正します。最初のcdコマンドで移動するパスが、FileMaker Serverをインストールした場合のApacheのルートディレクトリです。

cd /opt/FileMaker/FileMaker\ Server/HTTPServer/
sudo nano conf/httpd.conf

以下のような場所があるので、まずここを検索します。

#
# Disable PHP document
#
<FilesMatch "\.php$">
    Require all denied
</FilesMatch>

この部分を、以下のように変更します。php.confはこれから作ります。

#
# Disable PHP document
#
#<FilesMatch "\.php$">
#    Require all denied
#</FilesMatch>

Include conf/extra/php.conf

これだけでよさそうに思うのですが、これだけだと次のようなメッセージが出てしまいます。

[Wed Jan 19 11:11:29.516483 2022] [php7:crit] [pid 30487:tid 140490306792384] Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.  You need to recompile PHP.
AH00013: Pre-configuration failed

Apacheはマルチスレッド対応だけど、PHPは違うから、PHPを再コンパイルしろとあります。再コンパイルできるなら、レポジトリから取って来ません。そこで、若干問題が生じる可能性もあるのですが、Apacheをマルチスレッドではない状態で動かします。こちらのサイトを参考にしましたが、手順は異なります。

この点を解決するためにconf/httpd.confの編集を続けます。以下のような部分を検索します。「mpm」で検索すると良いでしょう。

LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so
LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
LoadModule negotiation_module /usr/lib/apache2/modules/mod_negotiation.so

これを、次のように変更します。mpm_event_moduleをコメントにして読み込みません。新たに、mpm_prefork_moduleを読み込みます。記載されていないモジュールの読み込みが増えていますが、そのモジュールはもともとありました。

LoadModule mime_module /usr/lib/apache2/modules/mod_mime.so
#LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
LoadModule mpm_prefork_module /usr/lib/apache2/modules/mod_mpm_prefork.so
LoadModule negotiation_module /usr/lib/apache2/modules/mod_negotiation.so

これで、httpd.confを保存しておきます。

続いて、php.confを作ります。php7.4をインストールしたときに作られるファイルから適当に記述を持ってきて作ったものです。エディタを起動するために、次のようにコマンドを入れます。

sudo nano extra/php.conf

もちろん、存在しないファイルなので、エディタの画面は真っ白です。ファイルの中身は次のようにします。

LoadModule php7_module /usr/lib/apache2/modules/libphp7.4.so

<FilesMatch ".+\.ph(ar|p|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch ".+\.phps$">
    SetHandler application/x-httpd-php-source
    # Deny access to raw php sources by default
    # To re-enable it's recommended to enable access to the files
    # only in specific virtual host or directory
    Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(ar|p|ps|tml)$">
    Require all denied
</FilesMatch>

冒頭のLoadModuleは必須として、最初のSetHandlerだけでも多分動くと思いますが、とりあえず、他のものも入れておきました。なお、元のファイルにあったユーザのホームで公開した場合にスクリプトを動かさないようにする設定は省きました。

ここで、Apacheサーバだけを再起動とかして動くようにするのがお作法なのですが、サーバ自体を再起動します。それが確実なようです。すると、PHPが動きました。ちなみに、php.iniファイルのパスは、/etc/php/7.4/apache2/php.ini です。

こうしてPHPが稼働する状態になっているなら、PHPのモジュールはインストールするだけでOKです。例えば、初期状態ではcurlが稼働しませんが、次のようにコマンドを入れます。

sudo apt-get install -y php7.4-curl

すると、/etc/php/7.4/apache2/conf.dに、curl.iniファイルへのショートカットが作られて、認識します。あとは、サーバー再起動でもいいのですが、httpdctl gracefulでも設定は反映されます。

ちなみに、この方法でPHPを動かすのはまたまたアップデートの時などに手順やファイル名が違ったりしたりと色々面倒な気がするので、実稼働するシステムでは、FileMaker Serverとは別にPHPを稼働させるサーバを立てるのが、トラブルは少ないのではないでしょうか。

論理値の演算で→(IMP, implication, ならば)があればなぜ便利か?

ブール代数の演算では、AND(∧)、OR(∨)、NOT(¬)があれば、どんな論理式でも構築できるというのが基本ではあるが、命題論理の世界では、PとQが命題(真か偽かのどちらかの結論しか持たない記述)として、P→Qという演算を定義し、頻繁に利用する。この演算は、Pが真の時は、Qの真偽の値が得られる一方、ちょっとわかりにくいのが、Pが偽ならP→Qは真になるというルールだ。ここで、「ならば」というのを日本語として解釈すると、しっくりこない。これは『強いて言えば「ならば」みたいな感じ』程度での理解をしておくのがいいだろう。

この→は、命題論理だけではなく、もちろん、ブール代数でも定義して利用可能だ。論理式で記述すると、P→Qは「¬P ∨ Q」となる。ということは、プログラミング言語できちんと書けるではないかということになるのだが、 →に相当する演算子はあまりプログラミング言語としてサポートしている例は少ない。例えば、OCL(Object Constraint Language)ではサポートされているが、JavaScriptなど他ではあまり見ない。もちろん、演算子の定義ができれば自分で作るという手もあるが、言語でサポートされていない機能はそれだけ馴染みが薄いとも言える。しかしながら、→を使った方がシンプルに論理式を記述できるとしたら、プログラムの中で使ってみたくなる。

→演算が便利な場合はないかと例を考えてみた。ここで、何か商品を販売するときに、付随するオプション的な項目が、それぞれ状態があるとすると、→が使えると考えた。例えば、名刺印刷という基本的なテキストのみの印刷を行う商品があるとする。これに、「顔写真印刷」「会社ロゴ」印刷がオプションとして、追加料金を取っているとしよう。顔写真、会社ロゴ、いずれも画像ファイルを入稿しなければならない。つまり、入稿を確認して、印刷に入れるということだが、もちろん顔写真オプションを選択していないなら、入稿の有無は関係ない。次のように命題を定義する。

P = 顔写真印刷を申し込んだ
Q = 会社ロゴ印刷を申し込んだ
Y = 顔写真の画像をアップロードした
Z = 会社ロゴの画像をアップロードした

そして、名刺印刷のための版下作成が可能かどうか(ここでは簡単のためにオプションの画像が必要であれば入手されているという状況だけで考える)は、以下の論理式で求めることができる。

P→Y ∧ Q→Z

もちろん、真理値表を記述して全部検証すれば問題ないのはわかるが、まずはシンプルに意味的に検証しよう。P、Qはいずれも、→の左辺にあり、値が偽なら、つまり、オプションとして申し込んでいなければ→の結果は真になる。つまり、∧の両側は申し込みしていないものは常に真になり、真偽は申し込みをしているものに限って考えれば良いということになる。そして、申し込みをしていれば、アップロードしたかどうかで、∧の両側の値は決まるので、上記の式が真になるのは両方とも真、つまり、申し込んだオプションが全てアップロードされた場合に真になる。繰り返すが、オプションを何も申し込んでいないと式の結果はやはり真になり、オプション関係なしに印刷に入れば良いということだ。そういった状況が一気に→が表現しているとも言える。

真理値表を作成すると、以下のようになる。なお、オプションとして申し込みをしていないのにアップロードしているという矛盾した状況もある(表の最後の列に*を記述)が、申し込みをしていないという状況だけが結果に影響されるので、そのために式を修正する必要はない。言い換えれば、うまく→の右辺の状況を打ち消してくれている。

PYQZP→YQ→ZP→Y ∧ Q→Z
0000111
0001111 *
0010100
0011111
0100111 *
0101111 *
0110100 *
0111111 *
1000010
1001010 *
1010000
1011010
1100111
1101111 *
1110100
1111111

以上のように、「商品のオプション」という状況なら、→演算でシンプルに論理式を記述できそうだ。もちろん、¬と∨で展開してもさほどではないが、複雑な式は別の機会にみた場合には、間違いを誘発しそうな感じがありありとする。また、→での記述の方が、要求や要件の記述に近いと言うことも期待できるのである。

Apple IDの2要素認証をいつまでも求められる場合の対処

ちょっと話題的には古いのかもしれませんが、Apple DeveloperのApple IDは2要素認証が必須になり、そのような警告メッセージが出ました。で、ある時から、2要素認証を「しないといけない」状況になりました。

そこで、appleid.apple.comで、2要素認証をオンにしてみたのですが、XcodeやDeveloperサイトでの状況は変わりませんでした。Xcodeでは署名のたびにパスワードを求められるのですが、それでも認証が通らなくなってきてなんとかしないといけなくなりました。appleid.apple.comで設定すればいいだけではないというのがポイントです。

で、どうすればいいかといえば、macOSのシステム環境設定にあるiCloudで、そのApple IDを入力します。しばらくすると、警告アイコンが出てきて、更新するみたいな内容のボタンが出てくるので、それをクリックしてしばらくすると、アカウントの情報が更新された模様です。そこまでくると、Xcodeでの認証が通るようになります。

多分、何かの具合で、appleid.apple.comでは更新ができない状態なのでしょうけど、iCloudで普段使っていないアカウントの場合、入力し直しになり、データが消えるみたいなメッセージに対処しないといけないわけですが、データはクラウドにあるので原則問題ないと思います。しかしながら、システム環境設定を変えるのは色々面倒と後の影響がきになるところですが、appleid.apple.comでダメだったら仕方ないので、iCloudでセットアップして、更新処理をmacOS側からやってください。

Jupyter notebookでPHPを動かす

macOS Mojave上で、Jupyter notebookを動かし、PHPのkernelを稼働させる方法を記載します。ほとんど自分用のメモみたいなものですね。なんでJupyterなのかというと、先日Bitcoinのセミナーに行ったのですが、その中で自身が作ったライブラリのデモをJupyterでやっていた人がいて、なかなか良いなと感じたからです。結構分かりやすく、セットアップしていれば実際に動かすこともできるからです。そこで、FMDataAPIのサンプルをJupyter notebookベースで示せるようにしたいということがあります。

まず、Jupyterが動いている必要があります。以前にJuliaを入れた時に色々試行錯誤したこともあって、素直な手順がわからないのですが、Homebrewを使うなら、

brew install jupyter

もし使わないのなら、以下のように、pipのアップデートをしてからjupyterをインストールします。

pip3 install --upgrade pip
sudo pip3 install jupyter

PHPの稼働が必要ですが、Mojaveでは、Homebrewを使って入れるのが良いでしょう。こちらも、いろんな用途に使っているので、あれこれ試行錯誤した結果を使っています。何れにしても、php72を、brew installで入れています。

Jupyter用のPHPカーネルは、Jupyter-PHPをインストールします。なお、このカーネルを使うには、PHPのZMQ (ZeroMQ)のモジュールが必要になります。これは、Homebrewにないので、peclでインストールします。最初のコマンドを入れると、次のように、直接レポジトリを指定しなさいと出てくるので、ともかくそうします。

sudo pecl install zmq
sudo pecl install channel://pecl.php.net/zmq-1.1.3

php -iで、phpinfo()関数相当の情報を見てみますが、おそらくエラーが出ると思われます。peclが識別している.soファイルのフォルダと、php72の.soフォルダが違うからです。

メッセージを読めば、それぞれのパスがわかるので、例えば、以下のようなコマンドで、生成したzmq.soファイルを、php72の.soファイルの位置にコピーします。これで、php -iはエラーなく実行できました。

$ cp /usr/local/lib/php/pecl/20170718/zmq.so /usr/local/Cellar/php/7.2.12/lib/php/20170718
$ php -i|grep zmq
zmq
libzmq version => 4.2.5

続いて、Jupyter-PHPをインストールします。サイトのトップページに、インストーラーのダウンロードリンクがあります。署名付きで試したらエラーになったので、とりあえず、署名なしをダウンロードして以下のコマンドを打ち込むと問題なく終わりました。

cd ~/Downloads/
sudo php ./jupyter-php-installer.phar install

こうして、「jupyter notebook」とコマンドを入れれば問題なく使えるようになりました。NewのところにPHPが出てくるので、それを選択してノートブックを用意します。FMDataAPIのノートブックは出来上がれば。レポジトリに公開します。実行済みのノートブックだと、Outも全部入っているのですが、GitHubは多分、.ipynbをリードオンリーのノートブックとして開ける機能があるようなので、サンプルコードを解説とともに読めるノートブックを、該当ソフトウエアをインストールして稼働させなくても、結果を見ることができるようになります。

で、作業していると、コードのカラーリングがされないのがちょっと寂しいです。方法はあるようですが、これをやっても自分の環境だけなのではありますが、それでもカラーリングしたいので、探してみると、jupyter-themesというのがありました。手順通りインストールできました。wgetではなく、curlを使う程度の違いです。

mkdir -p $(jupyter --data-dir)/nbextensions
cd $(jupyter --data-dir)/nbextensions
mkdir jupyter_themes && cd jupyter_themes
curl -O https://raw.githubusercontent.com/merqurio/jupyter_themes/master/theme_selector.js
cd ../ && jupyter nbextension enable jupyter_themes/theme_selector

しばらくカラーリングはうまく動いていたのですが、今、これを書いている時にはなぜか動いていません。再起動ですしょうね。

[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はメールの整理・ストレージに移行するということです。

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