2015年9月30日水曜日

最近のWebの潮流

さて、いまどきのフロントエンド開発は恐ろしいことになっていて、シーンから少し遠ざかっただけで、取り返すのが大変な状況に陥ってしまうことも少なくはない。
わかりやすい例でいえば、Webの要とも言っても過言ではないJavaScriptが実は、扱うのに大変な苦労を強いられる。細心の注意を払わないと、あるいは、ちょっと手を抜くとたちまちスパゲティコードになってしまうという致命傷的な特性を持っている。
これをいかに解決するか?という観点でさまざまなフレームワークなり、ツールなりが考えられて使われてきたわけだが、その中でもおもしろいのが、CoffeeScriptの立場だ。
これは言語ではなく、あくまでシンタックスシュガーという位置づけで、規定は実装者自身に委ねられる。

つまり、オブジェクト指向で書きなさいと。

当然ながら、JSではクラスの概念をサポートしているわけではないので、なんとか工夫をしながら書いてきた歴史がある。この部分を乗り越えたのが CoffeeScript の功績だとも言えるのかもしれない。

はっきりいって面倒なものです。

独自のシンタックス感で CoffeScript を記述し、gulpやGrantでコンパイルする。さらにCSSをSassから変換して、のちほど散らかったファイル群を統合する。
しかし、JSの世界にクラスの概念を持ち込み・・・ 正確に言うとJSで実装する部分にオブジェクトアプローチの世界観をもたらしたことのメリットは実は大きいのです。

そして、当然のように面倒な部分は自動化し、極力、人の手の介在を避け、設計にこそ頭を使おうとこんなところを目指すのです。

2015年9月29日火曜日

Dockerfile から Dockerコンテナを生成しよう

今回は、Dockerfileを記述して、Dockerコンテナを生成するプロセスを体験します。
目指すのは、Webサーバを起動して動作を確認する、です。

まず、任意のディレクトリに Dockerfile という名前のファイルを作成して、以下のような記述をします。

FROM ubuntu:14.04
MAINTAINER kenny <kenny@mail.com>
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/

FROM で コンテナを作るにあたりベースになる環境として、Ubuntu14.04を使います。
MAINTAINER は見てのとおり作成者です。
コンテナをビルドするときに、上から順番に命令が走るわけですが、RUN でコマンドを実行します。
上の例では、nginxをインストールしています。非対話モードで走らせなければならないため -y オプションを追加しておきます。
次の ADD コマンドで、/usr/share/nginx/html に index.html を配置します。

たったこれだけです。
もちろん、必要最小限のコードしか記述していませんが、基本はこんな感じです。
これだけで、index.html を表示するWebを起動することができるわけです。

さて、index.html の中は空なので、このままでは結果を確認できません。

$ echo 'Hello!' > index.html

これでOK!

では、コンテナをビルドしてイメージを作ります。
$ docker build -t kenny/nginx:0.5 .

名前は適当でも構いませんが、慣習として <username>/<imagename> のように付与するのが推奨されます。
-t オプションでタグをつけます。上の例では 0.5 です。
注意点をひとつ。
最後の .(ドット)は忘れやすいので、注意です。最後の引数は、Dockerfileの配置したパスを指定します。つまり、このコード例では、カレントディレクトリで作業していることになります。

結果をリストします。
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
kenny/nginx 0.5  f5468aac82bb  18 seconds ago  206.9 MB
ubuntu 14.04  91e54dfb1179  5 weeks ago  188.4 MB

ここまできたらあとは起動してコンテナを生成します。
docker run -d -p 80:80 --name nginx1 kenny/nginx:0.5 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
18c2ceb92246540662d390550334b0c1f75e4437aa7fd66766ca2ffec25c6f8e

--name で nginx1 という名前をつけて、-d でバックグランドで動作します。
-p で80番ポートを常時リッスンして、ホスト側で80番でアクセスできます。

ためしに、curlコマンドで確認してみます。
$ curl localhost:80
Hello!

想定したとおり Hello! が得られました。
ブラウザで localhost:80 でアクセスしても、当然、同じ結果が得られます。

2015年9月28日月曜日

nodebrew で Node.js を管理する

先日は、Node.js を nvm で管理する方法を書きましたが、今回は、nodebrew を使ってみます。
特徴はこんな感じです。

1)perl で作られているため、Macなどに入っている可能性が高い
2)curl や wget で入れるため、git が入ってなくても構わない
3)パスを指定すれば、nodebrewコマンドが実行可能(.bashrc .zshrc に記述)
  つまり、sudo 指定がいらない
4)ls-remote、clean など、機能はひととおり網羅

こんなところです。
では、インストールいきます。

$ wget git.io/nodebrew

$ perl nodebrew setup
fetching nodebrew...
install nodebrew in $HOME/.nodebrew

========================================
Add path:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================

こんな指示が出ると思うので、従う。

$ vi ~/.bashrc
で、オープンする。
vim のタイプが苦手だ! という方は
$ sudo gedit ~/.basrc
これで、WondowsライクにGUIエディタでOKです。

で、指示にあるとおり、下記の行を追加します。

export PATH=$HOME/.nodebrew/current/bin:$PATH

追加したら、設定ファイルをリロードします。

$ source .bashrc

この状態で nodebrew コマンドを実行すると

$ nodebrew
nodebrew 0.9.0

Usage:
    nodebrew help                         Show this message
    nodebrew install <version>            Download and install a <version> (compile from source)
    nodebrew install-binary <version>     Download and install a <version> (binary file)
    nodebrew uninstall <version>          Uninstall a version
    nodebrew use <version>                Use <version>
    nodebrew list                         List installed versions
    nodebrew ls                           Alias for `list`
    nodebrew ls-remote                    List remote versions
    nodebrew ls-all                       List remote and installed versions
    nodebrew alias <key> <version>        Set alias to version
    nodebrew unalias <key>                Remove alias
    nodebrew clean <version> | all        Remove source file
    nodebrew selfupdate                   Update nodebrew
    nodebrew migrate-package <version>    Install global NPM packages contained in <version> to current version
    nodebrew exec <version> -- <command>  Execute <command> specified <version>

Example:
    # install from binary
    nodebrew install-binary v0.10.22

    # use a specific version number
    nodebrew use v0.10.22

    # io.js
    nodebrew install-binary io@v1.0.0
    nodebrew use io@v1.0.0

これで、あとは察しがつくと思いますが…
利用可能な Node.js と io.js のバージョンをリストする
$ nodebrew ls-remote

使用する Node.js をインストールしてやる
$ nodebrew install-binary v0.11.13
もちろん、npm もいっしょに入ります。

使用する Node.js を確定する。これを忘れないように。
$ nodebrew use v0.11.13
use v0.11.13

最後に確認します。
$ node -v
v0.11.13
$ npm -v
1.4.9

いかがでしたか?
とても簡単です。そしてわかりやすいと思います。

2015年9月25日金曜日

Vagrantで仮想環境構築の自動化を目指す

今回は仮想環境を自動で構築する方法を試してみます。
あらかじめ VirtualBox がインストールされていることが前提になります。
なに? 自動構築と思えば、なんだそういうことか・・・ と言わずに、これには多大なメリットが得られます。
たとえば、何名かのメンバーでチーム開発を始めることを想像してみてください。それぞれのホストOSはバラバラなので、仮想環境を構築して開発環境を揃えるという方針をとります。
しかし、各々が、バラバラに開発環境を構築した場合のデメリットはあまりにも大きすぎます。非常にシビアな開発プラットホームをメンバー全員が共有できるでしょうか? とても難しい問題です。
今回は、その問題を簡単に、そして、シンプルに解決するソリューションのご紹介です。

では、VirtualBox がインストールされていない方は、早速導入します。
次に、今回の軸となるツール Vagrant をインストールします。
これは、各々の環境に応じたものをダウンロードすればよいでしょう。

インストール自体はとても簡単です。
終了したら次のコマンドでインストール結果を確認します。

$ vagrant -v
Vagrant 1.7.4

では、開発環境の構築をするための手続きを実施します。
まずは Box と呼ばれるものを追加します。Boxとは、仮想環境を構築するにあたりベースになるテンプレートと考えてよいと思います。
このテンプレートに対してさまざまなパッケージを導入するなりして、仮想環境を整備します。このベースになる部分はたとえば、
Vagrantbox.es などのようなサイトに集積されてるので、はじめはそれを利用するのがベストな選択だと言えるでしょう。
Boxを追加するコマンドは以下のとおりです。

$ vagrant box add [name] [url]

[name] はこれから作成する仮想環境の名前を付与します。どんな名前をつけても構いません。
[url] の部分には、テンプレートとなるboxイメージをダウンロードするURLを指定します。
たとえば、以下のようになります。

$ vagrant box add centos_6_3_32bit http://tom.davidson.me.uk/dev/vagrant/centos63-32.box

コマンドを実行します。

http://tom.davidson.me.uk/dev/vagrant/centos63-32.box
Downloading box from vagrant box add centOS63_32 http://tom.davidson.me.uk/dev/vagrant/centos63-32.box
Extracting box...ate: 642k/s, Estimated time remaining: --:--:--)
Successfully added box 'centOS63_32' with provider 'virtualbox'!

Successfully added box・・・ と表示されたら完了です。
では、結果をリストしてみます。

$ vagrant box list
centos_6_3_32bit (virtualbox)

次にたったいまダウンロードしたテンプレートを元に初期化します。
適当なディレクトリを作成して、その場所をカレントとします。

cd C:\Users\username\Cent_OS_6_3_32

では、さきほどのBoxを名前を指定して初期化します。

$ vagrant init centos_6_3_32bit

初期化が完了したら、SSHでアクセスできるように設定ファイルを書き換えます。
カレントディレクトリに Vagrantfile が生成されているはずなので、config.vm.network セクションを変更します。
IPアドレスの部分のコメントアウトを外します。

# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network :private_network, ip: "192.168.33.10"

これで、192.168.33.10 が仮想マシンに割り当てられました。
これで起動できる状態になったので、起動します。

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.3.16
    default: VirtualBox Version: 5.0
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/username/Cent_OS_6_3_32
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

起動しました。
終わりから3行目に共有フォルダの設定が表示されていますが、この内容はVirtualBoxからでも参照できます。

仮想マシンへの接続は TeraTerm などを使ってSSH接続します。Windows以外であれば vagrant ssh というコマンドを使えます。
SSH接続は

ホスト: 192.168.33.10
ポート: 22
ユーザ: vagrant
パスフレーズ: vagrant

でログインします。

さて、ベースになる仮想マシンができあがったので、あとは開発に必要なパッケージを適宜導入して、メンバ間でこの仮想環境をシェアすれば、環境の差異という問題を解決することが可能になります。
もうひとつ、大きなメリットは仮想環境をひとつ作成すれば、ほかのメンバーに共有することにより、それぞれが環境を構築するという煩わしさから開放されます。

ぜひ、試してみてください。

2015年9月24日木曜日

nvmでインストールされたNode.jsを管理する

nvm を使用すると、複数の Node.js を管理できるようになります。
ちょうど Ruby における RVM と同じ思想ですね。強い影響下にあることがわかります。

では、早速 nvm をインストールしますが、ソースパッケージをビルドするにあたり必要なパッケージを前もってインストールしておき ます。

$ sudo apt-get update
$ sudo apt-get install build-essential libssl-dev

次に GitHub からインストールスクリプトを取得して実行します。
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.26.1/install.sh | bash

profleのいずれかが更新されるので、ターミナルを開きなおします。
これで、nvmコマンドを発行することができるようになりました。
次のコマンドで、インストールが可能なNodeを確認することができます。

$ nvm ls-remote

上記のコマンドの結果、導出されたリストから適宜、選択したNodeをインストールします。
最新のv4.1.1をインストールします。

$ nvm install 4.1.1

~/.nvm 配下に指定したバージョンのNodeがインストールされます。
同時に、npmもインストールされます。

インストールされたバージョンのNodeを明示的に指定しなければなりません。
$ nvm use 4.1.1

結果を確認します。
$ node -v
v4.1.1
$ npm -v
2.14.4

管理下にあるバージョンをリストするには次のコマンドを実行します。

$ nvm ls

デフォルトで使用するバージョンを指定します。

$ nvm alias default x.x.x
default -> x.x.x (-> vx.x.x)

また、現在選択されているバージョンを明示的に設定するには、次のコマンドを実行します。

$ nvm use default Now using node vx.x.x (npm vx.x.x)

これで、適宜必要なNode.jsのバージョンを指定できるようになりました。

2015年9月19日土曜日

DockerでWordPressを起動してみる

ubuntu に Docker をインストールしてある前提で話を進めます。
Dockerイメージではなく、Dockerfileを使ってビルドする方法をとってみます。

$ docker build --rm -t (name)/wordpress git://github.com/jbfink/docker-wordpress.git

(name)の部分は適当な名前を付与して構いません。
これを実行することにより必要なイメージをダウンロードしてビルドします。

次に、以下のコマンドを実行します。
$ docker run --name wordpress1 -d -p 8080:80 -p 2022:22 (name)/wordpress

(name)は適当に付与した名前です。たとえば、sample という名前をつけたなら、sample/wordpress というDockerイメージができあがるわけです。
そして、wordpress1という名前をコンテナに付与しています。
加えて、80番(HTTP)と、22番(SSH)のポートをホストの 8080番に、2022番に、それぞれルーティングするように設定します。

これで完了です。
では、http://localhost:8080/ にアクセスしてみてください。



WordPress のインストール画面が表示されます。
簡単ですね。

では、WordPressをインストールしちゃいます。


サクッと完了です。

では、Dockerコンテナを終了してみます。
$ docker stop wordpress

これで、さきほどのURLにアクセスしてみてください。画面は表示できないはずです。
もう一度、再開するには
$ docker start wordpress

さて、ここからがポイントです。
コンテナは終了すると破棄されます。つまり、インスタンスを失い次に起動したときは新しいインスタンスで立ち上がります。
したがって、コンテナの中で設定された内容は永続化されません。
それでは困ってしまうので、現在の状況を別のコンテナとして記録します。

$ docker ps -a

上記のコマンドで現在のコンテナプロセス(起動しているもの、停止しているものも共に)がリストされます。その中から、さきほど停止したコンテナのIDに注目します。
そのうえで、以下のコマンドを実行します。

$ docker commit (CONTAINER ID) wordpress2:test

これで、さきほどのWordPressコンテナをコミットしました。
その上で、コンテナのイメージをリストします。

$ docker images

REPOSITPRYが wordpress2、TAGが test というイメージがリストされたでしょうか。
これで、さきほど停止、または 中断したときの状態からコンテナを起動することができるようになります。

2015年9月18日金曜日

スコープに注意しよう

スコープとは見える範囲を規定する表現だ。
スコープとは見えてはいけない領域を明確にする思想だ。

オブジェクト指向におけるスコープの規定はだいたい前者の理解が主流だと思う。
おそらく世の中に出回っている参考書やガイドブックの類はほとんどが前述のような説明をしていると思う。
もちろん間違ってはいない。 ただし、充分か? と言えば、必ずしも充分ではないように思われる。 スコープ定義のひとつの目的として不具合の囲い込みがあげられる。適切に見える範囲をコントロールすることにより、不用意に値を参照したり書き換えてしまったりしないようにすることだ。
アクセス可能な範囲を適切に縮小して狭めてやることで動作のメカニズムは安全なものとなる。正確にいうと、動作のしくみ自体が安全なのではなく、実装や検討をするにあたり考えなければならない範囲を少なくしている。つまり、ひとの頭の中の思考をなるべくシンプルにして、その結果、誤りを減らそうとする努力の表れだ。
この思考そのものは、見えるもの を制御することに軸がおかれるため、見える範囲から見えない範囲の方向に進みがちだ。したがって、観察対象の本質を見誤れば見える範囲として認識される可能性がある。
この誤りの方向は必ず見える範囲で起こる。
すなわち、ここで不用意にデータを書き換えてしまう危険性が生まれるわけだ。
実は、このスタイルの不具合というのが最も多いように思われる。と同時に、人々の仕事の最も苦しい部分を助長する要因でもあるように思われる。
見える範囲でモデリングをしている限りは必ず起こり得る問題だ。そして、この問題の本質はスコープ制御ではなく、観察対象の分類、整理に突き当たる。

では、逆のアプローチをとることが可能なのか?
可能であればその有用性は? ということについて考えてみたい。

今度は見えてはいけない範囲の考察が軸になる。
観察対象は、はじめは種々雑多なデータやコンテキストが散りばめられた状態だと思う。
ここから不要なものを取り除いてゆくわけだが、一気に分解して整理してゆくのは難しい。徐々に問題を解体しつつ段階を踏む必要がある。当然、このときに意識するスコープに不要なのか? 必要なのか? という観点で分析が進むはずだが、もうひとつ特殊な性格をもった観察対象の発見があるに違いない。
それは、ほかのスコープでも使用することが予想されるものの発見だ。
実はこの部分がキーポイントになる。さきほどあげたスコープの内側から、いわゆる共通データや共通コンテキストを、考察の対象としてスコープ内でどのように定義するべきか? という問題に答えを出すのは非常に難しい。
分類、整理におけるねじれ現象にあたるこの問題を正確に捉えるには、対象スコープの外側からしか、その合理性を考察できない。
このねじれ現象をスコープの内側からの解決手段を定義しようとすると、後程、ほかのスコープから考察した場合のことを想定するのは難しいし、また、ほかの機会に、現在のスコープの共通項目を正確に捉えるのは困難だ。

ここまでで新たな発見があったと思うが、観察対象のスコープの外側から考察した場合、たったいま考えた、ほかのスコープとの共通項目が存在した場合、あるいは、見つけた場合は、それ自体が独立したスコープを形成し得ることをここで確認しておきたい。

2015年9月16日水曜日

Node.js 4.0.0 へ

Node.js の開発チームは最新の安定版となる Node v4.0.0 をリリースしました。

主な変更点としては

・非同期のコールバックパラメータを扱えるchild_processの追加
・拡張モジュールのビルドツールnode-gypおよびパッケージ管理ツールnpmのアップデート
・timerのパフォーマンス向上 など。

なお、Node は LTSと定期サイクルのリリースを進めているが、最初の LTS を10月にリリースする模様。

2015年9月15日火曜日

Go kit

世の中のサービスが、マイクロサービスのベストプラクティスの標準化を画策する中、おもしろいムーブメントが起きるのではないか? という予感がします。

Goと「Go kit」によるマイクロサービス構築


このインタビュー記事の中で、組織の中での作業の標準化というキーワードが何度となく飛び出してきます。
これはまさに重要なことを示唆しています。
問題なのは、アーキテクチャの中にあるのではなく実装の標準化に達していない文化なのだと思います。

2015年9月14日月曜日

命名法

思いの外悩むものが、名前の付け方だ。
変数から始まってメソッド、関数、クラス、名前空間、プロジェクト名称…
名前を付けるべきものはたくさんある。
命名とはパッケージなのだ。命名に関して思い悩む、あるいは、なかなかつけられないのは想像力が欠如しているわけではない。
分析が足りないだけだ。もしくは、名前をつけるには不適当な粒度と内容を持っているかもしれないことを検討する余地が残っているだけかもしれない。
一意の名前をつけられない原因は、対象となる変数なりクラスが、いったいどういう役割を持っているのか?という点でしっかりと確定されていないだけかもしれない。

そこで帰納法を試してみよう。
帰納法とは、特化したものから観察結果を取り出し一般的なものを導き出す手法だ。
つまり概念化して、形態や方向性など、モデルとしての本質を探る。まず、この段階で余計なファクタが取り除かれ重要なポイントだけが残ると思う。ここまでは確認段階だ。いわゆるインタフェースの抽出に似ている。

次にまったく逆のアプローチをとる。
演繹法により前提条件から結論を導き出す。ちょうど数学の公理から系統を導き出すようなイメージだ。ここでは、一般から特殊へと逆の流れをとる。
ここで、概念モデルから特殊化されたモデルが形成され、その対象を表す、もしくは、要約するべき名前が見つかれば幸いだ。
もし、この時点で要約すべき表現が見つからなければ、対象が明らかに役割過多かもしれない。

と、理屈ばかり書いたように思えるが、これは私たちがふだん行ったり来たりしているモデリング手法そのものだ。

2015年9月10日木曜日

AIによる作曲は果たして可能なのか?

この記事によると、Hello World というタイトルが付けられた実験音楽ではあるが、拍子は4/4拍子。
ただし、冒頭からピアノが4拍3連の連符を弾き、トップのバイオリンが3拍に感じられるであろうゆるやかなパッセージを奏でる。と思ったら、クラリネットがこのコンビネーションの中で旋律を前に引っ張っていくようなリズムをギミックのように表現している。なおかつ、このクラリネットのカウンターパートにバイオリンのトップノートは1小節目の最終拍で減5度で音をぶつけている。そうぶつけているのだ。
これは聞く人によっては強烈な不協感とインパクトを与えるだろう。加えてリズムのギミックはポリリズムの展開を見せ、果たしてこの音楽はどういうビート感を伴っているのか? とまどうに違いない。唯一、聞き分けが容易なのがピアノの3連符の強烈なインパクトだ。

これは、いわゆるアルゴリズムにより作られた音楽だそうだ。
作られたというより、ほぼインプロビゼーションの雰囲気に近いもののようにも思える。 音楽は、基本的に数学であり時間芸術だ。つまり、時間と周波数の高さを数理的に定義してはじめて成り立つものだ。このあたりが絵画や文学とは違った性質を持つ。そういう意味では、音楽は次元の設計に他ならず論理には極めてマッチする。
この試みは決して目新しいものではなく、かつて、ピエール・ブーレーズの音楽や、もしかしたらジョン・ケージも、そして、あのイゴール・ストラビンスキーの「春の祭典」で対数の分析から導き出された音楽たちで、その効果を追体験することが可能である。
そして、件の記事を追っていくと生活の音楽を提案している。これはまぎれもないエリック・サティの環境音楽の思想そのものだろう。 おもしろいことに音楽は一定の周期で、まるで波のように解釈や焼きなおしというムーブメントが必ず起こるが、このようなアルゴリズムが自立して紡ぎだす音楽が、今後のトレンドになるのかもしれない。

果たして、このアルゴリズムの音楽はどのような展開を見せるのか?

2015年9月9日水曜日

Prototype宣言

オブジェクトというものを考えてみます。

とはいっても、所謂オブジェクト指向言語のオブジェクトではなく、プロトタイプベースのオブジェクトを考えてみます。
その前に従来のオブジェクト指向言語のオブジェクトを簡単に振り返ってみます。
まず、システムやソフトウェアはあるシナリオによって動作します。このシナリオをできるだけ細かく分解して汎用的な部分を共通化して合理的な実装に備えます。
しかし、これではまだ不充分で、特性や性質、あるいは、本質的に何を表現するのか? という観点でさらに分解されます。
つまり、ある事象の根本的な動作の表現、それを色づけるための特性や性質に分解されることに結実するのがオブジェクトに対するアプローチだと思います。
たとえば、前者がコンテキストだったり、後者がデータだったりします。
合理的な単位で分解されたものがオブジェクトになり得る候補になります。私たちがやることは、その分析結果をクラスという概念でモデル化して、電気信号に変えられインスタンスに変化します。 これがオブジェクトです。
ここで注意したいのは、このオブジェクトは既に特性や性質を兼ね備えているということです。それらはメンバという形で自然に存在します。
なぜなら、オブジェクトとして実体になるクラスがそのように定義されているからです。

さて、ECMAScriptの世界はどうでしょうか?
プロトタイプベースのオブジェクトは、実はそのように考えません。
オブジェクト自身は別のオブジェクトを追加することにより、新たな性質が加わります。
これがプロトタイプの考え方です。
では、そのプロトタイプベースの考え方に則りオブジェクトを生成してみます。

function Object() {}
var onj = new Object();

上のオブジェクト定義では retun がありませんが、下のステートメントで new されたときにオブジェクトインスタンスが得られます。

さらに初期化してみます。

function Object() {
    this.param = “done.”;
}
var obj = new Object();
Console.log( obj.param );
>Done. と表示されます。

今度は、このようなコードを書いてみます。
function Object() {}
Object.prototype.param = function() {
    console.log('Done.');
};
var obj = new Object ();
obj .param(); // Done. と表示される。

これでは、どうでしょう。
function Object () {
    this.param = function() {
        console.log('Done.');
   };
}
var obj = new Object ();
obj .param(); // Done.

ほぼ、同じです。
しかも同じように動作します。
しかし、大きな違いがあることがわかると思います。
後者のコードでは毎回インスタンス化されてしまうという違いがあります。 すべてのオブジェクトは prototype オブジェクトの参照を持っています。 この prototype オブジェクトに新たな特性や性質を付与することにより、細かなニュアンスの違いを表すことができます。
オブジェクト指向言語の継承に近い雰囲気を持っているように見えますが、性質が違います。
prototype に特性や性質を加えて、かつ、削除することも可能です。

ここでポイントです。
new により生成されたオブジェクトは、Object の prototype と同じ参照を持っています。
これによりオブジェクトは合理化されるわけです。

2015年9月8日火曜日

ASP.NETの吐き出すマークアップの矯正

知っている人も多いと思いますが、ASP.NET Web Forms の出力するHTMLコードがいかんともしがたい。
CheckBoxやRadioButtonListなどで顕著。
つまり、素直なHTMLツリーが出力されないのだ。

たとえば、以下のマークアップは
<asp:CheckBox ID="check" runat="server" class="myClass" />

このようなHTMLとしてレンダリングされる。
<span class="myClass"><input id="check" type="checkbox" name="check" /></span>

そう、<span></span>タグで括られてしまう。 これでは、フロントエンドでDOM解析をしたいときに非常に不便だ。と同時に input に属性を付与できないという最も大きな問題を引き 起こす。
そこでレンダリング方法をカスタマイズしてみたいと思う。

WebControlAdapterクラスを継承したクラスを作る。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;

public class CheckBoxAdapter : WebControlAdapter
{
    protected override void Render(HtmlTextWriter writer)
    {
        CheckBox targetControl = this.Control as CheckBox;
        if (targetControl == null)
        {
            base.Render(writer); return;
        }
        writer.WriteBeginTag("input");
        writer.WriteAttribute("type", "checkbox");
        writer.WriteAttribute("id", targetControl.ClientID);
        if (targetControl.CssClass.Length > 0)
        {
            writer.WriteAttribute("class", targetControl.CssClass);
        }
        writer.Write(" />");
    }
}

でもって ブラウザ定義ファイルに以下のコードを追加する。
<browser refID="Default">
<controlAdapters>
                        <adapter controlType="System.Web.UI.WebControls.CheckBox" adapterType="CheckBoxAdapter" />
        </controlAdapters>
</browser>

さて、この状態で以下のようなマークアップがどのように変化するのか・・・ というと
<div> <asp:CheckBox ID="check" runat="server" CssClass="myClass" /> </div>

きれいなHTMLコードをレンダリングするようになりました。
<div> <input type="checkbox" id="check" class="myClass" /> </div>

まぁ、いまさら ASP.NET Web Forms もないだろ・・ という声も聞こえてきそうですが、画面の初期化を Web Forms で画面の更新を Web API で実行するハイブリット方針も、これはこれでなかなか生産性が高い方法でもあるのです。

コミット・メッセージには気をつかっていますか?

コミット・メッセージには気をつかっていますか?
1か月も経てば、いや、1週間程度でほとんど記憶も吹っ飛び、自分が書いたメッセージさえ意味がわからないなんてことになっていませんか?
たとえば、Git界隈では、このあたりも積極的に議論が成され一定の規範に則って運用しようという文化が醸成されつつあります。
調べてわかればよい、という意見も多く聞かれますが、果たしてこの感覚は正しいものでしょうか?
いえ、正しい誤りという二律背反的な捉え方は無意味でしょう。 第一、時間の無駄です。調べるという行為には追跡という要素があります。この追跡という行為には推測という要素がつきものです。つまり、推測に誤りがあれば間違った情報や解釈に到達してしまう危険性があります。
たかが、コミットメッセージだけで大げさな… という見方もできるかもしれません。事はコミットメッセージだけに留まらずドキュメントやコードにまで影響するのです。

どういうことか?
コミットメッセージさえ気を使えなければ、ドキュメントもまたしかりだと思います。
これは作業品質の問題です。 あるいは、余計なことに頭を使う必要がなければ、もっと本質的な部分に注力することが可能になります。

2015年9月5日土曜日

boot2dockerを試す

WindowsやOSXな方は、boot2docker を導入することで、手軽に Docker のソリューションを試してみることができます。
とは言え、それなりにハマりどころが存在するのも、この手の技術の常です。

まずはインストールしてみましょう。
公式サイトに行って自身の環境にあった boot2docker のインストーラをゲットします。
インストール自体は非常にシンプルで、指示に従うのみです。
その際、VirtualBoxとcygwinもいっしょにインストールされますが、既に導入済みのかたはチェックを外せばいいでしょう。

さて、VirtualBox で 32 bit の仮想サーバーしか作れない、というトラブルに見舞われたなら、BIOSをチェックしてみてください。
VT-x が BIOS で OFF になっているケースが考えられます。

ということで、boot2docker のインストールが完了しました。デスクトップにあるアイコンをダブルクリックすると Dockerコンソールが起動します。このとき、コマンドプロンプトで入力待ち状態になります。これで boot2docker が起動しました。

バージョンを確認してみます。
docker -v

Docker Version 1.8.0. build 0d03096

と表示されれば正常です。

では、早速 Docker を作成します。
たとえば、
docker pull centos:latest

CentOSの最新イメージを取ろうと思います。

と、Pulling repository docker.io...
となったところで、connection refused.

ん。。。

DNSの指定をチェックします。

$ boot2docker ssh
docker@boot2docker:~$ vi /etc/resolv.conf

## そして、以下を追加して
## nameserver 8.8.8.8

docker@boot2docker:~$ cat /etc/resolv.conf
nameserver 8.8.8.8
docker@boot2docker:~$ exit
$ boot2docker restart

そして再び Docker pull

超えるべき壁は多い予感です。

2015年9月3日木曜日

急がば回れ

落ち着きのない仕事をたまに見かけます。というよりかなりの高確率で見かけます。
先を急いでもよいことはありません。

たとえば、ひとつのクラスの実装を終えました。
これから動作させてデバッグをしようと思いますが、果たして、そこで確認をするでしょうか? 再確認です。
クラスを生成してオブジェクト化するにあたり、事前条件は揃っていますか?
実際に動作させた後の事後条件と期待値は頭の中で整理できていますか?
そもそもコードのセルフレビューは実施しましたか?

こういった単純な準備作業は案外重要です。ここで一歩引いて俯瞰するゆとりが、あるのか?ないのか? で時間の節約の仕方がだいぶ変わります。それどころか、この段階でつまらないバグはつぶせるはずです。

昔から言い古されている言葉ですが、ゆっくり、落ち着いて、ひとつひとつ確実にこなすのが結局はいちばん早いのです。

2015年9月2日水曜日

ASP.NETのレガシー・マークアップ

ASP.NET4.5 Web APIで構築されたHTMLに対して Angular.JS でバリデーションをレンダリングしようと企てたのだが、form要素のname属性が捨てられていることに、いまさらながらに気づいた。
下記は MSDN の ASP.NET と XHTML というドキュメントからの抜粋。

---

XHTML に準拠するための ASP.NET 機能 
ASP.NET は、form 要素に action 属性を動的に追加します。既定では、form 要素には XHTML 1.0 Transitional 仕様で許可されている name 属性が含まれています。これ により、フォーム名を使用して form 要素を解決するクライアント スクリプトに依存する既存のアプリケーションとの下位互換性が保持されています。 
メモ : 
form 要素の name 属性は XHTML 1.1 ガイドラインでは許可されていません。name 属性をレンダリングしないようにアプリケーションを構成できます。 

ASP.NET ページとコントロールの XHTML レンダリングの制御 
ASP.NET コントロールで XHTML 1.1 仕様のより厳密な形式でマークアップをレンダリングすることが必要な場合があります。既定のレンダリングには、XHTML 1.1 仕様に 準拠していないマークアップも含まれています。たとえば、XHTML 1.1 標準では、HTML form 要素の name 属性の使用は禁止されています。 
メモ : 
レガシ マークアップをレンダリングするオプションは、主に既存のページを ASP.NET の最新バージョンに移行するために提供されているので、ASP.NET の将来のバージョ ンではサポートされなくなる可能性があります。 

レガシ レンダリング 
レンダリングをレガシに設定すると、ASP.NET のページとコントロールは、レンダリング機能を ASP.NET の以前のバージョンの動作に変更します。次のような変更が行われます。 
form 要素は、name 属性を使用してレンダリングされます。

---

以上を踏まえてASP.NETのマークアップを利用してレンダリングするには、次の3つの方法がある。

・Legacy (以前のバージョンの ASP.NET でのマークアップのレンダリング方法とほぼ同じ、典型的な例は、form タグの name 属性をレンダリングする場合)
・Transitional (XHTML 1.0 Transitional)
・Strict (XHTML 1.0 Strict)

どの方法を使ってレンダリングするかは、以下の方法で指定する。
Web.config ファイルの system.web 要素に xhtmlConformance 要素を追加する。次に、mode 属性を Legacy、Transitional、または Strict に設定する。

xhtmlConformance 要素が Web.config ファイルに定義されていない場合、既定の設定モードは transitional となる。

以下は、XHTML のレンダリングを無効にするコード例

<system.web>
<!-- other elements here -->
    <xhtmlConformance
        mode="Legacy" />
</system.web>

以下は、XHTML 1.0 Strict のレンダリングを指定するコード例

<system.web>
<!-- other elements here -->
    <xhtmlConformance
        mode="Strict" />
</system.web>

では、Legacyレンダリングに設定した場合の副作用は・・・
1)form 要素の内部の div 要素はコントロールのコンテナとして自動的にレンダリングされない
2)検証コントロールは、controltovalidate などのカスタム属性を使用して span 要素としてレンダリングされる
3)img 要素では、alt 属性と src 属性はそれらを明示的に含めない限りレンダリングされない
4)Autoポストバック機能をサポートする必要がある場合、コントロールは language="javascript" などの language 属性をレンダリングする。
5)コントロールの Wrap プロパティが false に設定されている場合、div 要素をレンダリングする Panel などのコントロールに nowrap 属性が追加される
6)ImageButton コントロールは、border 属性をレンダリングする
7)br 要素は、すべて <br> としてページにレンダリングさる。ただし、明示的に <br /> タグを記述すると、そのままレンダリングされる。
8)BackColor プロパティが設定されている場合、DataGrid コントロールと Calendar コントロールには、レンダリングされた table 要素に bordercolor 属性が含まれる

以上は押さえておくべきポイントです。

2015年9月1日火曜日

gulpモジュールで簡単なタスク自動化

gulp は Node.js 上で動作するタスク自動化のためのビルドツールです。
ソースファイルの圧縮、lessファイルのコンパイルやCSSのベンダープレフィックスの付与、CoffeeScriptのコンパイルなどを実行できます。
タスク定義をシンプルな JavaScript で記述して動作させるのが特徴です。このあたりが Grunt のJSONで宣言的に定義する方法より細かい制御がシンプルに記述できる理由です。

では gulp をインストールしてみます。今回はWindowsで試してみます。
まずは npm で gulpモジュール をグローバルオプションでインストールします。
npm install -g gulp

C:\Users\username\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js
gulp@3.9.0 C:\Users\username\AppData\Roaming\npm\node_modules\gulp
├── pretty-hrtime@1.0.0
├── interpret@0.6.5
├── deprecated@0.0.1
├── archy@1.0.0
├── tildify@1.1.0 (os-homedir@1.0.1)
├── minimist@1.2.0
├── v8flags@2.0.10 (user-home@1.1.1)
├── chalk@1.1.1 (supports-color@2.0.0, escape-string-regexp@1.0.3, ansi-styles@2.1.0, strip-ansi@3.0.0, has-ansi@2.0.0)
├── semver@4.3.6
├── orchestrator@0.3.7 (sequencify@0.0.7, stream-consume@0.1.0, end-of-stream@0.1.5)
├── liftoff@2.1.0 (extend@2.0.1, rechoir@0.6.2, flagged-respawn@0.3.1, resolve@1.1.6, findup-sync@0.2.1)
├── gulp-util@3.0.6 (array-differ@1.0.0, array-uniq@1.0.2, lodash._reevaluate@3.0.0, lodash._reescape@3.0.0, beeper@1.1.0, object-assign@3.0.0,  lodash._reinterpolate@3.0.0, replace-ext@0.0.1, vinyl@0.5.1,lodash.template@3.6.2, through2@2.0.0, multipipe@0.1.2, dateformat@1.0.11)
└── vinyl-fs@0.3.13 (graceful-fs@3.0.8, strip-bom@1.0.0, defaults@1.0.2, vinyl@0.4.6, mkdirp@0.5.1, through2@0.6.5, glob-stream@3.1.18, glob-watcher@0.0.6)

任意のディレクトリに再度gulpモジュールをインストールします。
これは、グローバルでインストールした gulp がローカルインストールの gulp を実行する役割に使われるためです。
プロジェクトによって gulp のバージョンを合わせることなくタスクを実行できます。
npm install gulp

また、以下のようなオプションでインストールすると package.json で管理できるようになります。
これは、プロジェクトメンバ間でパッケージモジュールそのものを管理するのではなく、package.json を基にして、その都度インストールするときに便利です。
npm install --save-dev gulp

バージョンを確認します。
gulp -v
[23:05:23] CLI version 3.9.0
[23:05:23] Local version 3.9.0

次に gulpfile.js というファイル名で gulp の設定ファイルを作成します。

'use strict'
var gulp = require('gulp');
 
// 監視タスク
gulp.task('watch', function () {
    gulp.watch('*', function (event) {
        console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
    });
});
 
// デフォルトタスクとしてwatch
gulp.task('default', function () {
    gulp.run('watch');
});

では、gulpを動作させます。コマンドは次のようにシンプルです。
gulp

[23:15:09] Using gulpfile C:\xxx\Gulp_Test\gulpfile.js
[23:15:09] Starting 'default'...
gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead.
[23:15:09] Starting 'watch'...
[23:15:10] Finished 'watch' after 12 ms
[23:15:10] Finished 'default' after 21 ms
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント.txt was added, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (2).txt was added, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (2).txt was deleted, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (3).txt was renamed, running tasks...
File C:\xxx\Gulp_Test\新しいテキスト ドキュメント (3).txt was deleted, running tasks...
^Cバッチ ジョブを終了しますか (Y/N)? y

任意のディレクトリ配下のファイル変更を監視し、変化があればコンソールにメッセージを表示します。
gulpコマンド実行後、いろいろなファイルを作成して試してみてください。

以上のような特性を利用して、テストランナーを走らせたり、ビルドタスクを実行したりするわけです。