2018年11月7日水曜日

VB6は永遠に・・・!?

熟年エンジニア向け、VB6のお仕事を頂戴しましたorz
これを機に.NETに移行してくれないかなあと思いつつも、せっかくなのでVB6Runtimeのサポートがいつまで続くのかを調べてみました。

https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-basic-6/visual-basic-6-support-policy

Windows10でのサポートは健在です。
Microsoftさすがです。
ではWindows10のサポートはいつまで続くのかというと・・・

https://support.microsoft.com/ja-jp/help/13853/windows-lifecycle-fact-sheet

エディションによって異なりますが、いまのところ最長はWindows 10 Enterprise 2016 LTSB エディション(企業向け固定化モデル)の2026年ということになります。
Windows 10 LTSBのリリースが今後もあるなら延長サポートの期限も伸びますので、
VB6RTのライフサイクルポリシーが変わらない限り当面サポートの終了はないということでファイナルアンサーでしょうか。

以下参考まで。
https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/12851976-congratulations-to-microsoft-for-extending-vb6-pro

2018年10月2日火曜日

さくらレンタルサーバーに Python3.6.6(pyenv) + Flask をインストール

bash したあと

[xxxx@www9999 ~]$ pyenv install 3.6.6
[xxxx@www9999 ~]$ pyenv local 3.6.6
[xxxx@www9999 ~]$ pyenv versions
  system
* 3.6.6 (set by /home/xxxx/.python-version) 
[xxxx@www9999 ~]$ which python3
/home/xxxx/.pyenv/shims/python3 
[xxxx@www9999 ~]$ git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
[xxxx@www9999 ~]$ wget https://files.pythonhosted.org/packages/4b/12/.../Flask-1.0.2.tar.gz
[xxxx@www9999 ~]$ tar zxf Flask-1.0.2.tar.gz
[xxxx@www9999 ~]$ cd Flask-1.0.2
[xxxx@www9999 ~/Flask-1.0.2]$ python3 setup.py build
[xxxx@www9999 ~/Flask-1.0.2]$ python3 setup.py install
[xxxx@www9999 ~]$ wget https://files.pythonhosted.org/packages/9f/08/.../Werkzeug-0.14.1.tar.gz
[xxxx@www9999 ~]$ tar xzf Werkzeug-0.14.1.tar.gz
[xxxx@www9999 ~]$ cd Werkzeug-0.14.1
[xxxx@www9999 ~/Werkzeug-0.14.1]$ python3 setup.py build
[xxxx@www9999 ~/Werkzeug-0.14.1]$ python3 setup.py install
[xxxx@www9999 ~]$ wget https://files.pythonhosted.org/packages/56/e6/.../Jinja2-2.10.tar.gz
[xxxx@www9999 ~]$ tar xzf Jinja2-2.10.tar.gz
[xxxx@www9999 ~/Jinja2-2.10]$ python3 setup.py build
[xxxx@www9999 ~/Jinja2-2.10]$ python3 setup.py install
[xxxx@www9999 ~]$ wget https://files.pythonhosted.org/packages/4d/de/.../MarkupSafe-1.0.tar.gz
[xxxx@www9999 ~]$ tar xzf MarkupSafe-1.0.tar.gz
[xxxx@www9999 ~]$ cd MarkupSafe-1.0
[xxxx@www9999 ~/MarkupSafe-1.0]$ python3 setup.py build
[xxxx@www9999 ~/MarkupSafe-1.0]$ python3 setup.py install
[xxxx@www9999 ~/MarkupSafe-1.0]$ python3
[xxxx@www9999 ~]$ wget https://files.pythonhosted.org/packages/f8/5c/.../Click-7.0.tar.gz
[xxxx@www9999 ~]$ tar xzf Click-7.0.tar.gz
[xxxx@www9999 ~]$ cd Click-7.0
[xxxx@www9999 ~/Click-7.0]$ python3 setup.py build
[xxxx@www9999 ~/Click-7.0]$ python3 setup.py install
[xxxx@www9999 ~]$ wget https://files.pythonhosted.org/packages/dc/b4/.../itsdangerous-0.24.tar.gz
[xxxx@www9999 ~]$ tar xzf itsdangerous-0.24.tar.gz
[xxxx@www9999 ~]$ cd itsdangerous-0.24
[xxxx@www9999 ~/itsdangerous-0.24]$ python3 setup.py build
[xxxx@www9999 ~/itsdangerous-0.24]$ python3 setup.py install
参照
 以下 PyPi

2017年10月26日木曜日

Keysight IO Libraries Suiteがインストール済みのPCで、viOpen関数のリターン値がbfff00a5になるとき

Keysight IO Libraries Suiteがインストール済みのPCで、VISA32.DLLのviOpen関数を実行してリターン値がbfff00a5になるときの設定です。

Keysight Connection Expertを開いて、Settings タブを選択します。


Options の Keysight 488 options の Enable Keysight GPIB Cards for 488 Programs にチェックして、Accept します。

もし Accept 後に、先のチェックボックスからチェックマークが消える場合で、PCにNI (National Instruments) 製品をインストールしている場合は、NI Configuration Manager というサービスが影響しています。

「Windows の検索」で「ローカル サービスの表示」を検索して実行し、サービスを停止後PCを再起動します。


ローカル サービス

「サービス」が起動したら、NI Configuration Manager を見つけてプロパティを開きます。

NI ConfigurationManager のプロパティ・ウィンドウ

いったん「無効」にセットしてPCを再起動し、Keysight Connection Expert の設定をやり直します。

2016年5月24日火曜日

IronPythonでIvi.Visa.Interop.IMessage.Closeをコールする

難儀したのでメモ
import sys
import clr
sys.path.append(r'C:\windows\assembly\GAC_32\Ivi.Visa.Interop\5.5.0.0__a128c98f1d7717c1')
clr.AddReferenceToFile('Ivi.Visa.Interop.dll')
from Ivi.Visa.Interop import *

visa_rm = ResourceManagerClass()
dev = FormattedIO488Class()

dev.IO = visa_rm.Open('GPIB0::5::INSTR')
dev.WriteString('*IDN?')
idn = dev.ReadString()
print(idn)

# 本題はこちら↓
imessage_close = clr.GetClrType(IMessage).GetMethod('Close')
imessage_close.Invoke(dev.IO, None)

NI Spyで確認した結果

2016年4月15日金曜日

Windows7 + VB6 で MSComctlLib を含むフォームのロードがコケる

大手電機メーカーのソフトウェアであっても製造の現場で安定して稼働しているシステムはいまだにVB6で作ったものだったりします。
今回もそんなVB6で構築したシステムのエンハンスで、.vbpファイルを開くとMSComctlLibを含むフォームのロードでエラーが出る状態だったため手っ取り早く対処します。

まずフォームをロードした時、VBがご丁寧に通知してくれるエラーログを確認します。

行 14: クラス MSComctlLib.Toolbar(コントロール Toolbar1) はロードされていません。
行 140: クラス MSComctlLib.ImageList(コントロール ImageList1) はロードされていません。
行 177: クラス MSComctlLib.StatusBar(コントロール StatusBar1) はロードされていません。

続いてcmd.exeを「管理者として実行...」して、以下の3行をコピー&ペーストです。
regsvr32 /u /s C:\Windows\System32\MSCOMCTL.OCX
regsvr32 /s C:\Windows\System32\MSCOMCTL.OCX
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe C:\Windows\system32\msdatsrc.tlb
あとはVB6 IDEのツールボックス上で右クリック⇒コンポーネントと進んで Microsoft Common Dialog Control 6.0 (SP6) をチェックして、 適用をクリックしてもエラーが出なければ・・・
 

2016年2月16日火曜日

プレゼンテーションは楽しむものか

私は仕事柄、依頼を受けたソフトウェアを「こんな風に実現します」ということを説明したり、立場上会社の説明を人前ですることが時々あります。本当に時々です。
でも私は全くもってこのスピーチとかプレゼンテーションが不得意科目で、少人数のまえでも熱い視線を感じると即座にアウアウアウアウアーとなってしまいます。
安定のド緊張チキンです。

そこでこのTEDを見て、スピーチとかプレゼンテーションの本質は何かを考えました。


正直な話、ウィル・スティーヴンは何を伝えたかったのかわかりません。
リスナーが彼の伝えようとしていたことを勝手に解釈すればいいのかもしれません。

個人的には人前で話すことを「楽しんでみたらどうよ?」って推奨しているかのように感じましたね。
こんなふうに自信をもって人前で話せるようになりたいす。

(完)

2016年2月5日金曜日

Arduinoはじめました(環境構築編)

「Arduinoはじめました」の第2回目、今回は開発環境の構築といきます。
まず前提ですが、こちらの環境はMacBook Pro、OSはYosemiteです。

では早速ソフトウェアを落としてきてインストールしましょう。
ソフトウェアのダウンロードは以下のリンク先から、Arduino謹製IDEです。
Windows、MAC、Linuxとあるので、自分がこれだと思ったものをダウンロードします。
https://www.arduino.cc/en/Main/Software

インストールは端折ります。

ではさっそくIDEを起動してみましょう。
素敵ですね、何の前触れも下準備もなく、しかもなんとなく何をしでかすのかわかるファンンクションネーム。
さあこれさえあればArduinoで実行するプログラムを作って、作成したプログラムをArduinoへ書き込んで、デバッグ用にログを表示するコンソールも準備完了。
環境構築\(^o^)/オワター
続いていちばん楽しみな、OSOYOO UNOとMacをUSBでつなぎますドキドキです。
およ、基盤の右側にあるグリーンのLEDが点灯してすんなり起動。
ちょっとは問題にぶち当たりたいかも。
嘘です。

さてここまできたら接続を確認します。
ArduinoのIDEをアクティブにして、メニューバーの[ツール]にマウスカーソルをあてて「マイコンボード」と「シリアルポート」になにやらデバイス感があればOKでしょう。
それでは今回の〆です。
OSOYOO UNOとMacをつないだときの写真、基盤中央よりちょっと左の上にあるオレンジのLED、その名も”L(える)”、こいつが点滅するプログラムを書いてボードに書き込んでみます。コードを書いて ➡︎ のアイコンをクリックするだけです。
void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
  delay(100);
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
  delay(1000);
}
ちょ、たのしぃ。。。

2016年1月23日土曜日

Arduinoはじめました (出会い)


冬ですが夏を感じさせるタイトルで失礼します。

去年のクリスマス、長男にサンタさんからプレゼントがありました。

↓こんなのです
  

黒いサンタは子供をハッカーにしようとしているのかもしれません。
長男がテキストを進むにつれ、父はLEDとコンタクトスイッチとブレッドボードとジャンパーワイヤが必要となることを知ります。
そして父は自分の体温が上昇しているのを知ります。
インターネットを徘徊し、お得感最強な一品を探しだしAmazonしました。

↓こんなのです

電子部品だけでも個別に買えばいいお値段しそうですが、Arduino互換ボード付きで¥3,780(当時)です。
私はプライムな人間なので、その日のうちにこの互換ボードと出会うことになります。



OSOYOO・・・ 
「おそよお」と読むのでしょうか、寝坊した時の挨拶のようです。

そしてこの日の夜、OSOYOO UNOはキット同梱のUSBケーブルで、自身のMacBook Proとめでたく結ばれることになります。

このキットの詳しい説明はコチラ

To be continued...

2015年11月30日月曜日

CoffeeScriptのススメ

CoffeeScript は、シンプルな記述でJavaScriptのコードを生成するための一種のコンパイラです。
これにより、冗長な記述や誤りが入り込みやすい部分を、よりシンプルに記述することが可能になります。
そのCoffeeScriptでクラスを記述してみたいと思いますが、その前にライブラリをインストールします。
ここでは、Node.jsを既にインストール済みであることを前提とします。

$ npm install -g coffee-script

グローバル・オプションでインストールしました。これでCoffeeScriptのインストールは完了です。
コンパイルのコマンドは以下のようになります。

$ coffee -c hoge.js.coffee

CoffeeScriptによって記述された hoge.js.coffee をコンパイルすることにより、hoge.js が生成されます。
この流れが基本です。

JavaScriptにはクラスという考え方が存在せず、prototypeというクラスに似た考え方を利用して、あたかもクラスを実装しているように見せかけていますが、CoffeeScriptでは、classキーワードを使用してクラス定義を記述できます。

# TVクラスを定義
class Television
  # チャンネルプロパティを定義します。
  ch: '7'

  # 引数としてnameを受け取り初期化をするコンストラクタを定義します。
  constructor: (@name) ->

  # メソッド watach を定義
  watach: ->
    alert "#{@name}で#{@ch}を視聴中 ..."
    return

# Usage;
tv = new Television 'television'
tv.watch()


var Television, tv;
Television = (function() {
  Television.prototype.ch = '7';

  function Television(name) {
    this.name = name;
  }
  Television.prototype.watch = function() {
    alert("" + this.name + "で、ch " + this.ch + "を視聴中 ...");
  };
  return Dog;
})();

tv = new Television('4Kテレビ');
tv.watch();

結果は ...
「4Kテレビで、ch 7を視聴中 ...」


CoffeeScriptの @は、thisとほぼ同じ意味でインスタンス・プロパティへの参照です。
また、()なども省略可能で、インデントにより表します。このあたりは、Rubyや、Python、または、Jadeに似た感覚です。

2015年11月14日土曜日

DockerでGUIアプリケーションを動かしてみる

高性能なIDEなどを構築するのはとても手間な作業だと思います。
この実験がひとつの発火点になれば、より合理的に仕事ができるようになるかもしれません。

まず、以下のような Dockerfile を用意します。

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y firefox
RUN export uid=1000 gid=1000 && \
    mkdir -p /home/developer && \
    echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
    echo "developer:x:${uid}:" >> /etc/group && \
    echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer && \
    chown ${uid}:${gid} -R /home/developer

USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox

そして、イメージを作成します。
ビルドにはしばらく時間がかかります。

$ docker build -t kenny/gui-docker .

次に run します。

$ docker run -ti --rm \
       -e DISPLAY=$DISPLAY \
       -v /tmp/.X11-unix:/tmp/.X11-unix \
       gui-docker

すると Firefox が起動します。























たったこれだけの実験なのですが、ひとつ可能性の地平が拡がりました。




2015年11月11日水曜日

Docker ver. 1.9 を発表

米Docker が現地時間(11月3日)にバージョン1.9を発表しました。
大きなポイントとして、マルチネットワーキングへの対応と永続的ストレージ関連の強化あたりでしょうか。

ひとつめは、コンテナの配備に関係なく仮想ネットワークと紐付けてコンテナの通信を完全に制御できるという点です。複数のホストにまたがって仮想ネットワークが構築できるようになります。
つまり、仮想ネットワークで抽象化され、どのホストでコンテナを実行するのか、という事実を隠蔽します。今回は安定板という位置づけなので本番環境での利用も可能です。

つづいて永続化ストレージに関して
1.9ではボリュームシステムが完全に再設計されたようです。データボリュームは複数コンテナで共有できるようになります。また、Swarmとの連携で、たとえばクラスタ全体での永続化を管理できるようになります。

その Docker Swarm ですが、今リリースから ver1.0 に到達し正式版になります。
コンテナで構成したクラスタのスケールが自動的に管理されるようになります。

オーケストレーションの Docker Compose は、ver. 1.5 になりました。
今回からWindowsのサポートも加わりました。
Swarm上でComposeのアプリケーションを複数のホストにまたがってデプロイすることが可能になります。

以上、Docker 1.9 のバージョンアップの要点をまとめました。

2015年11月9日月曜日

MongoDBをDokcerに隔離してマニュアル操作する

まずは、MongoDBのコンテナを作成します。

$ docker pull mongo

Latestは3.2です。
早いです。
11月5日に MongoDB Blog でアナウンスされたばかりです。3系の最新版ということになります。
軽く主な変更点に触れておこうと思います。

1)注目はストレージエンジンです。負荷状況に応じた最適化の選択肢の設定を行いやすくなった点です。これにより複数のストレージ稼働でのスケールがより柔軟になり運用の負担を軽減します。
2)ドキュメントバリデーションも強化されました。
3)インデックス作成時にフィルタをかけることによりメモリ容量を節約する。
4)BIコネクタ (BI Connector) が導入されました。

主なところをリストしてみました。
BIコネクタの導入は簡易なBI分析に向けて、ビッグデータ的な大がかりではないようなちょっとしたことがいろいろ可能になるような夢を感じますね。

では、pullしたmongoDBコンテナを起動します。

$ docker run --name mongo-sampler -d mongo:latest

さて、起動したら念のため ps で確認してみてください。
クライアントを起動してMongoDBを扱いたいわけですが、ホスト側のローカル環境にはMongoのコマンドは存在しません。
そのために、クライアントの役割を演じるコンテナをひとつ起動します。

$ docker run -it --link mongo-sampler:mongo --rm mongo sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/sample-db"'

MongoDBの操作が終わればクライアントのコンテナは必要なくなるので -rm でオプションを設定して、これからログインするコンテナを抜けると同時に終了するように設定します。
--link で既に起動してある MongoDB のコンテナに接続します。
sh -c でシェルスクリプト経由で、$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT のコマンドを実行します。内容は、Dockerで自動的に生成される環境変数でMongoDBのIPアドレスとポート番号を参照するようにします。
最後の sample-db は MongoDB に作成するデータベースです。

先のDockerコマンドを実行するとMongoDBのコンテナにログインするので、作成されたデータベースを使ってみます。

> use sample-db
switched to db sample-mongo

データを投入します。

> db.records.insert({_id:1,title:"MongoDBへテストレコードを投入する。",number:100})
WriteResult({ "nInserted" : 1 })
> db.record s.insert({_id:2,title:"続いてレコードをもう1件投入します。",number:101})
WriteResult({ "nInserted" : 1 })

検索します。

> db.record s.find()
{ "_id" : 1, "title" : "MongoDBへテストレコードを投入する。 ", "number" : 100 }
{ "_id" : 2, "title" : "続いてレコードをもう1件投入します。 ", "number" : 101 }

更新します。

> db.books.update({ _id:2 }, { $set : { title: "上書きします。" } })

確認します。

> db.record s.find()
{ "_id" : 1, "title" : "MongoDBへテストレコードを投入する。 ", "number" : 100 }
{ "_id" : 2, "title" : "上書きします。 ", "number" : 101 }

削除します。

> db.books.drop()
true
> db.record s.find()
>
> exit
bye

そしてプロセスを抜けたので、クライアントのコンテナは消滅しました。
NoSQLを実感してください。

2015年11月3日火曜日

Cloud9 で Rails を動作させてみる

ローカル環境でアプリケーションを構築して、gitにコミットしてクラウドにデプロイという流れとは別にクラウド上でアプリケーションを構築して、gitにpushしたり、任意のクラウドにデプロイという開発の流れもあります。
いちばんのメリットは個々の環境に開発環境を作らなくても済むという点です。
つまりブラウザさえあればモノが作れてしまうというわけです。

そういうわけで、今回は Cloud9 という開発用のクラウドサービスを試してみようと思います。

まずは、どんな機能を持っているのか? をまとめます。

1)開発に関連する環境がすでに揃っている(ruby, php, node.js, java C++ ...)
2)フレームワークもインストール済みなので、そのまま使用できる(Rails, httpd など)
3)Ubuntu環境なので、ターミナル操作をそのまま実行可能
4)データベースも用意されている(MySQL, Postgres, Redis, MongoDB など)
5)サンプルやデモとして簡単にアプリケーションをインターネットに公開できる
6)メンバーとのリアルタイム編集
7)エディタ環境は、Vim, Emacs, Sublime から好みのものを選択できる
8)Chrome, Firefox, safari など、クロスブラウザチェックが可能

次に、無料の範囲でどこまでスペックを活用できるのか? もついでにまとめます。

1)1GBのディスク容量
2)512Mのメモリ
3)ひとつまでのプライベート環境インスタンス

さて、Cloud9のアカウントを作成するか、GitHub、Bitbucketのアカウントがあれば、そのままログインできます。























ログインしたら、まずはワークスペースを作成しますが、Workspace name の入力欄に任意の名前をつけて入力します。この部分がのちほどURLのドメインの部分に付与されます。
Workspece Privacyは、公開したければ public で設定します。

今回は、Ruby on Rails のプラットホームでアプリケーションを構築してみようと思います。
プラットホームのアイコンから Ruby on Rails を選択して Createボタンを押して、しばらく待ちます。
すると IDEが起動します。
左のペインにワークスペースのディレクトリツリーが、右ペイン上部には選択したファイル、下部にターミナルが表示されています。Visual Studio や eclipse を使い慣れた方ならば直観的に操作できると思います。

まずは、左のペインのワークスペースのディレクトリツリーから Gemfile を開きます。
とくに今回は編集しませんが、gem 'sqlite3' という部分があります。データベースは、そのままsqlite3でいこうと思います。

さて、さっそくbashターミナルでコマンドを実行します。
右側のペイン下部です。

$ bundle update
$ bundle install

必要なgemパッケージをインストール完了しました。
つづいて、Scaffoldでテンプレートを作成します。

$ rails generate scaffold User name:string email:string
      invoke  active_record
      create    db/migrate/20151103062340_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    test_unit
      create      test/controllers/users_controller_test.rb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/users.coffee
      invoke    scss
      create      app/assets/stylesheets/users.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

そしてマイグレーションです。

$ bundle exec rake db:migrate
== 20151103062340 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0023s
== 20151103062340 CreateUsers: migrated (0.0025s) =============================

これで完了です。
実行の Run ボタンを押すと、クラウド上でアプリケーションが構築されます。データベースは c9 インスタンスが生成されます。
ブラウザで、https://ワークスペース名-ユーザ名.c9.io/users にアクセスすると、おなじみのRailsのチュートリアル画面を生成します。



















個々のPCに開発環境を作るのは、意外と大変です。
たとえば、vagrantなどで合理化しても、それなりに学習コストがかかりますが、今回の Cloud9 であれば、直観的にプラットホームを作成して、コーディングに専念できるという点がアドバンテージだと思います。
興味のある方は、ぜひ試してみてください。

2015年10月28日水曜日

続・コメント

自身が以前、ある開発者組織の研修を経験したときに、おもしろい経験をしたので参考までに紹介したいと思う。
それはコメントに関する指針についてのレクチャだった。まず、例題としてごく簡単なクラスをひとつだけ実装して、その内容に応じたコメントを記述したもらった。
対象はヘッダからはじまって、コンストラクタ、フィールド、パブリックアクセサ、パブリックメソッド、プライベートメソッド、プロクテッドメソッド、そして デストラクタ。
奇妙なことに判を押したようにそれらのコメント群の記述、粒度、文言は一致していた。そのときの生徒数はおよそ15名。この程度の人数だと思うかもしれないが、この統制のとれたコメントのノーテーションには、非常にびっくりした記憶がある。驚いたというのは、とても優秀な成績だったということではなく、この奇妙な統制についてだ。
ある意味、これだけの人数のチームで、これだけの統一感があるというのは、とても望ましいことだと思う。しかし、自身が思ったのはまったく違った。
実際的なコメントを読むと、自身の水準に照らし合わせれば、悪くはないが合格点はあげられない出来だった。

何が問題なのか?

一般的にコメントは適度な粒度が必要だ。シンプルに、かつ、必要にして充分な情報を提供できなくてはならない。もちろんこれは本質ではあるが、一朝一夕で記述できるほど甘くはない。
まず、考えなくてはならないのは、文脈に即した情報を網羅できているのか? つまり、構造のコンテキストに応じた言葉の選択や論理で貫かれているだろうか? というのが第1のポイント。
2つ目に、よく考えてほしいのは、果たしてこのコメントを読んで3週間後の自分は理解できるだろうか? 半年後の自分は理解できるだろうか? そして未だ見ぬ未来の実装者は、ここから必要な情報を得られるだろうか?
読めばわかる、という考え方は実は閉ざされた地平でしか通用しないある種の文明なのだ。共通基盤と一定水準の知識があってはじめて成立する、いわば方言、地方言語でしかない。
コメントはローカルであってはならない。参考までに、プロプライエタリ系の言語世界では、よくローカルな方言に陥りがちだ。もちろん、これは経験的に感じた傾向ではある。

翻ってオープンソースの世界はまた違った側面を持っている。誰に強制されるわけでもなく、コメント文化は成熟しているのが常だ。もちろんすべてのソースコードがそういうわけではないが、傾向としてグローバルな文化が根付ているように見える。これは、コメントという小さな視点だけではなく、実装やプロジェクトの運営方針に対して極めて規範的な空気感が常に流れているからではないだろうか? と思うことが多い。
自らを律する。この地平で初めて他人のための仕事も成熟を遂げるのではないかと考えている。

2015年10月26日月曜日

ダメなコメント

「予約情報をチェックする」

というコメントがあったとする。

メソッドを見ると

CheckResavationData() : bool

とある。
メソッド名を見れば予約の情報をチェックしているのだろう、という察しがつくし、その結果を論理型で返すのだろうな・・・

という見当もつく。
それで? 結局、このメソッドは何をするのか? そしてどんな結果を返すのか? は不明だ。

予約情報の有無を調べているのか?
または、妥当性をチェックしているのか?
依然として不明だ。何より文脈がわからないのでどのように扱えばよいのかという点で理解はできない。

問題は、メソッド名の直訳的な説明しかコメントからは読み取れない。それ以上の情報は得られないのだ。
このメソッドを含むクラスはブラックボックス化されていて中の実装は気にしないでよい、ということを示唆しているわけだが、これでは上位の呼び出し側からはどんな論理を記述すればよいのかわからない。
世の中にはこういうコメントやメソッドが溢れている。

これは英語圏の表現からはかなり遠い(何しろ Far East なわけだし・・・)ところに本拠を置く我々の致命的な弱点なのかもしれない。では、仮に日本語でメソッド名を付けましょう、という運動でも展開すれば、この手の問題は解決するのだろうか?

2015年10月21日水曜日

expressでHTMLを直接扱う

今回も Node.js における expressフレームワーク の小ネタを。
一般的には、あるいは、モダンにHTMLを構築してレスポンスを返すという点では、既にこのフレームワーク は充分に洗練された機能を持っていると思います。
それは、たとえば、JadeのHTMLコンバータだったり ejsのテンプレートエンジンだったりするわけです。 しかし、これらの機能を使いこなすには従来のHTMLに関するパラダイムシフトがある程度は必要なわけです 。
この部分の考え方は、モダンであると同時にシンプルでもあるし効率的でもあるとも思います。
ただ、このシフトがいまひとつピンと来ない人や、これらのテンプレートの表現になじめない人もいると思 います。
そこで、今回はHTMLを直接扱う方法の紹介です。
ちなみに、Jadeやejsとは何か? ということに少し説明を加えようと思います。

Jadeは、HTMLからタグを取り払いインデントの階層でドキュメントを表現し、その構造をJadeテンプレートに投入してHTMLに変換する機能です。
コードとしては以下のような雰囲気になります。

extends layout

block content
  h1= title
  p Welcome to #{title}

  h3 BootStrap3 Sampler
  ul
    li: a(href="./bootstrap-nav") ボタン・サンプル

リクエストで受け取ったパラメータから title という文字列を取り出して画面に表示します。加えて上記の例では Bootstrap3 を装飾として使用しています。
ejsは、もっとHTMLそのものに近く直感的にわかりやすいと思います。それは、たとえば NetFrameworkの ASP.NET MVC で採用されているスキャフォールディングや、Ruby on RailsのViewの構造に近いとも言えます。

さて、本題に戻ります。
目標はHTMLの表現でViewを作り、そのままレスポンスとして返す方針の解決法です。

package.json に ejs のモジュールを追加します。
"ejs": "latest"

続いて

$ npm install

これで ejsモジュールがプロジェクトに追加されます。

app.js に以下を記述します。

app.engine('htm', require('ejs').renderFile);
app.engine('html', require('ejs').renderFile);

後は、個別に js ファイルにRESTを作成します。例えば下記のようにです。

router.get('/', function (req, res) {
    res.render('index.html', { title: 'Express' });
});

ここで出現した index.html はHTMLのルールに基づいて作成したファイルです。
これで素のHTML構造を返すことが可能になります。

2015年10月16日金曜日

コンテナ・インジェクションのアンチパターン

以前 C#におけるインジェクションテクニックのうち、Bastard Injection の紹介をしましたが、今回は Late Binding の手法を使ってみようと思います。
2000年代半ばの Java のフィールドでは数多くのプラクティスが生み出されましたが、他ならないリフレクションの最も基本的な実装方法とも言えます。
Spring framework では、最も洗練されたDIコンテナ(依存性の注入)の運用が編みだれました。
その中心的な考え方は、実装とインスタンスの生成を完全に切り離してしまうものです。それを今回はC#で試してみようという寸法です。

まずは、プログラムのインタフェース規約を定義します。

namespace Sample.DISampler.Injection
{
    interface IMessageWriter
    {
        void Execute();
    }
}


続いて、規約に基づいた実装です。

namespace Sample.DISampler.Injection
{
    public class ConsoleMessageWriter : IMessageWriter
    {
        public void Execute()
        {
            Console.WriteLine("OK!");
        }
    }
}


さて、コンフィギュレーションでは、検索のkeyとなるキーワードに対して、valueにコンテナ実装をフルネームで記述します。

<appSettings>
    <add key="InjectMessage"
         value="Sample.DISampler.Injection.ConsoleMessageWriter"/>
</appSettings>

最後に呼び出し方法です。

var typeName = ConfigurationManager.AppSettings["InjectMessage"];
var type = Type.GetType(typeName, true);
IMessageWriter writer =
(IMessageWriter)Activator.CreateInstance(type);
writer.Execute();


つまり、設定ファイルに記述された文字列から対応するクラスをインスタンス化して実際に動かすという目論見です。
動くまでは、どんな型になるのかは決まりません。
クラスの依存を動的に解決するわけです。

2015年10月13日火曜日

Vagrantfile で仮想環境を生成しよう

先日、Vagrantを使いコマンドラインから仮想環境を生成する方法を紹介しましたが、今回は、Vagrantfileに仮想環境の作成手順書を記述することにより、仮想インスタンスを生成する方法を書いてみようと思います。
Vagrantfile というのは、作成したい仮想環境をテキストとして記述しておくことにより、生成状態が常に一定の結果が期待される、いわゆる Infrastructure as Code の中心的な考え方を実現する手法です。
当然、ターミナルを開いてコマンドラインで1ステップづつ実行する場合と同じ結果が得られることを目標とするわけですが、結果を得るまでの品質がまったく違います。
コマンドラインの実行は誤りを犯しやすいわけですが、コードとして実行手順を記述すると、結果は常に同じになるわけです。
加えて、最も大切なポイントとして、環境を構築するコードは、実際的な「手順書」になるわけです。ここは、ぜひとも押さえておいてください。

では、Vagrantfle をまず作成します。
そのまえに、VirtualBox と Vagrant が導入してある前提です。OSは何でもよいと思います。自分の環境で構いません。
任意のディレクトリで以下のコマンドを実行します。

> vagrant init

この結果、Vagrantfile が作成され、あらかじめ必要なひな形は既にできています。
そこで、内容を以下のように編集します。

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "centos65"
  config.vm.box_url = "https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box"

  config.vm.hostname = "vagranthost"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "public_network"

  config.vm.synced_folder "host", "/guest"
  config.vm.provision :shell, :inline => "echo hello world"
  config.vm.provision :shell, :path => "provision.sh"
  config.vm.provision "file", source: "test.html", destination: "/guest/test.html"
end

do ~ end までがひとつの括りです。
では、ひとつづつ見ていきます。

config.vm.box_url
ここには、仮想環境を生成するうえで基になるBoxの入手先のURLを記述します。
以前も書いたように Vagrantbox.es などから、使用するOSイメージの入手先をコピーするのが簡単です。
例では、CentOS 6.5 のイメージを使用します。
そして config.vm.box には、任意の名前をつけます。

つづいてネットワークの設定です。
ホスト名にしたい任意の文字列を設定します。ここでは”samplehost ”という名前にしています。
config.vm.hostname = "samplehost"

ポートのフォワード設定には、ホストOSとゲストOSのポートの転送を設定します。
たとえば、ゲストOSの80番ポートをホストOSの8080に転送する場合、次のように記述します。
この設定を行うと、ホストOSでlocalhost:8080にアクセスすると、ゲストOSの80番ポートにアクセスできます。
config.vm.network "forwarded_port", guest: 80, host: 8080

ゲストOSにプライベートネットワークを設定します。
この例の場合、ホストOSから192.168.33.10のプライベートアドレスで、ゲストOSにアクセスできます。
config.vm.network "private_network", ip: "192.168.33.10"

ゲストOSにパブリックネットワークを設定できます。
プライベートネットワークの設定と同じようにStatic IPを指定できますが、次の例のようにIPアドレスを指定しなかった場合は、ゲストOSにホストOSと同じネットワーク環境でDHCP用のIPアドレスが設定されます。
config.vm.network "public_network"

ホストとゲストでディレクトリを共有します。
通常、Vagrantfileを置いたディレクトリがゲストから見ると /vagrant になります。
下記の例では、Vagrantfileを配置したフォルダに”host”フォルダを作成しました。
次にVagrantfileに以下の設定を行います。これにより、ホストOSの”host”フォルダとゲストOSの” /guest”が共有されます。
config.vm.synced_folder "host", "/guest"

プロビジョニング設定では、仮想環境構築時にあらかじめ用意しておいたシェルスクリプトを実行したり、ファイルを配置したりできます。
また、Chefなどの他のプロビジョニングツールと連携して環境を構築できます。
下記の例はもっともシンプルなシェルスクリプトによるコマンド実行の例について説明します。
まず、Vagrantでシェルを実行するには、config.vm.provision :shellを設定します。
例では、シェルをinlineで実行し、コンソールに”hello world”を出力する例です。
config.vm.provision :shell, :inline => "echo hello world"

実行したいコマンドを別ファイルに書いて一括で実行することもできます。
次の例では、"provision.sh"というファイルに書かれたコマンドを実行するための設定です。
provision.shは、Vagrantfileを格納したのと同じ階層のディレクトリに配置します。
config.vm.provision :shell, :path => "provision.sh"

ちなみに、provision.sh の中には次のような記述をします。
sudo yum -y install httpd
sudo service httpd start
ln -fs /guest/ /var/www/html
そうです。apache httpdサーバをインストールして起動しています。

セットアップ時にあらかじめゲストOSに任意のファイルを配置することもできます。
次の例では、ホストOS上に用意したtest.htmlをゲストOS上の"/guest"フォルダに配置しています。
config.vm.provision "file", source: "test.html", destination: "/guest/test.html"

さて、では次のようなコマンドを入力してみてください。

> vagrant up

先日、ご紹介したコマンドと同じです。
ただし、今回は Vagrantfle を元に仮想環境を自動で構築して、さらにプロビジョニングまで実行します。その結果、Webサーバが起動して htmlファイルをホストするまでを確認できます。
確認してみてください。

2015年10月2日金曜日

Bower

今回は、HTML/JavaScriptのパッケージ管理ツールを紹介したいと思います。
ふだん、あまりこの分野に関わりのない方は、ちょうど Visual Studio での .NET系の開発に NuGetを活用したり、Rubyでいうところの RubyGems だと考えてもらえればイメージしやすいと思います。

そんなわけで、今回ターゲットにしたいのは Bower です。
Bowerは、HTML/JavaScriptを対象に、CSSなども含めて依存性を解決しつつ管理することができます。
ここで思うのは、同じ対象を管轄範囲とする npm とキャラクターが重なります。
確かにそうなのですが、きちんと住み分けができていますので、簡単に整理しておきます。

Bower: jQueryや、CSSなどフロントエンドに関わるものが中心
npm: サーバーサイドを軸に開発系のパッケージ管理なども含む

さて、早速 Bower を導入しようと思いますが、Node.jsとGitが必要です。
以下のコマンドでインストールしますが、グローバルオプションを指定します。

$ npm install -g bower

これでインストールは完了です。
任意のディレクトリに移動して、jQueryをダウンロードしてみます。

$ bower install jquery

バージョンを指定してダウンロードしたい場合は

$ bower install jquery#1.11.3

また、直接GitHubのURLを指定してダウンロードすることもできます。

$ bower install git://github.com/jquery/jquery.git

加えて、GitHubのユーザ/リポジトリを指定してもOKです。

$ bower install jquery/jquery

さらに、任意のURLを指定してダウンロードすることも可能です。

$ bower install http://xxxyyy.com/script.js


今度は Bootstrap を導入してみます。依存するjQueryも判断してダウンロードしてくれます。

$ bower install bootstrap


これらの結果は、bower.jsonに設定されます。
あるいは、bower.json に記述してから

$ bower init

でもOKです。
使い勝手は npm とほぼ同じです。

今度は逆のアプローチをとります。必要なパッケージをダウンロードして、bower.json にリストします。

$ bower install bootstrap --save

これも npm と同じコマンドオペレーションです。

では、最後に導入したパッケージをリストします。依存性がツリーの形式で表現されます。

$ bower list


このような管理系の問題は人手で解決するのは難しいものです。
ぜひとも、オートメーション化して、正しい手の抜きかたを実現したいものです。
さらに大きなメリットとして、このような解決が難しい問題の本質は、ドキュメントと実装が乖離していくという点で、そのような問題を防止できるということを指摘できます。
現代のシステム構築でこれをクリアするのははっきりいって困難だと思います。無駄な努力はさっさとあきらめて、jsonスキーマに管理をまかせてしまうのも一手だと思います。
つまり、源泉はただひとつ、という方針を貫くのです。jsonスキーマであれば、管理の属人性も排除できますし、いかようにも加工ができるという点で大きなアドバンテージになるのではないでしょうか。

2015年10月1日木曜日

Docker - 削除系のTips2題

Docker でいろいろ試行錯誤をしていると、さて。。となることがよくあります。
そんなときの軽いTips2題。

$ docker imgaes
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none>  <none>  c395172a74e5  8 hours ago  1.151 GB
<none>  <none>  05a17381460b  8 hours ago  1.151 GB
<none>  <none>  eb3ce0796961  8 hours ago

と、こんな状況に陥ることがまれにあります。
そんなときは、以下のコマンドで <none> のイメージをきれいに削除できます。

$ docker images | awk '/<none/{print $3}' | xargs docker rmi

では、すべてのイメージを一気に片付けたい場合は

$ docker images | awk '{print $3}' | xargs docker rmi

で、一気にきれいになくなります。
必ず使うコマンドなので、メモしておくとよいです。