2013年12月13日金曜日

Windows環境でのbundle install

proxy環境下でbundleコマンドを実行する場合、そのままだとエラーが発生します。
bundleに外部アクセス時にはproxyサーバーを使用する設定します。

コマンドプロンプト画面よりhttp,httpsのproxyサーバーを設定します。

http_proxy="http://192.168.1.1:8080" 
https_proxy="http://192.168.1.1:8080" 

これで同じように

bundle install

bundleコマンドが使用できます。現在proxy環境下で開発しているので、これができると便利です。

2013年11月27日水曜日

四国コワーキングフォーラムに参加

四国コワーキングフォーラムにて、コラボワークの事例紹介として、WEBアプリケーション開発事例を発表させてもらいました。

場所は香川県高松市のe-とぴあ・かがわです。4月にDev Love四国を行った場所です。
10分程時間を頂きまして、どのようにしてNcPartworkを開発していったのかを発表しました。

コワーキングスペースでどんな感じでコラボワークしてくのかを発表したのですが、皆さん真剣に聞いて頂き、発表したかいがありました。

フォーラム全体では
  • 基調講演
  • コラボワークの事例
  • コラボワークの体験
3セッションがあり、愛媛県以外のコワーキングスペースでも、活発に活動されている様が分かりました。
各コワーキングスペースとも特色があり、総じてオシャレな作りになっているのが、印象的でした。
徳島の神山バレーはえらいことになっているようです。

コラボワーク体験はおなじみマシュマロタワーです。
今回はスパゲティがちょっと壊れ易かったのか、50cmと前回の記録を更新することはできませんでした。ただ、初めてお会いしたメンバーといい感じで共同作業ができるようになったのは進歩したのかもしれません。



続いて、フューチャーセッションに参加し「盆栽をBonsaiへ」とのお題で、ひたすら盆栽の世界進出について話合いました。
大人5人で盆栽について、真剣にアイディアを出し合っているのがとても新鮮でした。
あと盆栽って思ったより、海外に進出しているんですね。

最後に懇親会ですが、何故かチーム徳島に混ぜてもらい、面白い話を聞かせてもらいました。徳島の皆さん、ありがとう!

2013年10月18日金曜日

ios 7でstatusbarの色を白くする

今作成中のiosアプリなのですが、全体的にダークなデザインのアプリなので、ステータスバーが黒いと正直言って全然良くないです。
加えて、可視性もよくないです。

ステータスバーの色を白くしたかったのですが、ios 7ではステータスバー周りの実装が変わってしまったのか、Statsu bar styleをUIStatusBarStyleLightContentにする方法ではうまくいきません。
Google先生に聞く事一時間。やっと分かりました。

Info.plistを以下の通りに設定します

  1. "View controller-based status bar appearance" をNOに設定
  2. "Status bar style" を"Opaque black style"に設定
これでステータスバーの色が白になりました。コードを書かないのはいいのですが、この組み合わせは分かりません。

2013年8月16日金曜日

石鎚神社


知り合いに誘って頂いて、石鎚神社にお参りに行ってきました。
石鎚神社とは日本七霊山の一つで、頂上社、成就社、土小屋遥拝殿、本社と4社あります。今回は石鎚山中腹にある、成就社へ行ってきました。

標高1,450mにある成就社までは、石鎚登山ロープウェイの山麓下谷駅からロープウェイ山頂駅まで約8分。そこから徒歩で20分ぐらいで成就社へ着きます。
道はちゃんと整備されているので、迷うことなく到着しました。

成就社までくると、地上とはかなり違って涼しくて、快適でした。ネットがつながるのなら、ここで仕事しようと思ったぐらいです。

参拝をした後、お札を購入しました。
これで弊社にも、何かご利益があれば。

来年は、山頂社を目指したいと思います。

2013年8月5日月曜日

NcPartWork

弊社で初のサービスがスタートします。
NcPartWorkといいます。

 
派遣型勤務アルバイトさんの給与計算するウェブアプリです。
元々、松山にあるコワーキングスペースのダイアモンドクロスさんと、ネットプラン松山さん、弊社ネクストコードの3社でスタートしたプロジェクトでした。

起業して思っていたことは、何か自分で製品を作って販売したいという事でした。アジャイル的に製品を開発し、継続して開発、運用できていければと思っていました。

しかし、今までのWebアプリの作り方では、継続開発は無理なんじゃないかと思っていたところでした。

特にJavascriptが致命的で、使い勝手がいいので、JQueryを色んな所で使うのですが、コードがうまく分けて記述できないので、コードの拡張性、保守性が確保できていませんでした。

サーバーサイドではJava+MVCフレームワークを使い、コードをうまく分離して記述していたので、クライアントサイドでも、何かのフレームワークを使用しなければいけないと思っていました。

まずはじめに、Javascriptフレームワークのbackbone.jsを触ってみたのですが、データバインディング機能がないので、モデルの変更に対して、ビューの変更も自分で行う必要があり、もっと楽が出来そうなフレームワークはないのかと探したのが、AngularJSでした。



AngularJSのチュートリアルを一通り、やってみて、何か自分で作ってみようと、始めたのが、自社向けの会計ソフトでした。特にいい案でもなかったのですが、どうせ作るなら、自分で使うものを作ろうと、始めたのでした。

それを見たネットプランの上田さんが、これは他に使えると提案してくれたのが、派遣型勤務アルバイトアプリでした。

元々上田さんはダイアモンドクロスで作業しているときに、簡単に給与計算ができて、データを共有できるアプリはないかと、相談を受けていたようです。

給与計算アプリはいっぱいあるのですが、高機能で価格も高いのネックのようで、導入に踏み切れていないようでした。

そこでちょっと作ってみようかと思い、始めたのがこのWebアプリでした。
特にこれをみんなに公開しようとは思ってなく、AngularJsの技術が習得できればいいなと思うぐらいでした。

普段であれば、途中であっさりと、挫折してしまうのですが、今回は自分以外のメンバーもいます。辞めますとは言えません。
他の事もやりながらですが、3ヶ月で一応なんとか公開できるレベルまで、持って行く事ができました。

ニッチな製品で、まだ完全ではないですが、一度公開して、ユーザーからのフィードバックがもらえればと思っています。

先月受講したセミナーでゲストスピーカーの方が仰っていました。

「もし、その商品やサービスを否定されても、その商品を柔軟に改善したり、成長させて行けるほどの体力や愛はありますか?」

やっと、入り口にたどり着いただけですが、仲間入りできそうです。

2013年7月23日火曜日

Angularjsで画面をスクロールする

久しぶりにAngularjsのTips。
Angularjsで任意の場所へスクロールを設定する方法。
ボタンが押下された場合、先頭に移動したりするときに使うと思う。

まずhtml側で

<div id="top"></div>

<button class="btn" ng-click="jumpTo('top')" type="button">先頭へ</button>



ジャンプ先を設定しておき、ng-clickのイベントで処理をする。
Controller側では

$scope.jumpTo = function (id) {
 $location.hash(id);
 $anchorScroll();
}


$location、$anchorScrollはモジュルをインジェクションする。
そうなんです、$anchorScrollを使えばスクロールできる。
今回、簡単そうに見えて悩みました。

2013年7月18日木曜日

マーケティング研修2

先週と同様に松山市地域雇用創造協議会の主催する「実践!売れるマーケティング体験研修」に参加した。
今回は、マーケティング事例紹介とアイディアの出し方だった。

事例は今治のさくらコットン様の事例だった。

なぜ事業を始めようと思ったのから始まり、どんな感じで進めてきたのか、ダメな所、よかった所など多岐に渡り、かなり具体的な内容を話して頂いた。あっという間の1時間だった。

実際の数字も出てきて、本当に為になるお話だったので、共感を持って聴かせて頂いた。

本人も仰っていましたが今までやってきたことが、自然にマーケティング活動になっているんだな。こんな感想だった。

簡単に製品開発とか考えているが、

「もし、その商品やサービスを否定されても、その商品を柔軟に改善したり、成長させて行けるほどの体力や愛はありますか?」

と言われていたのが印象的だった。
そんなことを言えるような、商品やサービスを自分も持てれば。
みなさん私なんかより、何倍も努力されているのだと、実感したセミナーだった。

2013年7月12日金曜日

マーケティング研修

松山市地域雇用創造協議会の主催する「実践!売れるマーケティング体験研修」に参加した。今回は第2回だが、前回も面白かったが、今回も面白かった。


  • マーケティングとは「売れる仕組み」を作る事です。
「誰に」、「何を」、「どのように」を構築していく。
加えて、ここに顧客視点、競争優位などの要素を考慮していく。


  • ターゲットを決める。

万人受けするものを狙いたがるが、買ってもらえなければ意味がない。
共感を得るには、ターゲットを絞って行った方がいい。
大きな会社ならば万人受けするようなものが作れるかもしれないが、
小さな会社は、ターゲットを決めほうがいい。

今までは、何となく分かっていると思っていたが、反省することばかりだ。
本研修は大変勉強になった。来週もう一回、それも事例紹介があるので楽しみだ。

2013年7月11日木曜日

HomeBrew でMySQL のインストールができない


Rails の環境を作成する際に、以下のメッセージが出た。


$ bundle install --local
Could not find mysql2-0.3.11 in any of the sources
Run `bundle install` to install missing gems.

mysql2-0.3.11 が不足しているようだ。
個別にインストールする。


$ gem install mysql2 -v 0.3.11
Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
    ERROR: Failed to build gem native extension.

    /Users/xxxx/.rbenv/versions/2.0.0-p247/bin/ruby extconf.rb
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
...

しかし、エラーになった。
MySQL をインストールしていなかったので出た模様。

HomeBrew を使用して、MySQL をインストールする。

$ brew update
$ cd /usr/local
$ brew versions mysql
5.6.12   git checkout ba37612 Library/Formula/mysql.rb
5.6.10   git checkout 48f7e86 Library/Formula/mysql.rb
5.5.29   git checkout 336c976 Library/Formula/mysql.rb
5.5.28   git checkout 5825f62 Library/Formula/mysql.rb
5.5.27   git checkout 93aecfa Library/Formula/mysql.rb
...

バージョン5.5系が欲しかったので、git から取得

$ git checkout 336c976 Library/Formula/mysql.rb
$ brew install mysql
==> Downloading http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.29.tar.gz/from/http://cdn.mysql.com/

curl: (7) couldn't connect to host
Error: Download failed: http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.29.tar.gz/from/http://cdn.mysql.com/

ここでもエラーでコケる。
この後、プロキシの設定などを行なってみるが結果変わらず。

バージョンの指定を指定なかったので、バージョンを付けてインストールしてみる

$ brew install mysql55
==> Downloading http://downloads.mysql.com/archives/mysql-5.5/mysql-5.5.30.tar.gz
######################################################################## 100.0%
==> cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/Cellar/mysql55/5.5.30 -DMYSQL_DATADIR=/usr/local/var/mysql55 -DINSTALL_MAN
==> make
==> make install
==> /usr/local/Cellar/mysql55/5.5.30/bin/mysql_install_db --verbose --user=xxxx --basedir=/usr/local/Cellar/mysql

If you are using a binary release, you must either be at the top
level of the extracted archive, or pass the --basedir option
pointing to that location.


READ THIS: https://github.com/mxcl/homebrew/wiki/troubleshooting


バージョン指定が大切だったのか。

2013年7月9日火曜日

Deviseで登録画面をrootにする方法

Railsで簡単に認証機能を追加できるDevise
ネット上を見ていると、カスタマイズしづらいとかあまり評判はよくないようだ。
私はとくに問題なく使っている。あまりカスタマイズしないからだろうか?

Deviseでは初期画面としてログイン画面が表示される。今回はこれを登録画面が表示されるように変更したい。
グーグル先生に探してもらったのを試しでみたが、動かない。なんでだろう。
Deviseのrouteを変えるのではないかとニラんでいたので、ソースコードを覗いてみた。

こんなときにGitHubは便利だ。


    # Allow you to route based on whether a scope is *not* authenticated.
    # You can optionally specify which scope.
    #
    #   unauthenticated do
    #     as :user do
    #       root :to => 'devise/registrations#new'
    #     end
    #   end
    #
 


見ていると、コメントアウトされているが、こんなコードが書いてあった。
まさにこれがやりたいとだ!

これをroutes.rbに書いてみた。
正解でした。これでアプリにアクセスした時には登録画面が表示されるようになった。
routes.rbにこんな書き方できるんだ。勉強になった。

2013年7月4日木曜日

iOSでLibrary Linkエラーが発生する

iOSでオープンソースのライブラリをリンクしようとするとエラーが発生した。

 ignoring file /usr/local/lib/libevent.dylib, file was built for unsupported file format
サーポートされていないファイルフォーマットだと言われている。

このライブラリはLibeventというもので、callback関数を設定したり、呼び出す為に使用する。Mac OS Xでは、標準ではないようなので、いつもの通りにbrewでインストールして、xcodeでリンク作業を行ったが、上記のエラーが発生してしまう。

brewでのインストールは64bitで行われるようで、iosとか32bit環境でも使いたい場合はuniversalオプション付きでインストールする必要がある。


brew install libevent --universal


でインストールするとよい。

2013年7月3日水曜日

Redisのインストール

Redisを知ってますか?

私は正直言って知らなかった。
RedisとはBSDでライセンスされている、オープンソースのkey-valueストアことで、簡単に言えばNoSQL。

NoSQLは過去にMongoDBCassandraを使った事がある。特にCassandraでスキーマの作り方とか学習したが、そんな大量データを扱う事がないので、今もって業務では使用していない。

今回は新たに、Redisを使ってみる。Redisにはkey-valueストア以外にも機能があり、Pub-Subサーバーとして使える。

今、個人的にPub-Subにハマっているので、インストールしてみる。
Mac OS Xでパッケージ管理にはhomebrewを使っていると、コマンド1行で終わる。


$brew install redis
dyld: DYLD_ environment variables being ignored because main executable (/usr/bin/sudo) is setuid or setgid
==> Downloading http://redis.googlecode.com/files/redis-2.6.14.tar.gz
######################################################################## 100.0%
==> make -C /private/tmp/redis-t51l/redis-2.6.14/src CC=cc
==> Caveats
To have launchd start redis at login:
    ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents
Then to load redis now:
    launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
Or, if you don't want/need launchctl, you can just run:
    redis-server /usr/local/etc/redis.conf
==> Summary
  /usr/local/Cellar/redis/2.6.14: 9 files, 760K, built in 10 seconds


何事も問題なくあっさりと10秒でインストールできた。
起動は手動でやりたいので、書いてある通り


$redis-server /usr/local/etc/redis.conf
[80525] 03 Jul 16:45:20.844 * Max number of open files set to 10032
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 2.6.14 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 80525
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

[80525] 03 Jul 16:45:20.846 # Server started, Redis version 2.6.14
[80525] 03 Jul 16:45:20.846 * The server is now ready to accept connections on port 6379


いい感じで起動が完了した。
接続をしてみる。


$ redis-cli
redis 127.0.0.1:6379>


これで接続確認できた。あとは、使い方を習得しないと。

2013年7月2日火曜日

OpenLayersのMarkerにidを設定する

今回もOpenLayers。OpenLayers.Layer.Markersを使って、Markerを表示させる。
表示したMarkerをクリックしてイベントをキャッチするまでは前々回書いた。

今回はどのMarkerでイベントが発生したか判定する方法。
ドキュメントを見るのだが、Markerにはデータを保持できるようなプロパティはない。
しかし、OpenlayersにはいろいろなExampleがあり、それを見て自分でやり方を発見するのだ。MarkerのExampleはここにある。

ソースを見て分かったのは以下の通り。


var marker = new OpenLayers.Marker(lonLat, icon);
marker.id = uid; //ここで設定 
marker.events.register('mousedown', marker, showMessages);

Markerにidというプロパティがあり、これを使用する。
設定したidはイベント内でどのように使用するか。


showMessages = function(evt) {

    if (this.id == "uid") {
    }
    OpenLayers.Event.stop(evt);
};

this.id で判定できる。このようにしてイベントが発生したMarkerを判定できる。

2013年6月26日水曜日

AngularJSでController間の通信を行う

AngularJSでController間の通信を行うには2つの方法がある。

1つは$rootScopeに値を設定してしまう方法。
もう一つは$broadcast,$onを使う方法。

$rootScopeはグローバルなオブジェクトであるので、アプリ内のどこからでも参照できる。ここに値を設定すると、各Controllerで値を参照することができる。
しかし、これはグローバル変数を使ったプログラムの弊害で、メンテナンス性が悪くなるのでお勧めはできない。簡単に使えるのでつい使用してしまうが、後で困るのは自分なので使わなようにしたい。

そこでAngularJSでは$broadcast,$onメソッドが用意されている。これを使ってpub-subパターンが実現できる。

angular.module('myApp.controllers', []).
 controller('mainCtrl', ['$rootScope', '$scope', function($rootScope, $scope) {

  var date = {"id": 1, "text": "メッセージです"}
  $rootScope.$broadcast('messageBroadcast',data);

 }]).
 controller('subCtrl', ['$scope', function($scope) {

  $scope.$on('messageBroadcast', function(event,data) {

   $scope.message = data;

  });


 }]);

mainCtrlからイベントを発生させ、subCtrlでイベントを受け取とる。
簡単で有効なパターンなのでぜひマスターしておけばいいと思う。

2013年6月24日月曜日

OpenLayerのMarkerイベントでAngularjsを使用する

Mapアプリ向けのjavascriptライブラリOpenLayersを使ってMapアプリを作っている。javascriptフレームワークはAngularjsを使用している。

この2つのライブラリ、フレームワークを使っているが、Dialog表示でハマってしまった。
マップにピンのようなマーカーを表示させ、マーカーがクリックされたら、Dialogを表示させたかった。

この場合は以下のようなコードになる。

イベントの設定
    var marker = new OpenLayers.Marker(lonLat, icon);
    marker.events.register('mousedown', marker, $scope.showDialog);

イベント
    $scope.showDialog = function(evt) {
        $scope.openDialog();
        $rootScope.$apply();  //これ大切!!!
        OpenLayers.Event.stop(evt);
    };

ここで大切なのは$rootScope.$apply();を呼ぶ事だ。 これによりAngularjsのdigestサイクルに制御が移り、非同期動作のDialog処理が実行される。

2013年6月21日金曜日

Angularjsでフォーカスを設定する。Directivesを使ってみた。

AngularJSで入力項目にフォーカスを設定したい。
JQueryではこんな感じになると思う。

$(document).ready( function() {
   $("#inputText").focus()
});

至ってシンプルだ。しかし、AngularJSでは基本的にDOM操作はしない。Controllerにこのコードを書く事はできるが、スマートは方法とはされていない。このような場合、Directivesを作成するのが正しいやり方だ。

AngularJSの説明を読んでみたが、要はDirectivesとはhtmlを拡張するのだ。と書いてあるがよく分からなかった。いつものようにコードを書いてみると意味が理解できた。

<input type="text" id="inputText" nc-init-focus>


nc-init-focusなんて属性は通常では存在していないが、Directivesを書くことでhtmlを拡張し、動きを定義できる。View部分の操作をControllerに持ち込まなくていいし、モジュール化されているので、再利用しやすい。

フォーカスを設定するDirectivesは以下の通り


angular.module('myApp.directives', []).
 directive('ncInitFocus', [function() {
  var timer;

  return function(scope, elm, attr) {
   if (timer) clearTimeout(timer);

   timer = setTimeout(function() {
    elm.focus();
    elm.select();
   }, 0);
  };
 }]);

elmが渡されるので、そこでDOM操作をする。 このDirectivesはフォーカスを設定して、全選択も行うようにしている。

2013年6月15日土曜日

Webリニューアル


Webサイトをリニューアルした。
今までのページは法人化する前に、今後はこんな感じで活動していければいいなと思って作ったものだった。そのときは、なるべく企業っぽくしたくないと思っていた。

今回はちょっと企業サイトみたいにしてみた。前回の記述も残っているので全面リニューアルではないが、デザインを含めて大きく変えてみた。

今回のリニューアルでAngularJSを使用している。Webアプリではないので、動的な箇所は多くないが、「Contact」のところなどは、ちょっとプログラムを書いてみた。
あとは、Tabs箇所もちょっと手を加えている。

Webサイトも継続的に開発していければと思うので、フィードバックを頂ければと思う。

http://www.nextcode.jp/

2013年6月14日金曜日

Windows Azure

Windows Azureで自社で使用するサーバーを運用している。
マイクロソフトが我々みたいなスタートアップを応援してくくれる、BizSparkというプログラムがあり、入会するとMSDNを提供してくれる。

その中にWindows Azureのサブスクリプションがあり、使用させてもらっている。

いわゆる、クラウドサーバーは、Google App EngineHerokuと使ってきたが今回はWindows Azureだ。

Windows Azureと名乗っているので、Windows Serverしか動かないとかと思ったが、実はLinuxも動かすことも出来るのだ。情報を一元化したかったので、使い慣れたRedmineを使用するため、Ubuntu Serverを使って導入してみた。

Google App EngineやHerokuと違って、仮想マシンを立ち上げるような感じだ。
仮想マシンが立ち上がった後は、sshでログインして設定を行う。Linuxサーバーらしく、コマンドラインでの管理がメインだ。
後は普通のサーバーと同じく、Rails入れて設定するだけ。

Google App EngineやHerokuと違って、使用していない時でも仮想マシンは停止されていないので、サービス起動を待つ必要がないのがいい。
各種リソース使用量を見ていると、もう1台サーバー使えそうだ。
MSDNといい、Windows Azureといい、マイクロソフトさんありがとうございます。






2013年6月12日水曜日

mapソフトのライセンス

Mapサービスを使ったアプリケーションを開発したい。
 技術習得の為Google Mapを使ってみたことはあるが、そんなに難しくなかったようだった。

しかし、各サービスにはライセンスがあり、それもよく改訂されている。自分の要件にあったものがあるか調べてみた。

今回は有料会員しか使えなかったり、イントラネットでの使用するなど閉じた環境を想定している。

Google Maps

「エンド ユーザーが自由にアクセスできる一般公開のサービスであれば、この API を利用できます」 とあり


  1. 有料の顧客のみがアクセス可能なサイト。
  2. 社内から、またはイントラネットでのみアクセス可能なサイト。
  3. 企業の配達業務、車両管理、企業資産管理に関連するアプリケーション、またはこれに類似するアプリケーション。


 となっており、今回の要件ではNGのようだ。別途有料で契約すればいいみたいだが。

Bing Maps

資料さがしましたが、日本語でライセンスを明示しているところを見つけられなかった。
英語はあったので頑張って読んでみたが、

“Limited Public Website Use” means using the Services for commercial, non-commercial or government use (provided that such use is not considered Education or Non-Profit Organization Use as defined in this section) under the TOU without entering into an Agreement, provided that (i) your use is consistent with the terms of Section 6; (ii) your Company Application is available on a public website; and (iii) you do not exceed 125,000 cumulative billable transactions (which will be free of charge) as defined in the SDKs, in any twelve month period.

6.    Limited Public Website Use. Subject to your compliance with Sections 1, 2, 6 and 8 of this TOU, you may develop or host a Company Application that uses the Services for Limited Public Website Use (as defined in Section 2). You may use the Services solely in conjunction with and integrated into Company Applications using only methods and means of access that are documented in the SDKs. If you will exceed the Limited Public Website Use transaction limits or limits on use of the Bing Spatial Data Services API, please contact us at maplic@microsoft.com to discuss how you can license additional transactions. Please note that we do not provide warranties for the Services for Limited Public Website Use under this Section 6. This TOU also limits our liability. These terms are in Sections 8.8 and 8.9 and we ask you to read them carefully.

こんな感じでやっぱり公開サイトでないとダメだと書いているように見える。
ここも参照させてもらったが、やっぱりNGのようだ。これも有料契約すればいける。

Yahoo! Japan

Yahoo! Japanさんの地図はYahoo! Open Local Platformと言うらしい。
これは明確に、「閉じた環境での使用は有料サービスです。」と書いていた。登録すれば商用利用もOKだと書いていたのですが、NGのようだ。

OpenStreetMap
 「自由な地図をみんなの手に」のOSM。
ライセンスはクリエーティブコモンズライセンス CC-BY-SA 2.0となっている。

やはり閉じた環境では、OSM一択となる。Yahoo! Open Local PlatformでもOSMが使えるようになっているようだ。

あとは、どこかのサービスと契約して有料で始めるのも選択肢としてあるかも。

2013年6月5日水曜日

Railsでdevelopmentとproductionでインクルードするスクリプトを変更

Railsで開発時と運用時でインクルードするjavascriptを変えたい。

そもそもなぜこのような事をしたいのかは、webアプリをjavascriptで書いているが、サーバーへのアクセスが必要なもときがあり、それにはurlを指定する必要がある。だけど、開発環境時ではローカルにあるサーバーにアクセスさせたいし、運用時には正式なサーバー
にアクセスさせたい。
これまでは、運用環境にデプロイするたびに手動でurlを変更していた。

この作業はいずれミスをするだろうし、何しろ面倒くさい。なので、urlなど環境ごとに可変の情報を集めておき、開発時にはインクルードし、運用時にはインクルードしないようにできないか。と考えた。

google先生に聞いたみたところ、stackoverflowでこれを見つけた。

まさしくこれがやりたかったこと。

application.html.erb

<%load_javascript %>

application_helper.rb

module ApplicationHelper

 def load_javascript
   if Rails.env.production?
     javascript_include_tag 'application'
   else
     javascript_include_tag 'application', 'devVars'
   end
 end

end

devVars.jsに開発用の情報を記載する。
注意事項は、app/assets/javascriptsにdevVar.jsを置くとapplicationと一緒にインクルードされてしまうので、別の場所に置く必要がある。
vendor/assets/javascriptsに置いてみたところうまくいった。
同じ事で悩んでいる人はいないのだろうか。
railsでこれがベストプラクティクスか知りたい。

2013年5月30日木曜日

AngularJS UI でtypeahead,ng-changeだと動かない

AngularJSでBootstrapを使う場合、UI Bootstrapを使うと便利だ。もともと、AngularUIと呼ばれていたが、AngularUIが幾つかのサブプロジェクトに別れ、Bootstrap関連はUI Bootstrapとなったようだ。

Bootstrapにはtypeaheadの機能があり、テキストボックスに文字を入力すると、これだろうと候補を上げてくれる、イケてる入力補助だ。今回これを使ってみた。


  1. 営業担当の人をテキストボックスへ直接入力した時、typeaheadの機能で候補を選択させる。
  2. typeaheadから入力したい候補を選択する。
  3. 選択した候補のIDをID欄に表示する。

こんな機能を実現したい。
テキストボックスにはtypeahead、変更された事を検知して、営業担当からIDを選択、設定する。

UI Bootstrapではtypeaheadという属性が定義されているのでこれを使う。
変更された後の処理ではAngularJSのng-change属性を使う。

てっきり上記2点で大丈夫だと思っていたのだが、ハマってしまった。
ng-change属性が邪魔してtypeaheadが動かない。いろいろ調査した結果typeahead-editable="false"なる属性設定すると動いた。


 
<input class="inputSellName" type="text" name="inputSellNameForm" placeholder="営業" autocomplete="off" ng-model="project.sell.name" ng-change="changeId()" required typeahead="sell.name for sell in sells | filter:$viewValue " typeahead-editable="false">


こんな長い属性設定になってしまった。でもこの設定書いてる順番で動きが変わる。いいのだろうか。

2013年5月16日木曜日

.NET C#でのMVC

.NET C#でアプリを書いてみる。久しぶりに.NET C#を使った。
アーキテクチャとしてMVCを採用してみた。忘れないように。

 :Model
    public class Model
    {

        public int number = 0;
        public string message = "";

        public EventHandler toChange;

        public void addOne()
        {

            number = number + 1;
            message = "number has changed to " + number.ToString();

            toChange(this, null);
        }
    }


 :View

 
    public partial class Form1 : Form
    {
        public Model model;
        public Controller controller;

        public Form1()
        {
            InitializeComponent();
        }


        public void render(object sender, EventArgs e)
        {
            this.label1.Text = model.number.ToString();
            this.label2.Text = model.message;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            controller.addOne();
        }

    }


 :Controller

 
    public class Controller
    {
        public Model mode;
        public Form1 view;

        public void addOne()
        {

            mode.addOne();

        }
    }


 :Main

 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);


            Form1 view = new Form1();
            Controller controller = new Controller();
            Model model = new Model();

            view.controller = controller;
            view.model = model;

            controller.view = view;
            controller.mode = model;

            model.toChange += new System.EventHandler(view.render);


            Application.Run(view);
        }

こんな感じで作ってみた。
最近Railsでの開発を行っているが、先人達が苦労して編み出した、アーキテクチャとかベストプラクティスとかは積極的に取り入れた方がいい。勉強するコストが掛かっても、それ以上のリターンがあると思う。


2013年5月9日木曜日

AngularJS + Bootstrap + Ruby on Rails

Ruby on Railsで開発を始めて2週間になる。正直言って生産性は高いのではないか。動くものがすぐ作れるのでいい。

フロントエンドをAngularJS、バックエンドをrailsで実装して、フロントーバック間はJSONフォーマットでデータのやり取りをする。こんなシステム構成で開発している。

フロントエンド側をAgularJSベースで開発する利点はリアルタイム、インタラクティブなWebシステムを作り易いことだ。MVCフレームワークなので、ブラウザ側で階層毎にユニットテストが行える。

加えてフロントエンド側にbootstrapを使えば、いい感じでデザインされたWebアプリができる。bootstrapはレスポンシブにも対応しているので、タブレットにも対応できる。

バックエンド側はRailsで実装しているが、ここはRestfulなAPIとしている。Railsを使う利点はこのRestfulなAPIが簡単に作れることだ。

モデルを作成して、それをリソースとして使うと宣言するだけで、GET,POSTなど主だったサービスができる。フロントエンド側ができていなくても、リクエストを発行できるツールなど(firefoxのプラグイン使っている)で動いているのが確認できる。

Rubyが分からないので手探りだけど、RSPEC等のテストフレームワークを使うことで、書いた部分を何度もテストできるので、よりよい書き方があればリファクタリングできる。この後で変えられるという安心感は大切だ。

オープンなフレームワークを使うことで、いいものを安価に開発できる環境はある。あとは何を作るのが大切だ。
例えると、なんか英語は喋れるようになったけど、伝える事がないみたいな感じかな。

2013年5月8日水曜日

twitter-bootstrap-railsでcannot load such file が発生

Railsでbootstrapを使うときtwitter-bootstrap-railsというパッケージを使うと便利だ。Gemfileファイルに

gem "therubyracer"
gem "less-rails"
gem "twitter-bootstrap-rails"
3つのパッケージを使用するように記述。gem "twitter-bootstrap-rails"だけだとエラーが発生する。

cannot load such file -- less
  (in ~/app/assets/stylesheets/bootstrap_and_overrides.css.less)
 


使用する際は上記サイトを良く読もう。読まないとハマってしまい、無駄に時間を使う。

2013年4月30日火曜日

AngularJS date filterで日付がずれる

AngularJSでDate Filterを使うと日付が一日ずれる。
例えば


{{ '2012-04-01' | date:'d MMM yyyy' }} convert -> 31 Mar 2012

このように日付をフィルターした場合、UTCに変換され、前日の日付となってしまう。
この現象はバージョン1.1.2で修正されて、ローカルのタイムゾーンを使用するようになる。

しかしこれは今のところunstableなバージョンなので、アップデートしないで、保存時にUTC->JSTへ再変換することで対応した。


var date = new Date($scope.transDate);
date.setHours(date.getHours() + 9);
$scope.transDate = date;


AngularJSのバージョンアップ時に再度確認すること。

2013年4月25日木曜日

アジャイルサムライ読書会松山道場 #14


アジャイルサムライ読書会松山道場に参加した。
今回は、シトラス・スペース・カンパニーでの開催。シトラスさんには初めてお邪魔させてもらいましたが、いいところです。私はコーヒーを飲む方なので、コーヒーの美味しいお店は大歓迎。

今回は「第11章、現場の状況を目に見えるようにする」。
アジャイルに限らず、混乱している現場ではまずここに手をつけるべき。以前は見える化にはツールを使っていたのだが、最近は付箋紙などに書いて壁に貼る、アナログ手法がいいのでは。

ツールで行っていると外部公開できるようにすれば、社外での閲覧も可能になり便利だが、アナログ方式だどPCやタブレットなどなくてもみる事ができる。見やすい事が大切だと思う。

しかし、手書きだと字が汚いし、漢字も忘れてしまって分かりずらいのだが、汚いのは味だ!、漢字が書けなければひらがなでいいだろ。
と開き直れるようになった。

用語の定義と確認も大切だ。同じ用語でも業界によって意味が変わってくることもあるから確認しよう。読んだことはないが、エリック・エヴァンスの「ドメイン駆動設計」がオススメみたいだ。

平日開催だったので、参加がちょっと少なかったし、メンバーの平均年齢がちょっと高かったようだ。

次回以降はアジャイルサムライの筆者が「問答無用で実践すべき」と思うテーマなので、興味があれば参加してみてください。

bundlerでNetwork error



Ruby on Railを使ってRestfulなサービスを作ろうとしている。
しかし今回も環境構築でハマってしまった。アプリの依存性をチェックして必要なパッケージをインストールしてくれるbundlerがエラーとなり動かない。

bundle install
Fetching source index from https://rubygems.org/
Resolving dependencies...
Network error while fetching
https://rubygems.org/quick/Marshal.4.8/rails-4.0.0.beta1.gemspec.rz


これもproxy環境での問題だ。どうもbundlerにはproxy設定ができないようなのでローカルにある情報でチェックさせる。

bundle install --local
Resolving dependencies...
Could not find gem 'rails (= 4.0.0.beta1) x86-mingw32' in the gems available on
this machine.

--localオプションをつけるといいそうです。


rails new foo --skip-bundle

作成時必ずエラーとなってしまうので、スキップしよう。

DevLOVE四国

4/20土曜日にDevLOVE四国に参加した。DevLOVEとは「開発の楽しさを再発見し、広めて、現場を前進させる」ために様々なコミュニティを融合させて、技術者同士の出会い、学べる機会を提供するものだ。

今回はDevLOVEが四国に初上陸するので高松市まで行ってきた。松山市からでも高速道路を使えば高松までは2時間ぐらいだ。せっかくなので早起きしてうどんも食べに行った。

午後1時開始で、開催の挨拶のあと、「アジャイル開発体験」として、ワークショップがあった。3〜4人のチームでペーパータワーを作成し、高さを競うものだ。以前スクラムのワークショップでマシュマロタワーを作ったが、今回はペーパータワーだ。

物理的、時間的制約下でどのようなタワーを建てることができるか。3回チャレンジしたのだが、なんと1回目で一位の71cmの記録を作ってしまった。何気なくテープで接着した台座が功を奏したのか、安定して立っていた。

2回目は失敗してしまい記録は0cmだったが、3回目はなんと全体でも最高の101cmのタワーを建てることができた。1回目に記録がでたので、以後余裕をもって出来たのが勝因かもしれない。開発も同じで常に動くものがあると、いい感じで開発が続けられる。


その後、HTML5の話。これはブラウザだけで、凄いグラフィックのゲームが作れることに感心、HTML5はWebの可能性を広げたのを実感した。

Google Developer Expertの方はAndroidの今後について数字で説明された。でもプレゼン前半の個人的な内容を説明されていたのが面白かった。東京からのUターンで、どちらかと言えば、後ろ向きな起業だったそう。なんか、「後ろ向きな起業」と言うところが相通じるところがあるのだが...
オラクルJava エバンジェリストの方はさすがに講演がうまかった。多いと年間200回ぐらい講演しているらしく、話も分かりやすく、GlassFishってそんなにいいのか、と引き込まれた。

続いて、私です。今回愛媛県枠で依頼を受けたと思っていたのだが、なんと四国枠として発表。アジャイル導入について話をした。
このように人前で話すことなどないので、緊張し、しどろもどろになった。事前の練習では講演時間ぴったりだったが、次々と話したいことが浮かんできて、付け足していると、後半部分が説明できなくなった。
正直他の方と比べて差があったので、次回このような機会があればリベンジしていきたい。


その後LT、クロージングと進んだが、このあたりは安堵感いっぱいで、良く聞けてなかった。ただ、GDS Shikokuの方がグーグルグラスを購入されていることは覚えている。羨ましい。一度使ってみたい。

DevLOVE終了後、懇親会があり、参加した方々からたくさんの話ができてよかった。同年代の人達とはマニアックな昔話など一人で盛り上がった。

このような機会を与えてくださった関係者の方々ありがとうございました。準備、運営等お疲れさまでした。





2013年4月6日土曜日

Google App EngineでLocalServiceTestHelperを使用した時のタイムゾーン

Google App Engine(GAE)でアプリを作成していて、いいなと思うことはローカル環境でのテスト環境を提供してくれていることだ。

先日、記したJDOを使ってオブジェクトの永続化をする場合でも、ちゃんテストユーティリティが用意されている。LocalServiceTestHelperを使えばローカルでユニットテストができる。


public class LocalDatastoreTest {

    private final LocalServiceTestHelper helper =
        new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

    @Before
    public void setUp() {
        helper.setUp();
    }

    @After
    public void tearDown() {
        helper.tearDown();
    }

 }

マニュアルに書いてある通り。Helperの開始処理と終了処理を行うだけで、ローカル環境でユニットテストができる。なので、データベースとか用意しないでいいのでお手軽
だ。

しかし、このLocalServiceTestHelperを使うとデフォルトのタイムゾーンがUTCに設定される。なので、日付関連のプロパティを持っていたり、ロジックを書いている場合はテストエラーになるので注意が必要である。


    @Before
    public void setUp() {
        helper.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo"));
        helper.setUp();
    }

 }

Helperにタイムゾーンの設定をすると日本時間でテストできる。Javaのタイムゾーン設定は初めてだったので、調べてしまった。

2013年4月5日金曜日

Gsonでjava.lang.StackOverflowError

Google App Engine(GAE)での永続化はJDO(Java Data Objects)で行われる。作成したモデルはPOJOとして使えるのでモデルがきれいに使える。オブジェクト永続化の情報はアノテーションを使って指定する。

親オブジェクトが子オブジェクトを複数もつようなモデルを永続化するときは、アノテーションで1対Nの関係を指定しなければならない。


//親クラス
@PersistenceCapable
public class Parent {

 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 @Extension(vendorName="datanucleus", key="gae.pk-id", value="true")
 private Long keyId;
 
 @Persistent(mappedBy = "parent")
 private List children;

 public Parent()
 {
 }
}

//子クラス
@PersistenceCapable
public class Child {

 @PrimaryKey
        @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 private Key key;
  
 @Persistent
 private Parent parent;
 
 public Child()
 {  
 }
}


コードで表すとこうなる。Childクラスには親インスタンスをもつプロパティを作り、関係性を持たせる。
これをJDOで永続化すると1対Nの関係性をもつオブジェクトがそのまま保持される。

Webアプリの通信をJSONで行う場合、この親オブジェクトからJSON化していけば、綺麗にシリアライズされるはず。そう思ってこんなコードを書いた。ライブラリはGsonを使ってみた。


Gson gson = new Gson();
gson.toJson(parent);


シンプルだ。これでJSON化できるのだから簡単だ。
と思ったら、java.lang.StackOverflowErrorで落ちた。

もう、分かってると思うが、Gsonは親クラスをシリアライズした後、子クラスをシリアライズする。そのとき、マッピング用に指定している親オブジェクトもシリアライズしてしまう。するとまた親から子に向けてシリアライズを行い、永久ループに入ってしまう。

分かると単純なんだが、原因が分かるのにちょっと時間を使った。以前Hibernateでも同じように悩んだ記憶がある。同じ事を繰り返さないように記事にしておいた。

2013年4月4日木曜日

MongoLabからGAEへ

フロントエンドの開発はAngularJSで、バックエンドはMongoLabを使っていた。MongoLabはNo SQLのMongoDBをホスティングサービスしていて、無料で500MBまで使用できるサイトだ。

RESTfulなAPIをサポートしているので、フロントエンドとバックエンド間をJSONで通信するアプリの場合、MongoDBのようなNo SQLだとブラウザからデータをポストするだけで、簡単にデータを永続化できる。

とりあえずフロントエンドを作ってみて、永続化させたい部分をDBに入れる。これだけで、ちょっとしたWebアプリが作成できる。

ただ、残念なことにMongoLabはパフォーマンスがちょっといけてないので、本当に使いたいのであればバックエンドを別に作った方がいい。

今回AngularJSで作ったものを一段グレードアップする為に、Google App Engineを使うことにした。Java+JDOでデータの永続化に挑戦してみる。GAEは料金体系がよくわからないので、使用したことはなかったが、いい機会だ。

パフォーマンスは良くなるのであろうか。楽しみだ。



2013年4月1日月曜日

シマリスScrum

名古屋アジャイル勉強会スタッフ@you_and_iさんによるスクラムワークショップに参加した。
じつはスクラムは体験したことがなかったので、今回が初スクラムだった。始めにチームビルディングでマシュマロタワーチャレンジを行った。これが難しいが、面白かった。2回行ったのだが、1回目は時間内に完成しなかったので、記録は実質0cmだった。だが2回目は心を入れ替えて、アジャイル的に進めて58cmだった。


これが完成したマシュマロタワー。アジャイル的とは最後にマシュマロを載せるのではなく、始めからマシュマロを載せておき、少しづつ改良していく方法だ。2回目はこれでうまくいった。ちなみに世界記録は98cmらしい。
建築とか勉強している人とやってみたい。有利な構造とかあるのではないか。

一通りスクラムの説明を受けたあと、ワークショップで実践。今回のお題は「動物園を
つくる。」
ルールとして動物園に動物を置くためには、それに応じた折鶴を折る必要がある。もしパンダを置きたければ折鶴を4個折る必要がある。トラなら1個。こんな感じで自分の動物園に動物を増やす為には、折鶴を折る作業が必要になる。この作業をうまくマネージメントできるようにスクラムを使う。

しかし、一番の問題は私は折り紙したことがないことだった。チームの中で折れないのは自分一人なので、空き時間をみつけて必死になって勉強したが、どうしても覚えられない。

スプリント1では成果が0であった。これが本当のシステム開発ならば1イテレーションで1つも機能が完成しなかったこととなり、えらいことだ。

その後、見かねたメンバーが助けてくれ、なんとか折れるようになり最後のスプリントでは1.5個折れるようになった。大きな進歩だ。アジャイル的にはベロシティがアップしたのだ。


これが我々の動物園だ。折り紙がきつかった。


これが別チームの動物園。

最後に振り返りを行い、今後に生かせること、問題点、トライしたいことなど話し合い終了。
シマリスScrumワークショップ面白かった。シマリスはリスの一種だったのか!


2013年3月29日金曜日

AngularJS リファクタリング コントローラーの継承

AngularJSで試作しているものはTDDで開発している。レッドー>グリーンー>リファクタリングのサイクルで回していくとコードも改良されて、いい感じになってくる。

リファクタリングではじめに行うのは重複コードの削除だ。AngularJSではコントローラーにコードを書く事が多いだろうから、まずコントローラーの継承方法を。


//BaseController
function BaseController($scope) {
 //ベースコントローラー
}

//Controller1
function Controller1($scope,$injector) {
 //継承されたコントローラー

 $injector.invoke(BaseController, this, {$scope: $scope});
}
BaseController.prototype = Object.create(Controller1.prototype);

AngularJSではこれでコントローラーの継承が行える。これだけのことなのにかなり時間がかかった。AngularJSというよりも、Javascriptでつまずいた感じだ。

参考にしたこのはここ

2013年3月28日木曜日

Agile459 2013年3月


Agile459主催のアジャイルサムライ読書会に行った。10章は本の記述量も少なく、内容もまとめみたいなものだったので、さっくりと終わりました。
 この章に書いてあるように、アジャイルサムライに書いてあることを忠実にやる必要はなく、自分達の組織にフィットしたものからやればいいので、気楽に始めればいい。原典主義に陥らなようにやれば導入できるのでは。あとダメなら止めると宣言してから始めると、いいかもしれない。
個人的には第一歩はユニットテストの導入&自動化からやればいいと思う。これで品質を確保して時間ができれば、他の事に手をつけれるのではないか。

以前DevLove四国やるので、喋ってもらえませんかと依頼を受けていた。安易にいいですよと答えておいたが、四国で喋るのは私一人だったらしい!

2013年3月27日水曜日

AngularJSでUnit Testを行う

AngularJSを使い始めて1週間になる。なんとなく理解できてきたので、AngularJSを使ってのUnit Testのやり方を書いておく。


  • angular-seedよりプロジェクトの元をダウンロードする。GithubなのでクローンでもZipでダウンロードでもどちらでもいいです。

  • Unit TestのrunnerとしてKarma(名前が変わったようだ。前はTestacularだった。)を使う。node.jsが必要なのでまずインストールする。その後Karmaをインストールする。テスト対象のソースコードが更新されたら自動的にUnit Testが実行される。これは便利だ。

  • angular-seedのフォルダ構成は以下の通り。

app/                --> all of the files to be used in production
  css/              --> css files
    app.css         --> default stylesheet
  img/              --> image files
  index.html        --> app layout file (the main html template file of the app)
  index-async.html  --> just like index.html, but loads js files asynchronously
  js/               --> javascript files
    app.js          --> application
    controllers.js  --> application controllers
    directives.js   --> application directives
    filters.js      --> custom angular filters
    services.js     --> custom angular services
  lib/              --> angular and 3rd party javascript libraries
    angular/
      angular.js        --> the latest angular js
      angular.min.js    --> the latest minified angular js
      angular-*.js      --> angular add-on modules
      version.txt       --> version number
  partials/             --> angular view partials (partial html templates)
    partial1.html
    partial2.html

config/testacular.conf.js        --> config file for running unit tests with Testacular
config/testacular-e2e.conf.js    --> config file for running e2e tests with Testacular

scripts/            --> handy shell/js/ruby scripts
  e2e-test.sh       --> runs end-to-end tests with Testacular (*nix)
  e2e-test.bat      --> runs end-to-end tests with Testacular (windows)
  test.bat          --> autotests unit tests with Testacular (windows)
  test.sh           --> autotests unit tests with Testacular (*nix)
  web-server.js     --> simple development webserver based on node.js

test/               --> test source files and libraries
  e2e/              -->
    runner.html     --> end-to-end test runner (open in your browser to run)
    scenarios.js    --> end-to-end specs
  lib/
    angular/                --> angular testing libraries
      angular-mocks.js      --> mocks that replace certain angular services in tests
      angular-scenario.js   --> angular's scenario (end-to-end) test runner library
      version.txt           --> version file
  unit/                     --> unit level specs/tests
    controllersSpec.js      --> specs for controllers
    directivessSpec.js      --> specs for directives
    filtersSpec.js          --> specs for filters
    servicesSpec.js         --> specs for services

test/unit以下にテストを書いていく。


  • Unit TestのフレームワークはJasmineを使っている。Jasmineでなければいけないことはいが、とくにこだわりがないのならJasmineでいいのでは。ControllersSpec.jsはこんな感じになっている。
'use strict';
/* jasmine specs for controllers go here */

describe('MyCtrl1', function(){
  var myCtrl1;

  beforeEach(function(){
    myCtrl1 = new MyCtrl1();
  });


  it('should ....', function() {
    //spec body
  });
});


describe('MyCtrl2', function(){
  var myCtrl2;


  beforeEach(function(){
    myCtrl2 = new MyCtrl2();
  });


  it('should ....', function() {
    //spec body
  });
});


  • テスト実行はコマンドラインから行う。script直下のtest.shを起動する。


npm config set https-proxy http://10.10.40.99:8080
./scripts/test.sh 

すると新しいUnit Test用のchromeが起動され、自動的にテストが実行される。すでにchromeを起動している場合は2つ目のchromeが起動される。テスト用chromeはバックランドで動いていればいいだけなので、小さくしてもいいし、隠してもいいので邪魔にならないところにおいておく。

test.shを起動したターミナルに結果が表示される。


Starting Testacular Server (http://vojtajina.github.com/testacular)
-------------------------------------------------------------------
INFO [testacular]: Testacular server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 25.0 (Mac)]: Connected on socket id kOH8yR-070Vtb5m8pwXt
Chrome 25.0 (Mac): Executed 5 of 5 SUCCESS (0.13 secs / 0.022 secs)

こんな感じで5件のテストが成功したと教えてくれる。

TDDで開発するならここからがスタートとなる。こんな感じでの開発開始となる。JavascriptのUnit Testは初めてだったが、使いだすと必須だ。やっぱり自動テストは書かないといかんでしょう。


2013年3月26日火曜日

AngularJS seed project

一通りAngularJSのチュートリアルをすませたら、自分のプロジェクトを作成したくなる。 そこで使えるのがAngular Seed Prpjectだ。これはAngularJSを使ってプロジェクトを作成する際に雛型を提供してくれるものだ。これを基に開発を始めれば、ディレクトリ構成など共通となるので、プロジェクト間のリソースなどは流用性は高くなる。あとUnit Test, End-2-Endのテストも組み込まれているため、すぐにTDDで開発もできる。
オススメです。

2013年3月25日月曜日

MongoLabでオブジェクトのアップデート

フロントエンドはAngularJSで作成し、バックエンドはMongoLabを使ってオブジェクトの永続化を行った。RESTfulに接続を行ったが、GET,POST,DELETEはつまらなくて行けたが、PUT(更新)がうまくいかなかった。何度やっても更新されない。

MongoLabにあるAPI仕様書を読んでわかった。


$.ajax( { url: "https://api.mongolab.com/api/1/databases/my-db/collections/my-coll/4e7315a65e4ce91f885b7dde?apiKey=myAPIKey",
          data: JSON.stringify( { "x" : 2 } ),
          type: "PUT",
          contentType: "application/json" } );

PUTの時はMongoDB用のidをURLパラメタとして引き渡すが、PUTデータとしてはidは渡す必要はないのではないか!

早速コード書き換えて試してみた。


var url = 'https://api.mongolab.com/api/1/databases/my-db/collections/my-coll/';
var key = '?apiKey=myAPIKey';
var updateId = $scope.obj._id.$oid;
delete $scope.obj._id;  //これが必要?
$http.put(url + updateId + key,$scope.obj).success(function(data)
 { 
});


更新できた。_idは必要ないようだ。

2013年3月23日土曜日

AngularJS $filterの使い方

AngularJSの$filterの使用方法。
$filterをインジェクションして、$filter('使用フィルタ')(処理);

function AppCtrl($scope, $filter) {
 
 var date = Date.now();
 date = $filter('date')(date, "yyyy/MM/dd");
}

dateフィルタを使うと簡単に現在時間のフォーマットができる。

2013年3月22日金曜日

AngularJSでのチェックボッス初期設定

JavascriptフレームワークのGoogleのAngularJSを使っている。
他のフレームワークと違い、直接DOMを操作するようなタイプではなく、モデルとビュー間データバインディングで動的なWebアプリを作成できる。

そこでチェックボックとモデルをバインディングして、初期値を設定する方法が分からなかったので調べてみた。

コントローラー内で以下のようなデータを初期化して、テンプレートに表示する。
checkboxの状態はchekedで表す。

function listCtrl($scope) {
 
 $scope.data = [
 {"date": "2013/12/31","no": "1","checked":"YES"},
 {"date": "2013/12/31","no": "2","checked":"NO"}
     ];
 
}

サンプルにあるような感じでモデルにバインディングしても、初期値に反映されない。

<input type="checkbox" ng-model="journal.checked">

オプションを追加することで初期値に反映される。


<input ng-false-value="NO" ng-model="journal.checked" ng-true-value="YES" type="checkbox" />

trueとfalseの値を指定するとモデルの内容がそのまま初期値として設定される。

2013年3月21日木曜日

Nodeパッケージ管理のプロキシサーバー設定


ネット環境がProxyサーバー経由なのパッケージ管理ソフトにはProxyサーバーの設定が必要となる。
各ツールによって設定方法が違うのでまた設定だ。今度は以下の通り。

npm config set https-proxy http://10.10.40.99:8080

これでホーム直下の.npmrcに設定される。
proxyばかり設定している。

2013年3月20日水曜日

Ruby On Railsをインストール

Ruby On Railsをインストールしたので、環境構築手順を残しておく。残しておかないと忘れてしまい同じような作業を繰り返さなければならないので、インストールとか作業手順を残しておこう。今回はWindows環境にインストールしてみた。


  • Rubyのインストール
Rubyが何かを説明することはないと思うが、Rubyはオブジェクト指向のスクリプト言語。これがなければ始まりませんので早速インストールする。

http://rubyinstaller.org/ にインストーラーがるのでダウンロードしてインストールする。最新バージョンが2.0のようなので、これをインストール。通常こんなメジャーアップデート版をそのまま使うとハマることがあるが、今回はあえてリスクをとってみる。

あとダウンロードしたプログラムはまとめて保存しておく。次に同じ環境を作ることがあるかもしれないので。なぜか2度やらないと思う作業は繰り返されることが多い。

インストールオプションを聞いてくるが、

「Rubyの実行ファイルへ環境変数PATH を設定する」

これをチェックする。PATHぐらい自動で設定してくれてもいいのに。

ターミナルを開いてちゃんとインストールされているか確認する。


ruby -v
ruby 2.0.0p0 (2013-02-24) [i386-mingw32]

  • RubyGemsの更新
 RubyGemsはRubyパッケージ管理ソフトでRubyライブラリを追加、更新、削除できる。

gem update --system
Latest version currently installed. Aborting. 

最新になっているようだ。
ダメだった。プロキシ環境下でパッケージの情報がとれていないだけだった。
なのでまずプロキシの設定


ユーザのホームディレクトリに

.gemrc

というファイルを作りProxyサーバーの設定を行う。

http_proxy: http://hostname:port




再度アップデート
gem update --system
Updating rubygems-update
Fetching: rubygems-update-2.0.3.gem (100%)
Successfully installed rubygems-update-2.0.



こんな感じでアップデートされた。
  • rakeの更新
rakeとはRuby版のビルドプログラムでUnix系に詳しい方はRubyのmakeだと思えばいい。

gem update rake
Updating installed gems
Updating rake
Fetching: rake-10.0.4.gem (100%)
rake's executable "rake" conflicts with C:/Ruby200-x64/bin/rake
Overwrite the executable? [yN]  y
Successfully installed rake-10.0.4
Parsing documentation for rake-10.0.4
Installing ri documentation for rake-10.0.4
Installing darkfish documentation for rake-10.0.4
Gems updated: rake

  • Development Kitのインストール
Development KitとはWindows環境下でCやC++のエクステンションをビルドしてくれる。Windowsユーザはインストールしておいたほうがいい。(らしい。Windows環境で使ったことないので。)

http://rubyinstaller.org/downloads/にDevelopment Kitのダウンロードリンクがあるのでダウンロードする。ダウンロードしたファイルを解凍するが、解凍先はC:\DevKitとする。

\Devkit\devkitvars.bat
Adding the DevKit to PATH...

を実行してPATHを設定する。

動作確認してみます。JSONライブラリでもインストールしてみる。


gem install json --no-ri --no-rdoc
Fetching: json-1.7.7.gem (100%)
Building native extensions.  This could take a while...
Successfully installed json-1.7.7
Done installing documentation for json (0 sec).
1 gem installed


  • Ruby On Railsのインストール
RailsとはRubyを使ったWebアプリケーションフレームワーク。とりあえずRailsをインストール。


gem install rails --no-ri --no-rdoc
Fetching: i18n-0.6.4.gem (100%)
Successfully installed i18n-0.6.4
Fetching: multi_json-1.6.1.gem (100%)
Successfully installed multi_json-1.6.1
Fetching: activesupport-3.2.12.gem (100%)
Successfully installed activesupport-3.2.12
     ・
     ・
     ・
Fetching: rails-3.2.12.gem (100%)
Successfully installed rails-3.2.12
 
29 gems installed

こんな感じでバージョン3.2.12がインストールされた。

rails -v
Rails 3.2.12

でインストールしたバージョンが確認できる。

2013年3月16日土曜日

Gitのプロキシサーバー設定

Gitのプロキシサーバー設定方法です。

git config --global https.proxy 10.10.40.99:8080
git config --global http.proxy 10.10.40.99:8080

こんな感じでターミナルから登録するとプロキシサーバーが指定できる。

 設定情報はユーザデフォルトの

.gitconfig

にある。このファイルをグローバル設定ファイルと呼ぶようだ。
これでGitの設定ができた。

2013年3月14日木曜日

Aptana Studio3でプロキシサーバー経由のアップデート

Apatana Studio3を使っているのだがネットがファイヤーウォールで固く閉ざされており、ソフトウェアのアップデートをチェックがエラーとなって行えない。
Webブラウザも外部へのアクセスはproxyサーバー経由なのでAptanaにもproxyサーバーの設定を行います。

「環境設定」-「General」- 「Network Connections」を開きます。

Active Provider:

  • Direct プロキシサーバーを使用しない。
  • Manual Aptanaで設定いたプロキシサーバーが使用される。
  • Native OSで設定されているプロキシサーバーが使用される。
Proxy entries:
  ホスト、ポート、認証をプロトコル毎に設定する。

Proxy bypass:
  プロキシサーバを経由したくないホストを設定する。

Mac OS Xで使用しているのだが、Active ProviderのNativeが設定できなようなのでManual設定をした。

Aptanaのアップデートはできたが、まだGitがConnection refusedとなってしまう。

2013年3月13日水曜日

JUnit勉強会 in 松山 - "REVIVAL" #season1


Agile459/アジャイルプロセス協議会四国支部の主催でJunitの勉強会があったので参加した。Junitはちょうど10年前に自分がアジャイルに興味を持ち始めたきっかけだ。 

自動テストってなんや?
そんなにコードばっかり書いて作業量が増えるやろ?

こんな感じで懐疑心丸出しで始めたのを覚えている。今となってはあの時始めて本当に良かったと思う。どうしたらJunitでテストが書けるようになれるかを勉強したおかげで、オブジェクト指向についての理解度が深まり、それ以前とは全く違うコーディングスタイルとなった。

なのでJunit勉強会にはぜひ参加したかったし、知っていることを共有しようと思っていたが、自分はJunit4.4など知らなかったので、assertThatなるものがあることを知らなかった。逆に教わることばかりだった。いつもassertEqualsで書いていたので知らなかったが、新しい技術が取り入れられているんだな。

途中誕生会などはさみ3時間でしたが、まだまださわりの部分だけだったので、次回はぜひテストを書きやすいアプリケーションアーキテクチャなどを題材にしてもらえれば、もっとテストを書くのが楽しくなるのでは。

最後に確認したいのだが、テストコードにはテストコードいらんよね。

2013年3月11日月曜日

Node.jsを使ってみる2

前回の続き

  • リクエストのルーティング化
ルーターを作成してルーティングできるようにした。匿名クラスはどうしても好きになれない。


Stardust:Node user$ node index.js 
Server has started.
Request for /start received.
Request received.
About to route a request for /start
Request for /favicon.ico received.
Request received.
About to route a request for /favicon.ico

ちゃんと動いている。


  • 本当のリクエストハンドラへのルーティング
とりあえずrequesthander.jsファイルにハンドラーを記述してみる。
javascriptは連想配列に関数を設定できるようだ。なのでこんなコードがかける。


var handle = {}
handle["/"] = requestHandlers.start;

function route(handle) {
  if (typeof handle[0] === 'function') {
    handle[0]();  ---> ここのこと!
  } else {
    console.log("No request handler);
  }
}

これで関数が呼び出せる。コードを修正して起動してみた。
http://localhost:8888/startでアクセス

Stardust:Node user$ node index.js 
Server has started.
Request for /start received.
Request received.
About to route a request for /start
Request handler 'start' was called.
Request for /favicon.ico received.
Request received.
About to route a request for /favicon.ico
No request handler found for /favicon.ico


今度はhttp://localhost:8888/のみでアクセスしてみる。

Request for / received.
Request received.
About to route a request for /
Request handler 'start' was called.
Request for /favicon.ico received.
Request received.
About to route a request for /favicon.ico
No request handler found for /favicon.ico

ちゃんと動いているようだ。


  • リクエストハンドラによる応答
nodeではノンブロッキング処理が基本で、イベント駆動に対応させる必要がある。非同期のCallback関数を設定した場合、responseを終了する場所を考えよう。server.jsのstartメソッド内でroute()メソッド後response.endを呼び出してしまうと、Callback関数が終了する前にレスポンスを返してしまうので、真っ白な画面が表示されるだけになる。注意が必要である。

function start(route, handle) {
  function onRequest(request, response) {
   var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    console.log("Request received.");
    
    route(handle,pathname,response);

    response.end(); ---> これだ!これがダメだった。
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}


  • 有益なものを提供する

この章問題なく、upload処理まで終わった。requestに対してListenerを追加するところなどは、Java,PHPなどのフレームワークと同様なので扱いやすい。あと外部モジュールを使って画像ファイルとPostデータ周りも他のフレームワークと変わりはない。


いまさらながら、Socket通信がなかったような。Nodeは簡単にSocket通信できるがウリだったような次はSocket.IOを試してみよう。

清掃


入居した創業準備室だが、長年にわたる酷使により、床がかなり汚れている。荷物の少ないうち掃除した方がいいとの忠告もあり、早速床を清掃することとした。(汚いので写真は小さ くした。)






ホームセンターでリンレイのオール床クリーナー、スポンジを購入し床のワックスはくりをおこなった。原液を床にまきスポンジでこすると、信じられないぐらいきれいになる。
成果がすぐにフィードバックされるので掃除はいい。

現代化学の素晴らしさを体験した後、水拭きして、ワックスをかける。

きれいになった!



ワックスがけに失敗したようで多少ムラがあるようだが、まあいいでしょう。
環境を変えると人間は変わる。良い環境で仕事することは大きな意味があると思う。

2013年3月8日金曜日

Node.jsを使ってみる

Node.jsを使ってみた。Node.jsはサーバーサイドの処理をJavascriptで書ける。あと非同期でリクエストが処理できる。これぐらいの知識しかないのでNodeビギナーズブックを一通りやってみることにした。

まずはインストール。ブックにはgitのリポジトリからソースコードをとってきてコンパイルするように書いてあるが、訳あってgitが使えないので公式サイトにあるINSTALLボタンよりインストール。Mac OS Xなのでインストールボタンを押すとnode-v0.8.22.pkgがダウンロードされるので、このパッケージをインストールする。
nodeは/usr/local/bin/nodeにインストールされた。

インストールされているか確認。

Stardust:~ user$ node -v
v0.8.22


まずはいつもの通りにHelloWorldから。コードはブックをみてください。

Stardust:Node user$ node helloworld.js 
Hello World


とくに問題なし。
今度はサーバーサイドを実装してみる。ブラウザでみてみると。

ERROR

The requested URL could not be retrieved


netstatで確認してみても確かに8888ポートでListenになっているものがない。

Stardust:~ user$ netstat -a -p tcp -L
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen         Local Address         
0/0/128        *.ddi-tcp-1            
0/0/50         *.cslistener           
0/0/50         *.ndmp                 
0/0/50         *.9980                 
0/0/50         localhost.intu-ec-svcd 
0/0/100        *.61307                
0/0/128        *.49181                
0/0/128        *.49181                
0/0/128        localhost.ipp          
0/0/128        localhost.ipp          


と思ったが、/etc/servicesでみてみると

ddi-tcp-1       8888/tcp     # NewsEDGE server TCP (TCP 1)


となっているので、Listenはしているようだ。
ということは、Proxy設定かも。localhostをproxyサーバに投げているのかもしれない。
「システム環境設定」ー「ネットワーク」ー「詳細...」ー「プロキシ」を確認してみるとlocalhostが例外に設定されていなかった。localhostもプロキシに投げないように設定する。

再度ブラウザでアクセス。
出た! Hello World!


次はモジュール化を行う。index.jsとserver.jsに分けて実行してみる。

エラー発生。スタックトレースが表示される。


/Users/user/Documents/Aptana Studio 3 Workspace/Node/index.js:3
server.start();
^
ReferenceError: server is not defined
    at Object. (/Users/user/Documents/Aptana Studio 3 Workspace/Node/index.js:3:1)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:245:9)


serverって単語の単純なスペルミスだったが、Nodeってエラーのときこんなスタックトレースを吐くのね。javaっぽい。 これ長くなりそうので、続きは次回。

机1つですが

テクノプラザ愛媛の創業準備室に入居できることとなり早速引っ越した。
在宅勤務の気軽さも捨てがたいが、どうしても行動範囲が狭くなってしまうし、仕事専用の部屋などないので、自室にある誘惑にあっさりと負けてしまい、ダメ人間の見本みたいになっていた。

これではダメだろうと反省し、テクノプラザに入居させていただくこととなった。
机一つではあるが、これはこれでモチベーションがあがるのである。

2013年3月2日土曜日

ザッポス

以前このブログにも書いたザッポスのことだが、より興味がわいてきたので「ザッポス伝説」を読んでみた。
著者はザッポスCEOのトニー・シェイ。序文にこの本はゴーストライターを使わないで書いたので、読みづらかったごめんなさいと書いてある。正直である。自分も文章を書くのが苦手なので共感がわく。

他の伝記みたいに生い立ちから章は始まるが、面白くなってくるのはザッポスCEOになったぐらいから。トニーはザッポス以前にリンクエクスチェンジ社を経営していたが、マイクロソフトに買収されたあと、企業文化がチームワーク主体から個人主体の環境になってしまったことで、自分が創った会社なのに最後には会社に行くのがいやになり辞めてしまった。そこで次の会社を経営するなら企業文化を重視するのだと思い至ったそうだ。

そこでザッポスのコア・バリューとして


  1. サービスを通して「ワオ!」という驚きの体験を届ける
  2. 変化を受け入れ、変化を推進する
  3. 楽しさとちょっと変なものを創造する
  4. 冒険好きで、創造的で、オープン・マインドであれ
  5. 成長と学びを追求する
  6. コミュニケーションにより、オープンで誠実な人間関係を築く
  7. ポジティブなチームとファミリー精神を築く
  8. より少ないものからより多くの成果を
  9. 情熱と強い意志を持て
  10. 謙虚であれ
を定めた。

各コア・バリューについて細かな説明もあるが、どれも見習いたいことばかりだ。
日本にもコア・バリューや経営方針、経営指針など定めている会社はたくさんあるだろうが、それらよりはちょっと変わったものが多い。

しかしこれらのコア・バリューにしても一昔前の日本企業では普通に持っていたものもある。7など日本企業の典型的な形態だったのでは。新入社員として一斉に入社し、同じ寮に住み、仕事も遊びも同じ会社の人達と過ごす。今、日本企業では仕事とプライベートを明確にわけることがおおいので、7を推進している会社は少ないのではないか。逆にアメリカの企業が大切な事だと言っていることがおもしろい。

加えてザッポスは「社員は会社にとって最も大切な財産だ。」と言う事を実践するため、パイプラインと言うシステムを構築している。パイプラインとは自社で社員のレベルやスキルをあげるもので、新社会人を採用して会社が教育を提供して育てていくシステムだ。日本と違いアメリカではジョブ・スクリプションで仕事が明確になっているので、自分の担当以外の仕事はあまり行わない。なので昇格したれば自分でそのジョブ・スクリプションを満たすような資格、経験などを自分でつまないといけない。

でも、ザッポスではバイヤー希望で入社してきた新人をマーチャンダイジング・アシスタント、アシスタント・バイヤー、バイヤー、シニア・バイヤー、ディレクター、バイスプレジデントと会社が教育してレベルアップさせていくのだ。
これなどまるきり日本企業のやり方と同じで、新人をとって、主任、課長、部長、取締役のように育成していく。昔から日本で行っていたことだ。
経営のグローバル化が叫ばれるなかでも、日本型経営でもいいところはある。

あと一番印象深かったのは、ザッポスはザッポスに影響を与えた書籍を集めてザッポス・ライブラリーを設置している。ザッポスは社員にこの本を読むことを勧めていて、ザッポスの考え方をより理解してもらえるようにしている。これはいいかも。見習いたいところだ。