2012/09/09

PATHの通っているディレクトリのファイルを全て出力するシェルスクリプト

環境

  • OS: FreeBSD 9.0 STABLE
find で type fするとか色々あるが、手っ取り早くこれで。
PATHのコロン区切り展開が sed なあたりが特に苦しまぎれだが、 スマートな解決はあるだろうか。

2012/08/21

JavaFX2を試しつつ gistを試す

Java FX2 を動かしてみたというのはもののついでで、 gistをBloggerに貼れるかどうか試したかったがためにできた記事。

環境

  • OS: Ubuntu 12.04 (64bit)
  • JDK: 1.7.0_06 64bit

Applicationクラス

アプリケーション全体の起動ポイントかつ各種制御。

FXMLファイル

画面の構成、デザイン。CSSも適用できるらしい。Flashで言うところのmxmlか。

コントローラクラス

FXMLの制御。Flashで言うところのmxmlに対するActionScriptファイルか。

その他

  • ビルド・起動時には、${JAVA_HOME}/jre/lib/rt.ja にパスを通す
  • FXMLを相対パスで指定する場合のベースディレクトリはJavaの起動ディレクトリ。リソースファイルとかと同じ。
  • "Control"って名前のクラスにしてしまっているけど、Oracleの名づけ的にはControllerですよ。
今までは、BloggerにGoogleのprettyprint.jsを入れて、preタグの特定クラスにマークアップさせていたが、 gistの方が手っ取り早い。 資産としてBloggerに依存しないし、訂正が楽なのもよい。ので、しばらくはgistを使っていってみる。

2012/07/08

jQuery MobileでGoogleMaps使う際の覚書(地図API動的ロードと地図サイズ最大化)

ライブラリ類のバージョン

  • jQuery 1.7.2
  • jQuery Mobile 1.1.0
  • Google Maps API V3 (3.8)

覚書1: Google Maps APIの動的ロード

htmlのどこいらかで、jsapiを読み込んでおく。
<div id="scriptArea">
  <script type="text/javascript" src="http://www.google.com/jsapi"></script>
</div>
地図を読み込む局面で、jspai経由でgoogle Maps API読み込みを行う。
// Maps API読み込み状態を管理するdeferredオブジェクトを作っておく。
_maps_loaded: $.Deferred()
// 地図の読み込み終了直後に行う初期化処理を登録しておく。
this._maps_loaded.done(this.initialize_map);

// 読み込み開始、完了時にDeferredを完了状態にする。
google.load('maps', '3', {
 other_params: 'sensor=false',
 callback: function(){
     that._maps_loaded.resolve();
}});

覚書2: 地図を画面いっぱいに広げる

jQuery Mobileだと地図用のdivのwidth,heightを100%にしても広がらない模様。
$('#map_canvas').css('width', $(document).width());
$('#map_canvas').css('height', $(document).height());

// ↓は実機では未検証。
// 画面回転についていくなら、orientationchangeメソッドについていけばよい(はず)。
$(window).on('orientationchange',function(e){
});




下はテスト書きした全文。適当なオブジェクトに作り始めたけど、クラス化するか、jQuery MobileのWidget化するか、かな。
var store_map_page = {
    _maps_loaded: $.Deferred(), 
    _map_options: {},
    geos: {},
        
    map_obj: {},
    
    map_info_window: {},

    _lazy_loaded: function(){
     this.geos = {
         station: new google.maps.LatLng(34.810538,135.494923),
         yamada: new google.maps.LatLng(34.812141,135.494709),
         oasis: new google.maps.LatLng(34.811155,135.494473)
     };
     var map_options = {
         zoom: 17,
         center: this.geos['station'],
         mapTypeId: google.maps.MapTypeId.ROADMAP
     };
     this.map_obj = new google.maps.Map(document.getElementById('store_map_canvas'), map_options);
     this.map_info_window = new google.maps.InfoWindow(this.map_obj);
     _map_options = map_options;
    },

    _initialize: function (){
     var that = this;
     this._maps_loaded.done(this.map_resize, this._lazy_loaded);
     google.load('maps', '3', {
      other_params: 'sensor=false',
      callback: function(){
          that._maps_loaded.resolve();
     }});
    },

    map_resize: function(){
     $('#store_map_canvas').css('width', $(document).width());
     $('#store_map_canvas').css('height', $(document).height());
    },

    orientation_changed: function(e){
     this.map_resize();
     if(e.orientation =='portrait'){
     } else {
     
     }
    }
};

$('body').on('pageshow', function(){
   store_map_page._initialize.apply(store_map_page);
      });

$(window).on('orientationchange',function(e){
   store_map_page.orientation_changed.call(store_map_page, e);
});

$(window).resize(store_map_page.map_resize);

2012/04/04

JavaScriptオブジェクト⇔JSON文字列の変換処理時間

JavaScriptオブジェクトをJSON文字列にシリアライズ、 逆にJSON文字列からJSONオブジェクトにデシリアライズするのにかかる時間の計測結果。 オブジェクトのネストはなく、型はStringのみで、かつ一回の集計のみと、 まともな計測データの体はなしていない。 Webサービスを作るときに、やり取りするJSONのサイズにかかる ブラウザの計算量負荷を考えるにあたって、大雑把にスケールをつかんでみようかという目的で計測。

環境

  • OS: Windows7 64bit
  • CPU: Core i5 650 (3.2 [GHz])
  • RAM: 12 [GB]
  • Chrome: 17.0.963.83 m
  • IE8(64bit): 8.0.7601.17514
  • jQuery: 1.7.2.min
  • jQuery.json: 2.3.min

動作

  1. Stringの配列を作成する。配列の長さは m であり、それぞれ n 文字のアルファベットからなる文字列がセットされている、
  2. 1.で作成したStringの配列をJSON文字列に変換する。JSON.stringify or jQuery.toJSONメソッドを用いる。
  3. 2.で作成したJSON文字列を、JavaScript文字列に変換する。JSON.parse or jQuery.parseJSONメソッドを用いる。
上記の3, 4の時間を計測する。 変数の値域は下記のとおり。
  • n = 1, 2, 3, ... 10
  • m = 20, 21, 22, ..., 219

結果

各シートの記述内容
  • Chrome: 17.0.963.83 m(JSON) JSON.parse, JSON.stringifyを使用
  • Chrome: 17.0.963.83 m(jQuery)  $.parseJSON, $.toJSONを使用
  • IE8_64:8.0.7601.17514(jQuery)  $.parseJSON, $.toJSONを使用
IEが思ったより時間かかりすぎて、グラフを起こす気力がない。 10文字程度のID文字列を複数件やり取りするとして、 レスポンスを5秒以下に抑えようとすると、 IEだと4万件以下、Chromeだと27,8万件以下に抑えないとまず無理なのかもしれんなー。 まぁそんだけの量をHTTPで一度に送受信ってのもちょっと考えづらいか。

テストコード


$(function(){
        function TestCondition(recordLength, recordNumber){
            this.isCalculated = false;
            this.recordLength = recordLength;
            this.recordNumber = recordNumber;
            this.spentTime = {
                constructJsObject: 0,
                serialize: 0,
                deserialize: 0
            };
        }

        TestCondition.prototype = {
            execute: function(){
                var recordString = "";
                for(var i=0; i<this.recordLength; i++){
                    recordString += "X";
                }

                var rawJsObject = {};

                var startTime = new Date();
                for(var i=0; i<this.recordNumber; i++){
                    rawJsObject[i] = new String(recordString);
                }
                this.spentTime.constructJsObject = new Date() - startTime;

                startTime = new Date();
                var serialized = $.toJSON(rawJsObject, null)
                this.spentTime.serialize = new Date() - startTime;

                startTime = new Date();
                var deserialized = $.parseJSON(serialized);
                var deserialize = new Date() - startTime;
                this.spentTime.deserialize = new Date() - startTime;

                this.isCalculated = true;
            },

            writeResult: function(){
                var resultTable = $('#resultTable');
                var resultRecord = $('<tr></tr>');
                resultRecord.append('<td>' + this.recordLength + '</td>');
                resultRecord.append('<td>' + this.recordNumber + '</td>');
                resultRecord.append('<td>' + this.spentTime.constructJsObject + '</td>');
                resultRecord.append('<td>' + this.spentTime.serialize + '</td>');
                resultRecord.append('<td>' + this.spentTime.deserialize + '</td>');
                resultTable.append(resultRecord);
            }
        };

        for(var i=1; i<11; i++){
            for(var j=0; j<20; j++){
                var test = new TestCondition(i, Math.pow(2, j));
                test.execute();
                test.writeResult();
            }
        }

   });

JSON文字列変換後の文字長ぐらい、計算出しておけばよかった。

2012/04/02

svn:externalsをファイル単位・フォルダ単位で設定する

Subversion(ver.1.6以上)であるディレクトリ内に別のディレクトリの内容をミラーリングする、
もしくは特定のファイルをミラーリングするために、svn:externalsを使う。

たとえば、

Subversionのリポジトリ上で複数のプロジェクトを管理している。
後発のプロジェクトBが、先発のプロジェクトAと同一のリソースを常に配置したい。
そしてそのリソースはどちらのプロジェクトでも更新するし、
その反映は常に両方のプロジェクトに対して行われる。

というような状態を作りたい場合。
(そんなシチュエーション、開発の初期フェーズしか通用しないと思うけど。)

ディレクトリの参照設定


[例]

http://localhost/svn/projA/resources

を常にprojBからも参照する。

http://localhost/svn/projB/resources


#参照設定 作成
~projB$ svn propset svn:externals 'resources http://localhost/svn/projA/resources' .
property 'svn:externals' set on '.'
~projB$ svn up
Fetching external item into 'resources'
A    foo
A    bar
Updated external to revision 2.
#参照設定 削除
~projB$ svn propdel svn:externals ./resources

特定の1ファイルの参照設定

※ Subversion 1.6以降に限る。

※ 参照関係を張ることができるのは、同一リポジトリ同士に限る

subversion.apache.org subversion1.6のチェンジログ中、svn:externalsについて記述した項。

svn:forum "svn:externals" 他リポジトリへのファイル参照設定できないんだけど、というフォーラム記事。


[例]

/repo/trunk/libA/resources/shared_file.txt

を

/repo/trunk/libB/resources/

にから参照設定する。


libB/resources$ svn propset svn:externals '^/repo/trunk/libA/resources/shared_file.txt shared_copy.txt' .
libB/resources$ svn up
libB/resources/shared_copy.txtを編集してコミットすれば、libA/resources/shared_file.txt更新時に反映される。

逆に、libA/resrouces/shared_file.txtを編集してコミットすれば、libB/resources/shared_copy.txt更新により反映される。

2012/03/22

[jQuery]テキストボックスへの「文字入力」の検知

  1. changeイベントを拾う…文字入力ではなくテキストボックスの入力終了でファイアするイベント。ざっくり表現すると、フォーカスアウト時。
  2. キー入力イベント(keypress, keyup, keydown)を拾う…キーボード押下時にファイアするイベント。テキストボックスに文字が入る前を取れる。
後者は、ブラウザ間の差が激しい。差については、下記が詳しい。
JavaScript Madness: Keyboard Events
キーボードからの、タブやカーソル移動、消去などを除いた「文字入力」だけを拾う手段として 下記の形で書いてみた。 ただし、ペーストや日本語変換入力などは検知できない。
// keypressイベントで発火させた後のコード
// @param event {Object} eventObject
// @return {Boolean} true:「文字入力」は行われていない、false:「文字入力」が行われた。


// キーコードの取得
var code = event.which ? event.which : event.keyCode ? event.keyCode : event.charCode ? event.charCode : 0 ;
//
if( (navigator.userAgent.indexOf('Gecko')) || (navigator.userAgent.indexOf('Presto')) ){
    // Firefox and Opera send a code of special key whe user press it.
    // below statements avoid prevented some codes sended.(arrows, delete, home, end, backspace, tab)
    if( (code==37) || (code==38) ||(code==39) ||(code==40) ||(code==46) ||(code==36) ||(code==35) ||(code==8) ||(code==9) ){
      return true;
    }
}
if( (!code) || (code < 32)) ) {
  event.preventDefault();
  return false;
}

日本語変換を検知するのは無理か。 Enter確定やスペース確定を拾うとそれっぽい気がするしたけど でも、普通目的のEnterと変換のためのEnterを分離しきれる気がしない。 あと、日本語IMEをデフォルトから変更されたりしたらお手上げじゃない?

ペーストについては、pasteイベント拾いそうなものだが、 こいつは入力確定前でかつ、何が入力されようとしているかは検知できない。 なにやら、Flashを埋め込んで連携することで可能になるようだが。 まぁ、ブラウザでWeb閲覧するごときでクリップボードの内容なんか引っこ抜かれちゃ困る。 世の中に何人かはパスワード入力でコピペってる人がいるんじゃない?

理想的には、「ペースト操作が完了してブラウザが文字列受取」 ~ 「文字列をテキストボックスに描画」の間がとれればと思うけど、 それが可能な仕組みになってるのかどうかすらわからん。

2012/03/20

[jQuery.inplim]inputの入力文字制限

入力文字種制限jQueryプラグインを作りかけている。 日本語やその他2ストローク入力言語に対応できればなーと思っているけど、 発生させるキーコードのブラウザ間の違いがあるので、そもそもに原理的に不可能なのか? と思いつつ、(Windows IMEで言うところの)直接入力だけ作成。
github:jquery.inplim.js
引数の名前やら中の制御やらについては、いろいろ潜んでいるので余暇でメンテしていきたい。 なんたってテストコードが入ってない体たらく。 jQueryプラグイン作成、githubの使用、gitなど慣れないもの満載だったので、徐々に覚えていきたいところ。
$('#numeric').inplim({regexStr:'[0-9]', jp:true});
$('#alphabet').inplim({regexStr:'[a-zA-Z]', jp:true});
$('#alphanumeric').inplim({regexStr:'[a-zA-Z0-9]', jp:true});
$('#mail').inplim({regexStr:'[a-zA-Z0-9-_\.@]', jp:true});