2019年12月12日 (木)

pandocでなんとかする話

Fujitsu Advent Calendar 2019の12日目です。 このエントリは個人の立場で書いております。 所属企業の見解を示すものではありません。

今年は最近個人的にちまちま書いているツールについて書こうと思います。 たいしたことやってるわけでは無いんだけど、 まあせっかく作ってるんだし。

そのモノはpandocでなんとかするためのツールです。

pandocは例えばmarkdownをHTMLとかに変換したりするのにとても便利なツールなのですが、 一群のmarkdownをまとめて変換しようとすると色々面倒があります。

  • 「一群」に含まれる他のmarkdownファイルへのリンクの拡張子を自動的に変更してくれない
  • 文書タイトルの扱いがなんか思てたんと違う
  • サブディレクトリがある場合、cssの相対パスとかの調整が面倒

等々。 こういった面倒事をよきにはからってなんとかするためのツールです。 名前は"Panasu"(ぱなす)と言います。 「んどっくでんとかる」の略です。 ソースはGitHub上に置いています。

縁起

メモをmarkdownで書きたいなあ、と思ったのがことの起こりです。

メモなんかOneNoteなりEvernoteなりのサービスを使えばいいじゃないか、 と言われればその通りで、 実際OneNoteを日常的なノートに使ってたりしてます。 そうなのですが、バージョン管理しながらプレーンテキストでメモしたいこととかもあるのです。 技術関連のメモとか。 コードブロックとか書きたいし。

じゃあ、GitHubなりGitLabに置けばいいじゃないか。 バージョン管理してくれる上にmarkdownは自動的にHTML化して表示してくれるし。 まあそうなんだけど(どうせgitに入れるんだし)、 サーバー側にコミットしないとHTMLで読めないのがなあ。 ネットワークがつながらない所でも手元ですぐ見れてほしいし、 HTML化されたmarkdown見てて「あっ、ちょっと書き方間違えてる」と気が付いて ちまちましたコミットがやたらと増えるの嫌なんですよ。 間違える自分が悪いんだけど。

ということで、 煮え切らないままに、 しばらくmarkdownを書いてそれをそのまま読む日々を送っていました。 が、ある日「やっとれるかー」と感極まってですね、 なんとかすることにしました。

最初はmarkdownを表示するブラウザのプラグインをいくつか試して、 ブラウザ経由で見る方法を試してみたんですけど、 フレームとか対応していないので左側に目次を置く構成とか面倒そうだし、 cssの指定とか柔軟じゃなさそうだし。 また、ローカルにWebサーバー立ち上げる式のツールも試してみたけど、 複数デバイスで共有することを考えると、 各環境にツール入れるんじゃなくて、 変換後のHTMLをOneDriveとかで共有できるようにした方がいいんじゃないかと感じました。 ということで、スクリプト一発でpandoc使ってhtmlを生成できるようにする方針で行くことにしました。

で、Makefileとかまじめに書いてたんですけど、 一群のファイルをひとかたまりとしてpandocで変換しようとすると、 色々と面倒が出てきまして。 しばらくスクリプトがりがり書いて頑張っていたんですけど、 ある日「やっとれるかー」と感極まってですね、 ツールを作ることにしました。

ざっと検索してみたんですけど、 似たようなツールはありませんでした。 皆さんどうしてるんですかね。 頑張って各自スクリプト書いているのかな。

効能

このツールは、 入力ディレクトリ下のソースファイル群をpandocを使って変換し、 それを出力ディレクトリにディレクトリ構造を保ったまま出力します。 その際に、 独自のpandocフィルタをかますことで、 以下の面倒事をなんとかします。

  • 変換に伴い相対リンクが切れてしまうのをなんとかします。 例えば、markdownファイル(拡張子.md)をHTML(拡張子.html)に変換する場合、 入力ファイルに"a.md"へのリンクがあれば、 それを"a.html"へ変換します。
  • pandocでタイトルの扱いが微妙に面倒なのをなんとかします。 詳細はGitHub上のチュートリアルを見ていただきたいんですけど、 markdown文書の先頭に唯一のlevel-1ヘッダとしてタイトルを書いておいてもらえれば、 だいたい期待した通りに出力される、はず。
  • メタデータの指定が面倒なのをなんとかします。 pandocでは変換に対するパラメーター的なものを「メタデータ」として指定できます。 メタデータはmarkdown中に埋め込むこともできますが、それをするとソースのmarkdownとしての互換性が低くなります。 コマンドラインで指定することもできますが、いちいちソースごとに指定するのも面倒です。 ということで、このツールでは"a.md"というソースファイルに対して"a.md.metadata.yaml"というファイルがあれば、 そこにこのソースに対するメタデータがYAML形式で記述されているとして扱います。
  • 変換セッション全体で共通なメタデータの指定が面倒なのをなんとかします。 例えば、入力ソースがすべて日本語文書の場合、 langメタデータの値を"ja"に設定する指定を各ソースに対して行うのは面倒です。 このツールでは、変換セッション全体に適用するメタデータをYAML形式で指定できます。
  • ローカルなCSSとかの指定が面倒なのをなんとかします。 pandocでソースをHTMLへ変換する場合、 変換後のHTMLファイルにスタイルシートを適用したい場合はcssメタデータを指定します。 そのcssが相対URLになる場合、ソースの場所に応じてcssのパスを調整する必要があります。 例えば、"a.html"に対しては"styles/style.css"、"sub/b.html"に対しては"../styles/style.css"のように指定しなければなりません。 これを何とかするため、メタデータに対して簡単なマクロ機能を提供します。 このケースの場合、共通メタデータ中にcssメタデータの値としてrebaseマクロとともにcssへのパスを書いておけば、 このツールがなんとかします。
  • 変換対象外ファイルへの相対リンクの扱いがなにかと面倒なのをなんとかします。 典型的には画像へのリンクですけど、 文書形式変換の対象ではないファイルへの相対リンクの扱いに二つのモードを用意しています。
    • その場で見るためのモード。 対象となる相対リンクはオリジナルのファイルを指すように書き換えられます。 例えば、"image.png"へのリンクは、"../md/image.png"のようにオリジナルの場所を指すように書き換えられます。
    • 出力をまとめてどこかへ持っていくためのモード。 対象となる相対リンクは変更されません。 その代わり、その相対リンクが有効であるようにするために、 オリジナルのファイルを出力ディレクトリ下へコピーします。

想定しているのはmarkdownからHTMLへの変換ですが、 pandocがサポートしている任意の入力・出力形式に対して適用することができます。

使い方

このツールは、現在のところPowerShell Coreのスクリプトと.NET Coreで書いたpandocフィルタでできています。 私は主にWindows上で使っていますが、 手っ取り早く試せるようにLinuxコンテナを作るDockerfileをご用意しております。

Linux上のdockerなり、Windows上のDocker Desktop for Windowsなりに対して 以下のコマンドを打てばpanasu:latestという名前のイメージができます。

docker build -t panasu https://github.com/ipponshimeji/Panasu.git#:Docker/Ubuntu_18.04

まあ、正直使ってくれる人はそんなにいないだろうと思っているので、 出来上がりイメージはレジストリに置いていません。

直接セットアップする場合や、コンテナ使う場合の詳細については、 インストールを見てください。

デフォルト状態での使い方としましては、 以下のようなディレクトリ構造を作ります。

- Documents(ここの名前は何でもよい)
  - _scripts
  - md
  - html

mdにmarkdownのファイルを格納します。 _scriptsにこのツールや変換に関する諸々を入れておき、 _scriptsディレクトリ上で_scripts/format.ps1を実行すると、 htmlに変換されたHTMLが出力されます。

コンテナイメージの場合は、 ~/PanasuSampleにこの構造のサンプルが格納されています。 ツール本体は~/.local/Panasuにあります。

詳細な使い方は、 チュートリアルにありますので、 ご興味ありましたらご覧くださいまし。 上の「効能」で述べた各機能の使い方も説明しています。

今後など

今作っているのがひと段落したら、 入力ディレクトリのファイルをまとめて一個にまとめるスクリプトも作ろうと思っています。 最終的に一枚のhtmlとかwordとかpdfにするやつ。 というか、 今頃はその機能ができているつもりだったんだけど、 この秋は何かと暇がなくて、あまり進みませんでした。 ぼちぼち進めていきたいと思っております。

パルナスとわたくし

さて、ここからは完全に余談なのですが、 ツールの名前をどうするか考えているときに、 「ぱんどっく、ぱ…ぱ…ぱなす、パルナス」とパルナスのことを思い出してですね。 思い出したついでに何か書き残しておこうと思うのです。

パルナスとは私の地元(神戸の西の方)の周辺にいくつか店があった洋菓子店です。 山陽電鉄や神戸電鉄の駅によく店がありました。 月見山駅と明石駅と三木駅に店があったのは覚えている。 板宿駅にあったっけなあ。 山陽そばがあったのは覚えている。大昔に洋菓子売っている一角があったような気がするけど、 もう震災前の板宿の記憶が定かではない。

まあともかく、 「モスクワの味」をキャッチフレーズに、 とんがり帽子の丸い口の子供が諸手をあげてうわーと走っているマスコットを掲げた店があったのです。 TV CMも流していました。 私的にはドレミファ噴水パレスと並ぶローカルCMの双璧です。

二年前くらいでしょうか、 ひょんなことからWikipediaの「パルナス製菓」の項を見つけまして、 2000年に最後の店舗が閉鎖、2002年にパルナスが解散していたことを知り、遠い目になりました。 パルナスの店がない世をもう20年近く過ごしていたのか。

そんなことも思い出して、 一時、ツールの名前を「パルナス」にしようかと迷いました。 ツールの語呂合わせどうしよう、ぱるなす、ぱんどっくでなんとかする、る、「る」って意外と言葉がない。 る、る、るしゃなぶつ、「ぱんどっくで廬舎那仏となんとかする」、 アイコンは金色に輝く大仏さんで。 この時、脳裏には廬舎那仏の前に展開する僧侶団がそれぞれ手にした経典をpandocで五色の瑞雲に変換するイメージが浮かんでいたのですが、 そこそこ知られた店の名前を流用するのも何か障りがありそうで、なんとか思いとどまりました。 なので、せめてここに記しておくものであります。

でもまあ、思い返してみたらパルナスのものを実際に食った記憶は無いんだなあ。

2018年12月 4日 (火)

それさえもおそらくは平穏なWindows 10 Mobile

Fujitsu Advent Calendar 2018の4日目です。 このエントリは個人の立場で書いております。

この期におよんで、Windows 10 Mobileについて書こうと思います。 今年はWindows 10 Mobile Advent Calendarが立たなかったので、ここに書く(自力で立てるような気概はない)。 富士通も昔TOSHIBAロゴの入ったWindows Phone出してたし、まったく縁がないわけでもないやろ(このエントリは個人の見解です)。

さて、Windows 10 Mobile。 Windowsベースのスマホです。 呼び名はちょこちょこ変わってまして、現在の名称は"Windows 10 Mobile"ですが、 昔は"Windows Phone"とか"Windows Mobile"とか呼ばれてました。 今でもざっくり"Windows Phone"でくくられることも多いです。 残念ながら、去年の秋に事実上のギブアップ宣言がありまして、先が無くなった状態なのですが、 我が家(家族5人)の家庭内シェアではいまだに過半数を占めております。

家庭内のスマホシェア

先が無くなったと言っても、 OSのサポート期限ははっきりしているし、 サポート中はどの端末にも定期的にWindows Updateがちゃんと降ってきて(偉い!)歯車ぐるぐるアップデート画面になっているし、 まだまだ運用はいけます。 とはいえ、 我が家においてもWindows 10 Mobile時代の終焉みたいなものがそろそろと見えてきてる感もあり、 そのあたりの近況など書いてみたいと思います。

これまでのあらすじ

うちは子供が三人おりまして、 妻と上の子はiPhoneを使っていますが、 下の子たち(現在中学生)には二年前からWindows 10 Mobile端末にLINEモバイルのSIMを入れて持たせています。 当初の目的はおでかけ時の連絡用。 二人分あわせて初期投資2万円、運用費月々1000円くらいでわりと安全安心な運用を行っております。 Windows 10 Mobile選択のポイントはペアレンタルコントロールがしっかりしていることと、 端末にきちんとOSの修正が降ってくる等の信頼性ですかねえ。 このあたりの経緯は過去に書いているので、ご興味のある方はご覧くださいまし。

当然ながら私もWindows 10 Mobile(MADOSMA Q601)を使っています。 普段使いには十分です。 でもまあ、アプリの品揃えはさすがに今ひとつ。 Windows 10 Mobile向けにはアプリを用意してくれないサービスもあったりしますが、 そういう場合は頑張ってWebから利用します。 逆に、店頭で店のアプリ入れろとかうるさく言われる時は、 「iOSでもAndroidでも大丈夫ですので…」「Windows Phoneです」「アッハイ」 みたいになって便利。

で、このWindows 10 Mobile家庭が今年をどのように過ごしてきたか。

マップがスカスカになる

まず、3月下旬から一か月くらい標準のマップがスカスカになるという事件が起きました。 陸地の形は出るんだけど、道路とか地名とかが入ってなくてスカスカ。

このスカスカ地図が出た時の衝撃。 何というか、「世界が終わった」感というか、 知らないうちに文明が消えて自分だけ取り残されてしまった感というか、 まあ、なすすべもなく脱力します。 落ち着いて考えれば代替サービスもあるので、 何とかなるんですけど。

2012-2014年頃、 「Windows Phoneの日本展開を見合わせる」とアナウンスされてたWindows Phone好きにはつらい時期、 同様に標準マップの日本の部分がスカスカでした。 あの頃のつらみがフラッシュバックしそうになるじゃないか。

二三日様子を見てても直らないし、 もうこれは終わってしまったのか、と覚悟しました。 が、一カ月ほどしたら突然元通りに直りました。 何のアナウンスもなし。 何だったんですかね。

twitterアプリが立ち上がらなくなる

6月初旬の日曜日の朝に娘に叩き起こされました。 「twitterアプリが起動しない」と言います。 娘は日曜日朝にtwitterの実況を見ながら鬼太郎をリアルタイムで見て悶絶するのを生きがいにしているので、 これは重大インシデントです。

確かにtwitterアプリを起動しても、 途中で何かエラーになっているらしく、 立ち上がってこない。 端末を再起動してもだめ。

アプリがアップデート履歴を見ると、案の定、夜のうちにアップデートされており、 システム必要条件がWindows 10 15063(version 1703)以降になっていました。 一方、子供らの端末はversion 1609までしかアップデートできない。

仕方ないので、ブラウザからtwitterを見る運用にしました。 アプリの代わりにtwitterのURLへのショートカットタイルをスタート画面に貼ります。 タイムライン見る上では操作性はあまり変わりません。 プロフィールへ飛ぶリンクが反応悪いのと、油断するとEdgeで画面が何枚も開いてしまうのがちと難点。

まあ、鬼太郎の放送に間に合ってよかった。

今、手元のtwitterアプリを確認したら、システム必要条件はversion 1609以降になってる。 戻したのかな。

Slackアプリの更新が終わる

6月中旬にはSlackアプリの更新が終わりました。 Slackを立ち上げると「最後のごあいさつ」が出てびびりました。 「今回のリリースがWindows Phone版Slackの最後のアップデートとなります」とのことです。

うちでは家庭内連絡にSlackも使っています。 アプリが動かなくなるわけではありませんが、 この先セキュリティホールとか見つかっても修正されないことになります。 OSがまだちゃんとメンテナンスされていると言っても、 アプリの修正が終わっていくとなると、 そろそろ移行しないとなー、という機運がもう一段高まるわけです。

まったくもってその通りでございます。 ありがとうございました。

息子の端末の調子が悪くなる

秋に入って、 息子の端末の調子が悪くなってきました。 まあ、息子のモノの扱いが荒いのもあるんだろうけど。 特にバッテリーが目立ってへたっている。

同時に、LINEアプリがなかなか立ち上がらないとのクレーム。 他のアプリを終わらせてる状態でも、3,4回に1回ぐらいでしか起動に成功しない。 廉価機でメモリ少ないから、アプリがアップデートで大きくなってくるとねえ。 今や中学校のクラスや部活の連絡はLINEがメインだそうで、 LINEが使いにくいのは致命的だそうです。 こいつ意外とリア充。 娘の方はLINEめんどくさそうで、どうでもよさげなのに。

そこで、私が予備機にしているMADOSMA Q501を設定しなおして 息子用にしました。 LINEも百発百中で起動するし、画面が綺麗になったと喜んでおります。 よかろうが。 お父さんはちょっとのことでもゆーざーえくすぺりえんす?改善を体感できるように最初はあえて廉価機にしとったんや(嘘)。

メイン機のバッテリーが膨張する

10月に入って、自分がメインで使っているMADOSMA Q601の裏蓋に隙間ができていることに気づきました。 「おや?」と思っているうちにどんどん隙間が大きくなっていきます。 バッテリーが膨らんでいるようです。 いわゆる「妊娠」と呼ばれる状態です。

バッテリーが膨張したQ601

最初はテープでも貼っといて使い続けたろとか思っていましたが、 日に日に煮られた貝のように裏蓋がじわじわ開いていくのに心が耐えられなくなって、 メーカー(マウスコンピューター)に見てもらうことにしました。

困ったのは代機。 予備機はちょっと前に息子用にしてしまった。 しばらく迷って、結局Q501をもう一台買いました。 今安く手に入るW10M機の中で一番信頼できる奴だし。 しかし、若干の「何しているんだ俺様」感。

で、マウスコンピューターからの回答。

バッテリー膨張により背面カバーが浮き上がってしまっている症状を 確認いたしました。 パーツ単体での交換が行えないため、本体交換にて対応させていただきます。

...

本体 MADOSMA Q601 … 42,800円

それ、新品買うのとほとんど変わらんやないですかー。 だからバッテリーは交換可能にしてくれよう。 修理断念。 代機のQ501が主力機に昇格。

これにより、 我が家のWindows 10 Mobile時代の終焉が前倒しされました。 旧主力機(Q601)はversion 1709が載るので2019年12月10日がOSのサポート終了日でしたが、 新主力機(Q501)はversion 1703までなので2019年6月11日で終わり。

娘の端末のOSのサポートが切れる

10月9日でversion 1607のサポートが終了しました。 サポート期間が1年延長されたと色めき立つも、単なる記載ミスだと判明し、 結局終わってた。 しょぼーん。

これは要するに娘の端末のOSサポートが終了したことを意味します。 近々なんとかせなならん。

息子が「ポケGoしたい」と言い出す

「このスマホにはポケGo入らないの?」と聞かれました。 ついに来た。 友達がポケGoやり始めたらしく、 みんなの見ているだけじゃつまらんと言います。

幸い、 こいつは音楽とゲーム実況見る用にお年玉でiPod Touchを買っていたので、 そちらにポケGoを入れて、 Windows 10 Mobileからテザリングで繋ぐようにしました。 あと、モバイル回線ではあまり動画を見ないように注意。

テザリングにひと手間かかりますが、特に気にせずやっているようです。

メールとカレンダーが起動しなくなる

つい先日は、 標準アプリのOutlookメールとOutlookカレンダーが起動しなくなりました。 どうやらこの問題らしい。

マップがスカスカになったときと異なり、 世界的に問題になったせいか、 すぐに修正されましたけど。

今後にむけて

今後ねえ…

さしあたって、 OSのサポートが終わった娘の端末を更新しなければならない。 元々、来年の高校進学前に買い替える予定だったので、 少し前倒しして年明けにでも新調することでしょう。 妻はiPhoneを推すのですが(本人は何でもいいらしい)、 iPhoneは高いモデルばっかりになっちゃったなあ。

一方、私と息子の端末もサポート終了が来年6月までなので、 次の春には移行を考えるかなあ。

といったことを思いつつ、 家庭内絶対多数派でありながらすぐ近くに終わりが見えているこの世界で、 Windows 10 Mobileと毎日ささやかに暮らしております。 時々問題が起こったりもしていますが、 それさえもおそらくは平穏な日々。

タイルUI、スマホでは使いやすくて好きだったんだけどなあ。 デスクトップや大きなタブレットだと微妙だけど。

来年機会があれば「Windows 10 Mobileは衰退しました」とか書くだろうかと考えてみたけど、 まあ、もう書くことは無いかな。

終わりに

特にオチはありません。 なんでしたら、うちの猫見ていってください。

うちの猫 その1

うちの猫 その2

うちの猫 その3

2018年2月12日 (月)

AlexaのカスタムスキルをTypeScriptで書く

やってみたことの覚え書き。 AWS Lambda上で動かすAlexaのカスタムスキルをTypeScriptで書くにはどうすればよいか。

例として、「Alexaスキル開発トレーニングシリーズ 第1回 初めてのスキル開発」の「宇宙豆知識」をTypeScriptで書いてみます。

npmパッケージを追加する

javascriptでAWS Lambda上で動かすスキルを書く場合、 以下のnpmパッケージをインストールしていることでしょう。

  • aws-sdk
  • alexa-sdk

これに加えて、以下のTypeScript用の型情報パッケージをインストールします。

  • @types/node
  • @types/aws-lambda
  • @types/alexa-sdk

"@types/node"はNode.jsの機能を使う場合に必要になります。 例えば、スキル実装の定石として、以下のようなコードがあります。 アプリケーションIDを環境変数"APP_ID"から読み込むものです。

    const alexa = Alexa.handler(event, context);
    alexa.appId = process.env.APP_ID;

このprocessはNode.jsのオブジェクトですので、 「process.env」をTypeScript上で型解決するには"@types/node"が必要になります。

"@types/aws-lambda"はLambdaの機能を利用する場合に必要となります。 しかし、単純なスキルの実装では、 Lambdaの機能を明に利用することはほとんどないでしょうから、 不要かもしれません。

型を利用してプログラムする

型情報を利用して、 「Alexaスキル開発トレーニングシリーズ 第1回 初めてのスキル開発」の「宇宙豆知識」のindex.jsをTypeScriptで書くと、 以下のようになるんじゃないかな。

import * as Alexa from 'alexa-sdk';

//=========================================================================================================================================
//TODO: このコメント行より下の項目に注目してください。
//=========================================================================================================================================

//Replace with your app ID (OPTIONAL).  You can find this value at the top of your skill's page on http://developer.amazon.com.  
//Make sure to enclose your value in quotes, like this: var APP_ID = "amzn1.ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1";
const APP_ID = undefined;

const SKILL_NAME = "豆知識";
const GET_FACT_MESSAGE = "知ってましたか?";
const HELP_MESSAGE = "豆知識を聞きたい時は「豆知識」と、終わりたい時は「おしまい」と言ってください。どうしますか?";
const HELP_REPROMPT = "どうしますか?";
const STOP_MESSAGE = "さようなら";

//=========================================================================================================================================
//「TODO: ここから下のデータを自分用にカスタマイズしてください。」
//=========================================================================================================================================
const data = [
    "水星の一年はたった88日です。",
    "金星は水星と比べて太陽より遠くにありますが、気温は水星よりも高いです。",
    "金星は反時計回りに自転しています。過去に起こった隕石の衝突が原因と言われています。",
    "火星上から見ると、太陽の大きさは地球から見た場合の約半分に見えます。",
    "木星の<sub alias='いちにち'>1日</sub>は全惑星の中で一番短いです。",
    "天の川銀河は約50億年後にアンドロメダ星雲と衝突します。",
    "太陽の質量は全太陽系の質量の99.86%を占めます。",
    "太陽はほぼ完璧な円形です。",
    "皆既日食は一年から二年に一度しか発生しない珍しい出来事です。",
    "土星は自身が太陽から受けるエネルギーの2.5倍のエネルギーを宇宙に放出しています。",
    "太陽の内部温度は摂氏1500万度にも達します。",
    "月は毎年3.8cm地球から離れていっています。"
];

//=========================================================================================================================================
//この行から下のコードに変更を加えると、スキルが動作しなくなるかもしれません。わかる人のみ変更を加えてください。  
//=========================================================================================================================================
export const handler = function<T extends Alexa.Request>(event: Alexa.RequestBody<T>, context: Alexa.Context, callback?: (err: any, response: any) =< void) {
    const alexa = Alexa.handler(event, context);
    alexa.appId = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

const handlers: Alexa.Handlers<Alexa.Request> = {
    'LaunchRequest': function (this: Alexa.Handler<Alexa.LaunchRequest>): void {
        this.emit('GetNewFactIntent');
    },
    'GetNewFactIntent': function (this: Alexa.Handler<Alexa.IntentRequest>): void {
        const factArr = data;
        const factIndex = Math.floor(Math.random() * factArr.length);
        const randomFact = factArr[factIndex];
        const speechOutput = GET_FACT_MESSAGE + randomFact;
        this.emit(':tellWithCard', speechOutput, SKILL_NAME, randomFact)
    },
    'AMAZON.HelpIntent': function (this: Alexa.Handler<Alexa.IntentRequest>): void {
        const speechOutput = HELP_MESSAGE;
        const reprompt = HELP_REPROMPT;
        this.emit(':ask', speechOutput, reprompt);
    },
    'AMAZON.CancelIntent': function (this: Alexa.Handler<Alexa.IntentRequest>): void {
        this.emit(':tell', STOP_MESSAGE);
    },
    'AMAZON.StopIntent': function (this: Alexa.Handler<Alexa.IntentRequest>): void {
        this.emit(':tell', STOP_MESSAGE);
    }
};

ポイントとしては、以下の通り。

  • varをconstに変更しているけど、これはTypeScriptに限らず、今となってはほとんどのvarはconst/letにした方がよい。
  • javascriptの"require('alexa-sdk')"はTypeScriptのimport文に変更する。
  • 唯一エクスポートする"handler"に"export"指定を追加。
  • 登録するハンドラを正しく型付ける。これにより、ハンドラ内の実装で型による検証が効くようになる。

で、TypeScriptで型付けを行った効果として、 潜在していたバグを見つけました。 上のソースで以下のように書いている部分、

    alexa.appId = APP_ID;

Alexaスキル開発トレーニングシリーズ 第1回 初めてのスキル開発」のオリジナルのサンプルでは、

    alexa.APP_ID = APP_ID;

となっています。 "alexa.APP_ID"は"alexa.appId"の間違いでしょう。 javascriptだとこの手の間違いは文法上間違いではないので、なかなか顕在化しませんが、 TypeScriptだと翻訳段階(チェック機能のあるエディタだとコーディング段階)であっさりと検出できます。

なので、TypeScriptの方が開発効率も安全性も向上すると思うんだけどなあ。

おまけ: インテントオブジェクトへのアクセス

多くの場合、 インテントのハンドラでは、インテントの内容を見なければなりません。 例えば、スロットの値を取得したりします。

    'MyIntent': function () {
        let value = this.event.request.intent.slots.MySlot.value; // スロットMySlotを参照
        ...

これを単純にTypeScriptで型付けすると、エラーになります。

    'MyIntent': function (this: Alexa.Handler<Alexa.IntentRequest>): void {
        let value = this.event.request.intent.slots.MySlot.value; // スロットMySlotを参照
        ...
[ts] オブジェクトは 'undefined' である可能性があります。

要するに、 "this.event.request"はAlexa.IntentRequestインターフェイス型なのですが、 その"intent"プロパティの定義は「Alexa.Intentインターフェイス型、またはundefined」となっており、 undefinedの場合"intent.slots"がエラーになる、と言っています。

この場合、このハンドラが呼び出されている時点でintentはundefinedでないだろうから、 以下のように書けばよいでしょう。 (intentが万一undefinedならば実行エラーとなる)

    'MyIntent': function (this: Alexa.Handler<Alexa.IntentRequest>): void {
        const intent = this.event.request.intent as Alexa.Intent;
        let value = intent.slots.MySlot.value; // スロットMySlotを参照
        ...

2018年2月 1日 (木)

Docker for Windowsでコンテナイメージの置き場所を変える

覚え書き。 Docker for Windowsで、コンテナイメージとかの置き場所を変更するにはどうするか。

  • Windowsコンテナの置き場所を変更する
  • Linuxコンテナの置き場所を変更する
  • 参考

Windowsコンテナの置き場所を変更する

構成ファイルの"graph"設定で指定する。 例えば、置き場所を"D:\Docker"にするには、 構成ファイルに以下のエントリを追加する。

{
  ... ,
  "graph": "D:\\Docker"
}

構成ファイルを編集するには、以下の方法がある。

  • 構成ファイルを直接編集する。構成ファイルのパスは"C:\ProgramData\Docker\config\daemon.json"
  • Docker for Windowsの設定GUIから編集する。設定GUIの「Deamon」で「Advanced」をオンにすると、構成を編集することができる。
【2018/02/05追記】 書き忘れていたが、 構成ファイルを編集する前に、Docker for WindowsのモードをWindows Containerにしておくこと。 デフォルトの構成ファイルはWindows Containerモードの初回実行時に生成されるし、 Linux Containerモードで設定GUIから構成ファイルを編集すると、Docker for Windowsが起動しなくなる。 (おそらく、Linux Containerの構成が変更されてしまう)

Linuxコンテナの置き場所を変更する

LinuxコンテナはHyper-VのVMの中で動く。 Docker for Windowsの稼働中にHyper-Vマネージャーを見ると、 "MobyLinuxVM"という名前のVMが動いているはず。 で、LinuxコンテナのイメージとかはこのVMの中に格納されるらしい。

というわけで、 Linuxコンテナのイメージの置き場所を変更するには、 "MobyLinuxVM"の仮想ディスクファイル(VHD)の置き場所を変えるということになる。

"MobyLinuxVM"はHyper-Vの設定に従ってDocker for Windowsが勝手に作成するので、 それはつまり、Hyper-Vの設定の「仮想ハードディスクのファイルを保存するための既定のフォルダー」を変更するということになる。

ちなみに、以下の手順を行うと、

  1. Docker for Windowsを停止させる。
  2. "MobyLinuxVM"の仮想ディスクファイルを削除する。
  3. Docker for Windowsを再起動する。("MobyLinuxVM"の仮想ディスクが再作成される)
  4. docker imagesを実行する。

pullしていたLinuxコンテナイメージがリストアップされなくなったので、 確かにLinuxコンテナイメージは"MobyLinuxVM"の中にあるみたい。

参考

あちこちに似たようなQAがあるけど、 以下が一番直接的だった。

Put "C:\ProgramData\Docker" on a different drive? Configuration option? (GitHub)

2018年1月 9日 (火)

AthlonマシンにWindows UpdateでMeltdown/Spectre対応をあてるとWindowsが起動しなくなる件

1月3日(US時間)にMeltdown/Spectre対応と思われるWindowsの修正がWindows Updateで配信されました。 Windows 10 version 1709(Fall Creators Update)向けはKB4056892ですね。

で、これを適用すると、 古いAMD AthlonマシンでWindowsが起動しなくなる現象が起こっているようです。

CPU脆弱性への修正含む「Windows」アップデートでAMDユーザーに不具合 (ZDNet Japan)

【2018/02/01追記】 この問題に対処した修正が公開されたようです。 version 1607, 1703は1/17, version 1709向けは1/31のやつ。 私はまだ試していないけど。

うちにも一台Athlon 64 X2のマシンがあり、 このマシンで同じ現象が起きました。 マシンは起動するんだけど、Windowsロゴが出た後だんまりになる。

ただ、うちの場合、記事に書かれている人のような面倒事にはならなかったので、 対処法をメモしておこうかなと。 これができるのは、

  • Windows 10 version 1703以降。かつ、
  • 以下のいずれかのエディション。
    • Pro
    • Enterprise
    • Education

の場合です。 記事の人はHomeエディションだったのかな。

うちの対処法

  • 起動後、じきに固まるので、電源をぶちっと落とす。 これを繰り返すと、三度目で復旧が走り出したので、 そのまま復旧させる。
  • 復旧したらすかさずログオンする。 ここでもたもたすると、また同じ修正が当たって起動しなくなる。
  • 直ちに「設定」-「更新とセキュリティ」-「Windows Update」-「詳細オプション」を開き、 「更新の一時停止」を「オン」にする。 この「更新の一時停止」設定はCreators Update以降のPro/Enterprise/Educationにある。

これで問題の修正が再度適用されることを防ぐことができます。 一時停止の期間は最大35日ですが、 その間には直してくれるやろ。

2017年12月 9日 (土)

せめて作業場所節の名前だけでも覚えて帰ってください

Fujitsu Advent Calendar 2017の9日目です。 このエントリは個人の立場で書いております。 なのですが、 せっかくなので業務で開発に携わっているモノを紹介しようと思います。 説明上、特定の製品の話も出てきますが、宣伝の意図はありません。 くどいですが、このエントリは個人的に書いているもので、所属企業の見解を示すものではありません。

さて、 私が開発に携わっているモノとは、COBOL処理系です。 富士通が何かやっているというニュースが出ると、 「どうせCOBOLだろw」みたいな反応が出たりもする、 みんな大好きCOBOLです。

古代の遺物扱いされることも多いのですが、 コードはまだまだあるところには大量にあります。 ぜひ「知っている言語」の一つに入れておいてもらって、 どこかのシステムの奥底からCOBOLコードが出てきた際には、 げえっと叫んで封印するのではなく、 読んで、場合によっては手直しなどしてもらえればなと思います。

ざっと以下の内容。

おかんについて

まずは、わたしらのおかんを紹介したいと思います。 Grace Hopperです。 COBOLの母です。 おかんがCOBOL作りました。

米海軍准将でした。 けっこう偉大な人なので、 その名を付けた駆逐艦があります。

つまり、うちのおかんはリアル艦娘です。 ハイパー婆さんなのに駆逐艦。 「バブみ」などという言葉ではとうてい表現できない歴史の深みです。 ひげのおっさんとかではなく駆逐艦が作った言語と聞くと、 ちょっとやってみようという気になりませんでしょうか。 なりませんか。そうですか。

Grace Hopperといえば、 コンピューターにおける「バグ」語源にからんだり、 「許可を求めるより後で謝った方が簡単だ」という名言を残したり、 逆回りの時計を壁に掛けていたり、 色々エピソードのある人です。 生きていれば、本日101歳の誕生日です🎂。 1992年に亡くなっていますが、 女性技術者の集まりである"Grace Hopper Celebration"に名を冠されていたり、 去年はアメリカ合衆国大統領自由勲章が授与されたり、 今なお存在感があります。

プログラムのスタイルについて

そんなおかんが開発したCOBOLはLispやFortranと並んで最古参の高級言語のひとつです。 記号をあまり使わず、 英語の文章のようにプログラムを記述していくスタイルです。 試しに簡単なプログラムを書いてみましょう。

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MAIN.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WK.
         02 FILLER  PIC X(6) VALUE "Hello".
         02 WK-NAME PIC X(5).
         02 FILLER  PIC X    VALUE "!".
       PROCEDURE DIVISION.
           DISPLAY "? " WITH NO ADVANCING.
           ACCEPT WK-NAME.
           DISPLAY WK.
       END PROGRAM MAIN.

"PROCEDURE DIVISION."と書かれてある行より後ろがプログラム本体になります(『手続き部』)。 この部分はとても文章的です。 まあ、文章的な代わり、 ちょっと複雑な処理を書こうとすると色々書かなきゃならないのが面倒になってくるのですが。 その「本文」の流れに邪魔になる様々な定義はほかの部分、

  • IDENTIFICATION DIVISION(『見出し部』)
  • ENVIRONMENT DIVISION(『環境部』、このプログラムでは省略されている)
  • DATA DIVISION(『データ部』)

に記述するようになっています。

このプログラムは、 例えば"World"を入力すると、"Hello World!"と返すものです。 以下のような感じ。

? World
Hello World!

このユーザー入力を受け取る部分は "ACCEPT WK-NAME."と書かれている行になります。 「"WK-NAME"という『変数』に入力を受け取る」という意味の文です。 この『変数』"WK-NAME"の定義はデータ部にあります。

       WORKING-STORAGE SECTION.
       01 WK.
         02 FILLER  PIC X(6) VALUE "Hello".
         02 WK-NAME PIC X(5).
         02 FILLER  PIC X    VALUE "!".

"PIC X(5)"は、 まあ、ざっくり言えば、「5文字分の領域」という意味になります。 なので、富士通のNetCOBOLの場合、 5文字分入力されるまで入力を待ち続けます。 3文字入力してEnterを押してもあと2文字入力されるまで律義に待ち続けます。 ちなみに、5文字以上を入力すると、余った入力は切り捨てられます。

で、プログラムの最後では、"WK-NAME"を含む"WK"全体を一気に出力しています。

           DISPLAY WK.

今時の感覚からすると、 文字列とかは可変長の「文字列オブジェクト」で扱ってほしいし、 テキストのフォーマットももっと動的に処理すれば使い勝手良いだろうに、 とか思うのです。 まあ、複雑な文字列編集を行うための文とかもあるのですが、 この程度ならばこんなふうに書いてしまうことが多い。

このあたりのデータの取り扱いの感覚が今時の言語との大きな違いではないかと思います。 何と言いますか、発想が帳票的です。 上のデータ定義、 そう思ってみると、 帳票的なイメージがしてきませんか? "WK"という一塊のデータ(レコードと言います)を定義し、 その内部の各欄に6文字、5文字、1文字というサイズを割り当てています ("FILLER"は「名前?名前などどうでもよい」という意味)。

それは構造体のようなものではないのか? 構造体の先祖と言えるかもしれませんが、 今となっては「構造体」で期待するものとかなり違うんじゃないかなあ。 COBOLのレコードは参照が含まれることがほとんどないので、 本当に固定長のべたな領域を区切っていることになります。 領域に余白ができたら自動的に空白を詰めたりします。 ファイルの読み書きもそのレコードをそのままべたに読み書きする感じ。

今の眼からすると、 COBOLはそういった帳票的なデータを加工したり入出力したりするための言語とイメージすると、 分かりやすいんじゃないでしょうか。

「事務作業なんて要するに何かの帳票を読んで別の帳票を作ることだろう」と割り切ったとでも言いますか。 英語の文章的な記述法といい、 おかんは技術者ではない一般の人でも事務作業を自動化できるようなモノを作りたかったのではないかと思います。 今で言えば、Excel的なものでしょうかねえ。 ただ、事務作業向きといっても、 やろうと思えばかなりのことができてしまいます。 それが行き過ぎて、神Excelならぬ神COBOLみたいなコードも大量にあったりします。 適材適所は大事。

ともあれ、 COBOLのデータの取り扱いは今時の言語のデータの取り扱いとは発想がかなり違っています。 この違いが、十進演算と並んで、COBOLの置き換えが結構難しい技術面での原因ではないかと思います。 興味があれば、 COBOLの表の添字付けについても調べてみてください。 COBOLの表は多くの言語での配列に相当するものですが、 多段になっている場合の添字付け方法が今時の言語とまったく異なっています。

ちなみに、 このデータ部の変数を定義する部分(WORKING-STORAGE SECTION)、 日本語では「作業場所節」と言います。 変数は「場所」なのです。 いかにもです。 ここに定義したデータは、C#やJavaなどで言うところのstatic的に割り付けられます。 つまり、もう一回このプログラムを呼び出すと、 "WK-NAME"には前回のデータが残ってます。 いったんプログラムがロードされてしまえば、 メモリ不足やStackOverflowが発生しにくい安心安全設計。 なお、2002年規格以降は、 ローカルなデータも定義できるようになっています。 ローカルなデータは局所記憶節(LOCAL-STORAGE SECTION)という場所に書きます。

いにしえの記法について

上のプログラム、左の余白が目につきます。 実は、この余白(行の先頭6カラム)は行番号領域です。 ですが、今となっては空白にしておくのが吉です。 下手に自動ナンバリングとかしてしまうと、 行を追加/削除した場合に以降の行番号がずれて、 ソース管理上そいつら全部が変更された扱いになってしまいます。

また、7カラム目は標識領域で、 ここに「*」が記述されていたら、その行はコメントです。

こんな調子で、昔のCOBOLのソースにはカラムに意味があります。 古典的な書き方では、73カラム以降はコメント(見出し領域)です。 下手にソースをUTF-8化すると、非ASCII文字を含む行で本文のカラムが増えて、 コード末尾が勝手にコメントになってしまうという事故が起きたりします。 その他、「この要素はこの領域から書き始めないとダメ」みたいな規則もあり、 解析処理を書く際にカラムの考慮が極めてだるいです。 文字コードの問題がからむとなおさら。

なんでこんな書き方をするのか。 今でこそみんなPCを持っていて、 エディタでプログラムを書くわけですが、 昔は一人一台端末を占有しつづけるなどできませんでした。 じゃあ、どうやってプログラムを書いていたかといえば、 こんな紙に書いていました。

コーディング用紙

コーディングシートというやつですね。 この紙に書いたプログラムをコンピューター室に持っていって入力したり、 さらに古くはパンチカードを打ってそれを読み込ませたりしていたそうです。 私自身は経験ないけど。

COBOLの古い書式は、このような昔のやり方に合うようにできていたのでしょう。 今では、カラムを意識しない「自由形式」という書法でも書けるのですが、 デフォルトは互換性のためにこの古い「固定形式」ですし、 なにより大量にある既存のソースが古い形式で書かれています。 カラムの呪縛からはなかなか逃げられない。

現状など

さすがに今となっては、世の中の最前線の課題の解決を期待されるようなことはあまりない、と思います。 が、COBOLの特徴は無限のCOBOLプログラムを内包する世界を創り出してしまっていることにあります。 Unlimited COBOL Worksです。 皆さんも日常生活で間接的にCOBOLプログラムを利用しているはずです。 銀行や自治体のシステムとか、表はWebで操作したとしても、 その最深部ではCOBOLプログラムが動いていたりします。 ちょっと古いのですが、2010年頃、 世界で2400億行のCOBOLコードが稼働しているという話がありました。 現在もまだまだコードが書かれています。 こいつらを無事に動かし続けなければなりません。 そのため、 新しいOSや環境で動くようにしたり、 連携できるようにしたり、 やることはまだまだあります。

で、新しいシステムと連携できるようにしたりすると、 「またCOBOLかよw」などと言われたりするわけですね。 数年前にHadoop対応をしたときも「なんでまた」みたいなコメントがありました。 あれ、ビッグデータをやりたいわけではなく(やってもらってもかまわないのですが)、 既存のCOBOLバッチを分割して並行に走らせたいんだけど、 それを独自の基盤を作るのではなく、 よく知られている基盤の上でやろうという話です。 別に流行りだからと何も考えずにやっているわけではないのです。 いや、何も考えずに流行りものをやってみたいとか、思ったりもしていますけど。

ハードや環境が変わっても同じ機能を動かし続けることができる、 というのがソフトウェアに期待される役割のひとつだとすれば、 それをしぶとく勤め続けております。 まだ当分、COBOLは使い続けられることでしょう。 COBOLで「先の規格」といえば応仁の頃に制定されたやつのことですが、 現行は2014年版で、 その次に向けても動きが始まっています。

今時の機能をCOBOLで書いてみる

せっかくなので、COBOLでもう少し書いてみましょう。 富士通の.NET向けCOBOL(NetCOBOL for .NET)を使ってみます。 実は、最古参の高級言語であるところのCOBOLは.NETプラットフォームにおいても最古参のサードパーティ言語だったりします。 2000年の.NET Framework発表直後のPDC 2000で、 ゲイツ先生に「わしも昔はCOBOL書いたがな」と紹介されてデモしたりしてます。 Channel 9でビデオを見れます。 COBOLの紹介は1:27:30頃から。今から見ると実に素朴。

ここで、 .NETとCOBOLのデータ型のマッピングなどを説明して、 「COBOLプログラムを.NETの一般的なデータ型で呼び出せるようにラップしてライブラリ化すれば、任意の.NET言語から利用可能になります」 とか述べればそれなりにお役に立つのでしょうが、 それはマニュアルにも書いてあるし、 せっかくのアドベントカレンダーですので、 ふつうCOBOLで書かないような処理を書いてみましょう。

async処理をCOBOLで書いてみます。

お題としては、 以下のような非同期でWeb上のテキストファイルを取ってくるメソッドがライブラリとして提供されているとして、

public class Downloader: IDisposable {
    private HttpClient httpClient = new HttpClient();

    public async Task<string> DownloadText(string uri) {
        string text;
        using (HttpResponseMessage response = await this.httpClient.GetAsync(uri)) {
            if (!response.IsSuccessStatusCode) {
                throw new Exception($"Error: {response.StatusCode}");
            }
            text = await response.Content.ReadAsStringAsync();
        }

        // 以下の行を入れてわざと待たせるようにすると、
        // 非同期に動作していることがGUI上から分かりやすい。
        await Task.Run(() => { Thread.Sleep(3000); });
        return text;
    }
    ...
}

以下のようなイベント処理をもつWindows FormをCOBOLで書いてみます。

private Downloader downloader = new Downloader();
...
private async void button_Click(object sender, EventArgs e) {
    // 処理中はボタンを無効化し、二度押しを防ぐ。
    this.button.Enabled = false;
    try {
        string message;
        try {
            string text = await this.downloader.DownloadText("http://www.msftncsi.com/ncsi.txt");
            message = $"[{DateTime.Now}] {text}";
        } catch (Exception exception) {
            message = exception.Message;
        }
        this.label.Text = message;
    } finally {
        this.button.Enabled = true;
    }
}

テキストのダウンロードは非同期処理なのですが、 その後、ラベルのテキストを更新してボタンを有効化する処理があります。 awaitを記述することで、 そのあたりがすっきり記述できています。 C#のasync/await機能ですね。

実行して、ウィンドウのボタンを押すと、こんな結果になります。

サンプルのGUI

Visual Studio 2017向けのNetCOBOL for .NETは(国内向けには)まだ出ていないので、 Visual Studio 2015 + NetCOBOL for .NET V7で書きます。

NetCOBOL for .NETはWindows Formsをサポートしています。 NetCOBOLのWindows Formsプロジェクトテンプレートからそのままプロジェクトを起こせます。 なぜWPFでないかと言えば、 残念ながらNetCOBOL for .NETでは諸般の理由によりWPFベースのGUIの作成をサポートしていないからです。 だって死にそうな思いで無理くりCodeDOM実装したのに、WPFではまったく別のコード生成インターフェイス使いよるし。 まあ、今となってはどっちみちRoslyn以前のものだけど。

で、Windows Formsを使うとして、 このasync付きのイベント処理をどうやってCOBOLで書くか。 当然、現在のCOBOLにはasync/await構文とかありません。 が、幸いなことに、.NETの機能の多くは素のクラスを使って記述可能です。 genericsを最後に構文に手を入れる必要があった覚えがありません。 LINQだろうがasyncだろうが、素のクラスとメソッド呼び出しだけで、がんばれば書けます。 がんばれば。

というわけで、 上のイベント処理を素のクラスとメソッドを使った処理に展開します。

  • 非同期処理をTask<string>オブジェクトを使う形で記述します。 非同期処理完了後の後続処理の実行はTask<string>.ContinueWith()メソッドを使ってスケジュールします。 C#のasync/awaitの展開では、ContinueWith()を単純に使わずに内部クラスを生成して色々処理をしています。 おそらくawaitが複数ある場合や例外処理をうまく処理するためでしょう。 が、今回の処理程度であれば、ContinueWith()で十分でしょう。
  • GUIはGUIスレッド上で操作しなければならないことに注意します。 C#のasync/awaitの展開ではよしなに計らってくれますが、 自力で展開する場合は自分で実装する必要があります。 ここでは、FormInvoke()メソッドを使います。
  • COBOLでラムダは書けないので、独立したメソッドに処理を記述します。 クロージャーが必要な場合は、そのためのクラスを新たに作らなければなりませんが、 幸いこのケースではそこまで必要ありません。 このForm内にメソッドを定義するだけで十分です。

いきなりCOBOLで書いても分かりにくいでしょうから、 まずC#で書きます。 以下のようなコードをこの後COBOLで書きます。

private Downloader downloader = new Downloader();
...
private void button_Click(object sender, EventArgs e) {
    this.button.Enabled = false;
    try {
        this.downloader.DownloadText("http://www.msftncsi.com/ncsi.txt").ContinueWith(
            new Action<Task<string>>(this.ContinuedProc)
        );
    } catch {
        FinallyProc();
        throw;
    }
}

private void FinallyProc() {
    this.button.Enabled = true;
}

private void ContinuedProcBody(Task<string> task) {
    try {
        string message;
        if (task.Exception == null) {
            message = $"[{DateTime.Now}] {task.Result}";
        } else {
            message = task.Exception.Message;
        }
        this.label.Text = message;
    } finally {
        FinallyProc();
    }
}

private void ContinuedProc(Task<string> task) {
    // GUIスレッド上で処理を行う。
    this.Invoke(new Action<Task<string>>(this.ContinuedProcBody), task);
}

ではCOBOLで書きます。 こういう場合以外なかなか使ってもらえないオブジェクト指向構文(2002年規格で導入)が炸裂します。 全体を載せると長くなるので、イベント処理関連の部分のみ掲載します。 クラス名の定義とかクラス定義の環境部にあるので、ここだけだと記述が完結しないけど、 まあ雰囲気を見てもらえれば。 ソース全体はGitHubに置いています。

一つおことわりを。 以下のソースでは、 メソッドの『ローカル変数』をWORKING-STORAGE SECTIONに書いています。 規格的にはここはLOCAL-STORAGE SECTIONであるべきですが、 NetCOBOLでは、歴史的な事情により、 メソッドの『ローカル変数』はWORKING-STORAGE SECTIONに書きます。

では。

       METHOD-ID. button_Click PRIVATE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WK-CONTINUED-PROC OBJECT REFERENCE DEL-ACTION-TASK.
       01 WK-TASK OBJECT REFERENCE CLASS-TASK-STRING.
       LINKAGE SECTION.
       01 sender OBJECT REFERENCE CLASS-OBJECT.
       01 e OBJECT REFERENCE CLASS-EVENTARGS.
       PROCEDURE DIVISION USING BY VALUE sender e.
      *    前準備
      *    複雑な型パラメータをもつ型によるメソッドオーバーロードの解決に問題があるので、
      *    ここではAction<Task<string>>ではなく、Action<Task>引数で
      *    Task.ContinueWith()を呼び出す。
           INVOKE DEL-ACTION-TASK "NEW" USING SELF N"CONTINUED-PROC" RETURNING WK-CONTINUED-PROC.
      
      *    ボタンを無効化する。
           SET PROP-ENABLED OF button TO B"0".
           TRY
               SET WK-TASK TO WK-DOWNLOADER::"DownloadText" (N"http://www.msftncsi.com/ncsi.txt")
               INVOKE WK-TASK "ContinueWith" USING BY VALUE WK-CONTINUED-PROC
           CATCH
               INVOKE SELF "FINALLY-PROC"
               RAISE
           END-TRY.
       END METHOD button_Click.
      
      *button_Clickで必ず行うべき後処理
       METHOD-ID. FINALLY-PROC PRIVATE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WK-BUTTON OBJECT REFERENCE CLASS-BUTTON. 
       PROCEDURE DIVISION.
      * ボタンを有効化する。
           SET WK-BUTTON TO PROP-BUTTON OF SELF.
           SET PROP-ENABLED OF WK-BUTTON TO B"1".
       END METHOD FINALLY-PROC.
      
      *ダウンロード終了後に行いたい処理の本体
       METHOD-ID. CONTINUED-PROC-BODY PRIVATE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WK-TASK OBJECT REFERENCE CLASS-TASK-STRING.
       01 WK-EXCEPTION OBJECT REFERENCE CLASS-EXCEPTION.
       01 WK-MESSAGE OBJECT REFERENCE CLASS-STRING.
       01 WK-TEXT OBJECT REFERENCE CLASS-STRING. 
       01 WK-NOW OBJECT REFERENCE CLASS-DATETIME.
       LINKAGE SECTION.
       01 PARAM-TASK OBJECT REFERENCE CLASS-TASK.
       PROCEDURE DIVISION USING BY VALUE PARAM-TASK.
      *    タスクをTask<string>型にキャストする。
      *    実際のタスクの型はTask<string>だが、インターフェイス上はTaskにしている。
      *    button_Clickメソッドの手続き部のコメントを参照。
           SET WK-TASK TO PARAM-TASK AS CLASS-TASK-STRING.
      
           TRY
      *      ラベルのテキストを更新する。
             SET WK-EXCEPTION TO PROP-EXCEPTION OF WK-TASK
             IF WK-EXCEPTION = NULL THEN
               SET WK-TEXT TO PROP-RESULT OF WK-TASK
               SET WK-NOW TO PROP-NOW OF CLASS-DATETIME
               SET WK-MESSAGE TO CLASS-STRING::"Format" ("[{0}] {1}" WK-NOW WK-TEXT)
             ELSE
               SET WK-MESSAGE TO PROP-MESSAGE OF WK-EXCEPTION
             END-IF
             SET PROP-TEXT OF label1 TO WK-MESSAGE
           FINALLY
      *      ボタンを有効化する。
             INVOKE SELF "FINALLY-PROC"
           END-TRY.
       END METHOD CONTINUED-PROC-BODY.
       
      *「ダウンロード終了後に行いたい処理」をGUIスレッド上で実行するメソッド
       METHOD-ID. CONTINUED-PROC PRIVATE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WK-PROC OBJECT REFERENCE DEL-ACTION-TASK.
       LINKAGE SECTION.
       01 PARAM-TASK OBJECT REFERENCE CLASS-TASK.
       PROCEDURE DIVISION USING BY VALUE PARAM-TASK.
      *    GUIスレッド上で処理を行う。
           INVOKE DEL-ACTION-TASK "NEW" USING SELF N"CONTINUED-PROC-BODY" RETURNING WK-PROC.
           INVOKE SELF "Invoke" USING WK-PROC PARAM-TASK.
       END METHOD CONTINUED-PROC.

C#のFormが106行(Form1.cs: 38行、Form1.Designer.cs: 68行)なのに対し、 COBOLのForm1.cobは1126行です。 いまどき行数で生産性を計っている方々、 お喜びください。 生産性10倍以上です。

まあ、COBOLのFormにはデザイナが自動生成する特殊コメント等が大量にありまして(しかも事情があってちょっと冗長)、 単純集計だと極端に行数が増えます。 なので、button_Click処理に限定しましょう。 それでも、C#: 16行に対し、COBOL: 83行です。 COBOLのスタイルだとどうしても記述量は増えます。

やはり、言語は適材適所に使っていただいて、 適切な言語で記述された今時のシステムから伝家のCOBOLプログラムを呼び出し、 末永く利用していただければと思います。

謝辞

古来、 COBOL仕様扱う文書はCODASYLへの謝辞を掲載していました。 謝辞を掲載することで、 COBOL仕様書の内容やアイデアを自由に利用することが許可されていました。 せっかくですので、 古式ゆかしく、 CODASYLへの謝辞で終わりたいと思います。 CODASYLはもうないけど。

以下、1984年版の謝辞(「CODASYL COBOL JOURNAL OF DEVELOPMENT 1984」から)。

【謝辞】

COBOLは産業界の言語であり、特定の団体や組織の所有物ではない。 CODASYL COBOL委員会又は仕様変更の提案者は、 このプログラミングシステムと言語の正確性や機能について、 いかなる保証も与えない。 さらに、それに関する責任も負わない。

次に示す著作権表示付きの資料の著作者及び著作権者は、 これら全体又は一部分をCOBOLの原仕様書中に利用することを許可した。 この許可は、COBOL原仕様書をプログラミングマニュアルや類似の刊行物に複製したり、 利用したりする場合にまで拡張される。

  • FLOW-MATIC(Sperry Rand Corporationの商標), Programming for Univac(R) Ⅰ and Ⅱ, Data Automation Systems, Sperry Rand Corporation 著作権表示1958年, 1959年
  • IBM Commercial Translator Form No.F28-8013, IBM 著作権表示1959年
  • FACT, DSI 27A5260-2760, Minneapolis-Honeywell 著作権表示1960年

今後ともよろしくお願い申し上げます。

2017年10月28日 (土)

Docker for Windowsをアップデート/再インストールできない件

今年の春の頃からだったろうか、 家のPCのDocker for Windowsがアップデートできなくなりました。

アップデートを開始すると、 「Do you want to replace your current version of Docker for Windows with this new one 17.09.0-ce-win33(13620)?」というダイアログが出ます。 ここで「はい」を押そうが「いいえ」を押そうが、 次の瞬間「install canceled」と出て先へ進めなくなります。

一回Docker for Windowsをアンインストールして、 最新バージョンのインストーラーで再インストールを試みても同じ結果。

そのうち直るだろうと思って放っていましたが、 一向に直らない。 で、まじめに調べてみました。

対処法

レジストリの以下のキーを削除してからアップデート/再インストールを行います。

HKCR\Installer\UpgradeCodes\9CA3F2E62DBFCA74DB9BD0384695C460

最後の"9CA3F2E62DBFCA74DB9BD0384695C460"の値は、 ひょっとすると環境によって異なるかもしれません。 アップグレードコードの役割からすると、同じ値の場合が多いと思いますが。 確実を期したければ、後述の詳細をみて、確認してください。

詳細

Dockerのコミュニティフォーラムの以下のトピックを参考にしました。

Cannot uninstall Docker for Windows

ここではアンインストール時の問題として取り上げられています。 このトピックは2016年1月に始まっていますが、 長らく進展していませんでした。 キーになるのは、一年半以上も後の投稿です。

2017年10月12日 3:06のdjarvis8さんの投稿

Process MonitorでDocker for Windowsのインストーラーをモニタし、 片っ端からチェックして"HKCR\Installer\UpgradeCodes"下のキーを読んでいるのが問題だと突き止めたらしい。 すげえ。

というわけで、 私もProcess Monitorで問題のレジストリキーを探して、 それを削除したところ、無事Docker for Windowsを再インストールできました。

問題のレジストリキーは同じだとは思いますが、 環境や現在インストールされているバージョンによっては異なる可能性があります。 確実を期すならばProcess Monitorでインストーラーが実際に読もうとしている"HKCR\Installer\UpgradeCodes"下のキーを確認するとよいでしょう。 結構めんどくさいけど。

2017年8月27日 (日)

IS12Tとわたくし

一昨日、auがこんなツイートを。

4年近く愛用してたよ。 ちょっと感慨深くて、何か書きたくなった。

ただ、まあ、IS12Tの発売がどんなに感無量であったかを書くには、 Windows Phoneの前史から語らねばならなくてですね…

Windows Phone 7まで

元々Microsoftは大昔からスマートフォンを作っていました。 それこそiPhoneが出るよりずっと前から。 当時「スマートフォン」と呼ばれていたものは電話回線につながるPDAみたいな感じだったけど。 日本でも2005年のW-ZERO3で知られるようになりました。 残念ながら住んでいる所が当時ウィルコムのサービスエリア外だったので、 私はW-ZERO3は買いませんでしたが、 その後、ソフトバンクから出たWindows Mobile(現行の"Windows 10 Mobile"ではなく、"Windows Mobile 6"ね)を使ってました。 X01TとかX02Tとか。

そんなこんなしているうちに2007年にiPhoneが出て(日本発売は2008年)、 「スマートフォン」のイメージを塗り替えてしまいました。 Microsoftも「これはいかん」ということで、 スマートフォンOSを刷新することになります。 確か、新しいやつは従来のWindows Mobileじゃなくて、 Zune(Microsoftのメディアプレーヤー)を元に作り直したんじゃなかったっけ。 あのタイルUI(メトロ)もZune起源だったような。 今や本家Windowsにもメトロの後継が入っていますね。

開発は順風満帆とはいかなかったようで、 Windows Mobile 6.5を繋ぎで出さざるを得なくなったり、 Kinという別系統のスマホを発売してたった2カ月でディスコンにするというわけの分からんサイドストーリーがあったり、 なんだかんだで、 2010年にやっとこさ"Windows Mobile 7"改め"Windows Phone 7"が登場しました。

が、今度はなかなか日本で発売されない。

技適の問題もありますが、 当時はまだSIMロック端末が一般的だったので、 キャリアがちゃんと対応機を出してくれないと国内で使い物にならないのです。

IS12T!

で、うーうー唸っているうちに、2011年7月27日、 突然auから「IS12Tを8月25日から発売する」との発表があり、 色めき立つのです。 しかも世界初のWindows Phone 7.5機です。 「Windows Mobileを現代風に作り直すやで」と聞いてからはや3年です。 まさかこの後、国内で次のWindows Phoneが出るのが4年後になるとは思わなかったけど。

開発は東芝ですけど、 直前に東芝と富士通のケータイ部門が事業統合したため、 富士通機種のような扱いになっていました。 でもロゴは"TOSHIBA"だったな。 発売直前に社内割引きで買えるとのアナウンスがあり、 速攻で予約しました。 色はシトロンを選びましたが、 シトロンは入荷待ちで発売当日には入手できないといわれた。 でも、発売翌日に入荷したとの連絡をうけ、 次の日、窓口のある武蔵小杉へ沼津から受け取りに行きました。 契約書を掘り出して確認しましたが、 ちょうど六年前、2011年8月27日でしたね。

感無量でしたねえ。 ぬるぬる動くし、 従来のWindows Mobileからずいぶん「現代的」になってたし。 カラーも気に入ったし。

当時、 スマホではまだあまりカラフルなモデルは出ていなかったように思います。 とくに海外では。 Lumiaが青や群青のWindows Phoneを出してなかなかカッコよかった記憶がありますが、 それでも青系で、 派手な色のスマホはIS12Tが先駆けのように思うけど、どうかな。 Lumiaが黄色とかを出したのはその後じゃなかったっけ。

ただ、機能は仕上がっていない部分もありました。 始めの頃は二三日ごとに再起動していたし、 冬まではSMSの受信はできても送信はできてなかったりして、 妻からのSMSにメールで返信するというはめになり、 iPhone使いの妻に「それは便利なのか?」と煽られたりしてました。 アップデートしているうちに色々直って安定してきましたが。

空白の4年間

というわけで、 機嫌よくIS12Tを使っていたわけですが、 これに続くWindows Phoneが国内でまったく出てこない。 「Microsoft側の都合」ということでしたが、 具体的な理由は公式に出たことはなかったんじゃないかな。 ストアなどの環境を日本向けに整備するのが追いついていないのではなかろうか、 とか言われていました。 この少し後にWindows Phoneの公式マップとして採用したNokiaのマップとか、 日本の領域はスカスカだったし。

一方、海外ではそれなりにWindows Phoneが出ていました。 Nokiaの力もあったのでしょう。 特に2012-13年頃はヨーロッパでわりとシェアがあったような。 イタリアとかiPhoneよりシェアが多かったはず。

IS12Tにはその後Windows Phone 7.8が配信されましたが、 それが最後。 ハードの世代的にWindows Phone 8にはできない。 主にNokiaがWindows Phone 8機を海外で出すのを横目で見ながら 再びうーうー唸る日々が続きました。

そして、ついに、2014年10月にWindows Phone 7.8のサポートも終了します。 でも、しばらく使い続けてたけど。

復活

2015年早春、マウスコンピューターとかFREETELとかがWindows Phone機の開発を表明します。 まあ、今までの経緯があるので「実物を手にするまで信じひんのやー」という思いでしたが。

ところが、6月、思ったより早くマウスからMADOSMA Q501が発売されました。 もちろん、すぐに入手しました。 またまた感無量です。 4年近くぶりですよ。 IS12Tと比べて、手に取った時あっけらかんと軽いので驚いた覚えがある。

この年、 Windows Phone OSもWindows 10ベースになり、 それに伴いブランドも"Windows 10 Mobile"に変わりました。 このMobile版のWindows 10のリリースに合わせて、 翌年にかけてWindows 10 Mobile機が国内でいくつか出ました。 11月には、Windows 10 Mobileの「日本最速提供」競争が発生していました。

  • 11/24: FREETEL Windows 10 Mobileスマホ「KATANA 01」を発表。
    • 11/25 受付開始
    • 11/30 発売(この時点で最速と思われた)
  • 11/26: ヤマダ電機 Windows 10 Mobileスマホ「Every Phone」を発表。
    • 11/28 発売(この時点で最速と思われた)
  • 11/27: マウスコンピュータ 既存のWindows Phoneスマホ「MADOSMA」へのWindows 10 Mobile搭載を発表。
    • 11/27 既存機の有償アップデート代行を開始。3000円。ダイレクトショップに持込んでアップデート可。
    • 12/04 Windows 10 Mobile搭載MADOSMA発売
    • 12月 既存機へのアップデート配信開始

結局、11/27に既存のMADOSMAをダイレクトショップに持ち込んでアップデートしてもらうと、 一般提供の公式版を「日本最速」で入手することができたようです。

まあともかく、日本では妙に盛り上がっていました。 逆に世界では失速ぎみでしたが。 このあたり、うまく波が噛み合わない。

で、現在

また微妙な空白期に入ってしまいました。 Microsoftはスマートフォンをあきらめていないようですが、 次の動きは2018年以降になりそうです。 Fall Creators UpdateのARM対応に合わせてなにか動きがあるんじゃないかと思っていましたが、 これは外れたようです。 また、どうやら現行の機種は「次のWindows 10 Mobile」にはアップデートできないっぽい。 あらあらという感じですが、 スマホはハードの制約が厳しかろうし。

まあ、またひたすら待つ局面です。 待つけど。 でも、Microsoftももうちょっとロードマップというか、どうするつもりなのか言った方がいいんじゃなかろうか。 おっちゃんは待つけど、パートナーは愛想つかさずに付き合ってくれるんだろうか心配。

再びIS12Tについて

結局、IS12Tは四年近く使い続けました。 その間に妻のiPhoneは3回ほど変わって、 回線もLTEになったりしましたが、 その激動の時代をあまり不満なく使っていたなあ。 スマホに関してはタイルUIが気に入っているし、 タイルのシトロンのカラースキームも好きだった。 さすがに最後の方は回線速度とか色々重かったけど。 電源はもう入れませんが、まだ手元に置いています。

というわけで、 IS12Tに感謝しつつ、 Windows 10 Mobileの存続を切に祈念しております。

2017年8月 9日 (水)

「認証プロキシ爆発しろ!」が自動構成スクリプトに対応しました

認証プロキシをなんとかするためのツールであるところの「認証プロキシ爆発しろ!」ですが、 プロキシ設定の自動構成スクリプトに対応しました。 自動構成スクリプト(.pacファイル)によって複数のプロキシを使い分けているような環境では、 「認証プロキシ爆発しろ!」は自動構成スクリプトの内容に応じた適切なプロキシに対して中継を行うようになりました。

今回のバージョンアップに伴って、設定の変更が必要になります。 以下、それも含めた説明など。

  • ユーザーへの影響
  • 従来の動きと問題点
  • 新しい動き
  • 設定変更の必要性
  • 問題など

ユーザーへの影響

現在「認証プロキシ爆発しろ!」をお使いの方のうち、 以下の条件に該当する方は設定変更の必要があります。

  • コントロールパネルの「インターネットオプション」-「接続」-「LANの設定」の「自動構成」 (Windows 10の「設定」で言えば「ネットワークとインターネット」-「プロキシ」の「自動プロキシセットアップ」)が 有効になっている環境下で「認証プロキシ爆発しろ!」をお使いの方。

と言っても、 ver 1.0.17.0以降のGUI版「認証プロキシ爆発しろ!」を起動すると、 変更の必要のある場合は「設定を推奨値にするか?」という画面が出ますので、 「はい」を押せばほとんどの場合大丈夫です。

設定変更の必要性の詳細を知りたい方は、 以下の説明をお読みください。

従来の動きと問題点

従来の「認証プロキシ爆発しろ!」において、 通信の中継先となるプロキシ(「実際のプロキシ」)はひとつだけでした。 通信の中継を開始する際に、 「実際のプロキシ」のアドレスを自動検出し、 そのアドレスに対して中継を行っていました。

一方、 多くの環境では自動構成スクリプト(.pacファイル)によるプロキシの自動構成が行われています。 この自動構成スクリプトでは、 通信元のアドレスや通信先のURLに応じて複数のプロキシを使い分けるということができます。 「認証プロキシ爆発しろ!」はこのような環境で複数存在する「実際のプロキシ」を使い分けて中継を行うことができませんでした。

というか、 私がこのツールをふだん使っている環境で、 近々複数のプロキシの使い分けが必須になりそうな状況でして、 そのために真面目に対応する気になったんですけれどもね。

新しい動き

PCのユーザー環境でプロキシ設定の自動検出や自動構成スクリプトが有効になっており、 かつ、 「認証プロキシ爆発しろ!」の「認証プロキシ」設定が「自動検出する」になっている場合、 「認証プロキシ爆発しろ!」は自動構成スクリプトが返す「実際のプロキシ」に対して中継を行うようになりました。

新旧比較

設定変更の必要性

変更が必要になる設定は、 「認証プロキシ爆発しろ!」の設定の「プロキシ」-「システム設定書換え」-「中継時の設定」にある以下の二つの項目です。

  • ローカルアドレスにはプロキシサーバーを使用しない
  • 次で始まるアドレスにはプロキシを使用しない

従来は「認証プロキシ爆発しろ!」を通す必要のないアドレスをここに指定していました。

今後、自動構成スクリプトが有効な環境においては、 いったんすべてのhttp通信は「認証プロキシ爆発しろ!」が中継し、 その内部で自動構成スクリプトの結果に応じて切り分けを行います。 その切り分けには「プロキシを通さない」という判断も含まれます。

なので、この場合、 上の「中継時の設定」は原則不要になります。 ぜんぶ「認証プロキシ爆発しろ!」を通せばよい。 まあ、全通信を中継するオーバーヘッドを考えると、 「プロキシを通さないことが確実なアドレス」は指定してもよいかもしれません。 「ローカルアドレスにはプロキシサーバーを使用しない」ぐらいが実用的ではないでしょうか。 ということで、新しい設定の推奨値は『「ローカルアドレスにはプロキシサーバーを使用しない」のみ有効』にしています。

問題など

「認証プロキシ爆発しろ!」による中継下で、 IEやChromeでは問題がないのに、 Edgeで「プロキシサーバーに接続できません」というエラーが出ることがあります。 現在気づいているケースとしては以下があります。

  • 新しいタブを開いた際の「新しいタブ」ページの「マイ フィード」の項
  • プロキシの内側にあるサイトのページ(外部ページは問題ない)

後者の正確な条件はよくわかりません。 ひょっとしたら、Active Directoryのドメインが関係しているのかも。

この問題の原因は分かりません。 このケースではそもそも「認証プロキシ爆発しろ!」に接続が来ていません。 Edgeが内部でプロキシの要不要をどう判定しているのかが謎。

あと、 ほとんどのhttp通信を「認証プロキシ爆発しろ!」に通すことになるので、 以前よりオーバーヘッドがかかるようになります。

現状、(httpsではない)普通のhttpではレスポンスを返す際にチャンク転送をサポートしていない(まとめて返している)ので、 体感的に遅く感じる場合があります。 これは以前からの問題なんだけど、今回の変更でより目立ちやすくなったかも。

そのうちなんとかしたい。

2017年5月14日 (日)

Windows 10 Mobileユーザーを一時的に増やした話

上の娘の機種変更時のつなぎにWindows 10 Mobileを使った話。 と、おまけで、Windows 10 Mobileをめぐる最近の状況についてちょっと思うところなど。

経緯など

うちには子供が三人います。 下の二人にはエントリーモデルのWindows 10 Mobileを持たせています。 このあたりの経緯は過去に書きました。

子供らの「つなぎ携帯」をWindows 10 Mobileにしてみた話

一方、 上の娘はiPhoneを使っています。 このiPhoneの契約が二年縛りの更新月を迎えました。 で、今になってみると、 うちの他の回線はすべてMVNOにしてしまったし、 こいつもMVNOにして通信料を節約したい。 ところが、都合の悪いことに、このiPhoneはSIMロック解除対応前のものです。

どうしたもんかと、色々費用をシミュレーションしたり娘と話し合ったりして、 「SIMフリーのiPhone SEに乗り換えよう」という結論に達しました。

AppleのiPhone下取りキャンペーン使って乗り換えるぞー。 なに?Apple Storeだとその場で下取分を割引するけど、 オンラインだとApple Storeギフトカードになる? ギフトカードなぞいらん、キャッシュよこせー。 よーし、ゴールデンウィーク中に一家で東京に行く機会があるから、 その時Apple Storeに押し掛けるぞー。 ということで、機種切り替えがゴールデンウィーク中にスケジュールされたのでした。

で、四月の終わり近くにキャリアにMNPの申し込み電話をしました。 例によって転出を思いとどまらせようとするような会話にテキトーに対応していたのですが、 一つ気になる指摘がありました。 予定では切り替えは5月上旬になるのですが、 となると、数日の利用のために5月分の基本料が丸ごと取られてしまうらしい。 「なので、切替えは月のなるべく遅くにした方が...」などとお勧めしてくれるのですが、 こちらは別のことを思いつくわけです。

ピコーン

回線は4月中に切り替え、 iPhone SEを入手するまではWindows 10 Mobileでつなごう。

娘に打診したところ、「一週間ぐらいなら」とOKが出ました。 妹と弟が使っていることもあり、多少の興味はあるようで、まんざらでもなさげ。

機種

機種はMADOSMA Q501を使います。 私がInsider Program入れて遊んでいるやつです。 ちょうど、Creators Updateに相当する10.0.15063.251が降ってきたところでした。 これに対して「電話のリセット」したところ、 都合よいことにOSバージョンは巻き戻らず、 ProductionなCreators Update機ができあがりました。 当時まだ国内のほとんどのProductionな電話にCreators Update降ってきてなかったのに。

MNPしたMVNOのnano SIMをmicro SIMアダプタかませてMADOSMA Q501に載せ、 娘のMicrosoftアカウントを指定し、 OutlookをiCloudのメールアカウントと接続。 あとは好きに設定せいや、 と渡したら、 次の朝にはあっさり実運用しとりました。 この時点でCreators UpdateのWindows 10 Mobile機使っている女子高生って、 日本に数人いるかどうかじゃないか?

というわけで、 わが家におけるWindows 10 Mobileシェアは80%に達しました。

我が家のスマホシェア

圧倒的ではないか、Windows 10 Mobileは。 こまるわー、寡占が進んでこまるわー。

あとは妻だけだけど、 妻は私がX01T時代にメール一本打つのに苦労してたの見てあきれてたからなあ。 今回も上の娘に「Windows Phoneにしたらメール打つのも苦労するで」とか言ってたし(もう今はあまりメール使っていないくせに)、 なかなか手ごわそう。

感想など

娘に一週間ほど使ってみた感想を聞きました。 良い点。

  • タイルのGUIはわかりやすい。
  • 一通りのことは問題なくできる。

悪い点。

  • アプリが少ない。今ゲームとかしてないからいいけど、ゲーム好きな人は困るんじゃないか?(まあねえ)
  • 一部アプリの動きがもっさりしている(まあ、元々そんなに高スペックでもないし)
  • カメラがあんまりきれいじゃない(これはW10Mというよりこの機種の弱い点だな)

その後

予定通り、一週間ぐらいでiPhone SEに移行しました。 家庭内シェアも元に戻ってしまった。

まあ、上の娘もWindows 10 Mobile使ってみてくれたから、よしとするのです。

ちなみに、四月中のMNP切り替えは失敗しました。 元iPhoneのバックアップ等に手間取って、 「当日中の切り替え締め切り」刻限に間に合わず、 5月1日切り替えになってしまった。 あかんやん。

(おまけ)最近のWindows 10 Mobileの話題について

Microsoftの最近の四半期決算にからんで、 「MicrosoftがPhoneビジネスを6月までに終わらせると言った」とか「証券取引委員会に提出した書類で投資項目からWindows Phoneが消えている」といった話が出ており、 またぞろ「Windows Phoneは終わった」みたいに言われています。

Microsoft’s 10Q SEC filing confirms investment in Windows Phone has ended (MSPoweruser)

ざっと見てみたけど、 記述対象となる期間からして、これらは多分Lumiaビジネスを畳んだことを指しているんじゃないかな。 実際、Microsoftの2017会計年度(2017年6月迄)を越えて作業予定があるように見える。 現状、秋のFall Creators Updateに向けてWindows 10 MobileのInsider Preview配信も進んでいるし、 つい最近もSurface Phoneの生存も確認されたし。

Nadella: “We’ll make more phones, but they will not look like phones that are there today.” (MSPoweruser)

今後、Mobileは"Windows 10"の一部分(おそらくはARM版の一部)として活動するんじゃないかな。 Intelがモバイル向けSoCやめちゃったから、 ARM版Windowsを是が非でも何とかしなければならなくなっているしねえ。

で、まあ、Surface Phoneは2017年中に出るのか、2018年になるのか分からないけど、 ハイエンドになるんだろうなあ、と思っています。 一方、あまり具体的な根拠はないんだけど、 Fall Creators Update世代では久々にサードベンダーからハードが出るんじゃないかという気がしています。 関係者のタイムラインとか眺めていると、 なにか動いているんじゃないかなあ、という気がしている。 もちろん、はっきり書いたりしていないんだけど。

なんにせよ、Windows 10ベースのスマホが存続してくれることを切に祈念いたしております。

«PCの時計が1時間進む問題が完全に解決した