Scalaはじめました

posted by cheesepie on 2009.08.28, under scala
28th

最初は関数型絶対肌に合わんと思ってたけど、触ってみると
以外といけそうな気がしてきたので、Scalaの勉強始めます。

いや、言語としては相当いい感じですよね。
Javaの静的なところとRubyのキレイに書けるところを上手く
合わせたみたいな。

ということで、事始めに文法注意書きメモ。

valとvar
再代入できる変数はvar、再代入できないのがval
関数型指向でいくなら、varを使わないような記述を心がける
staticな関数作りたい時
クラスは静的メンバを持てないので、代わりにobjectを使って実装する
リストとタプル
共にイミュータブルだけど、違う型の値を持てるのがタプル。
リストに「::」で値を追加する際、最後にNilを追加するのが何か慣れない

しばらくは言語自体の勉強して、それから何かアプリを作っていこう。GAEでも動くみたいですし。

FirefoxでAjax中にF5押したとき

posted by cheesepie on 2009.08.07, under javascript
07th

Ajaxでのコンテンツ取得に時間がかかっている時に、画面をreloadすると、Firefoxだけreload後にエラー処理が実行された。

例えば、ブラウザ側では

$.ajax( {
  type: "get",
  url: "test.php",
  data: queryString,
  success: function(msg){
    alert( "Success! " + msg );
  },
  error: function( msg ) {
    alert( "Error! " + msg );
  }
} );

で、サーバ側では時間がかかるようにsleep(10)とかしといて、待ってる間にブラウザをreloadしてみます。
すると、XHRがabortされずにエラーハンドラが実行されちゃう。

エラーハンドラが実行されてしまうのは、リロードされるタイミングでreadyStateは4なのに、statusが0(ってか空っぽ)が返ってきて、エラー処理まで到達してしまうからなんだけど、XHRってreload関係なく引き継がれるのか。。。
IEとSafariはよしなにabortしてくれてるみたい。

Firefoxで”readyState”が4なのに”status”が0ってのは仕様らしくて、その場合”responseText”があるかどうかでabortするか判定できる。
ちなみにjQueryの$.ajax関数は対応してないorz
そもそも、まだレスポンスが返ってきていないので、readyStateは1を返すべきですが。

でもreloadのケースの場合、reloadされるタイミングでabortしないといけないので、上の対応をしてもどうしようもない。

ということで、MDCを見たら”onBeforeUnload”というドンピシャなイベントを発見。

$( document ).bind( 'beforeUnload', function() {
  xhr.abort();
} );

これでエラーが出なくなりましたー。ヒャッハー!
勉強になりました。

HTML5を勉強していく

posted by cheesepie on 2009.08.05, under html5, javascript
05th

ちょっと早く帰れた日は、HTML5を勉強していくよ!

で、早速Web Workersを触ってみました。

バックグラウンドで処理を実行してくれる上に、マルチスレッドで動いてくれるらしい。しかもマルチコアCPU対応とのこと・・!
これまでのJavaScriptはシングルスレッドなので、setTimeout()使って無理くり並列で処理させていたのが、これでだいぶスッキリできる、、のか?

チュートリアルを参考に、フィボナッチ数列の計算をバックグラウンドで実行してみました。

sample.html内

// workers
var start1 = new Date();
var worker1 = new Worker('job1.js');
worker1.onmessage = function (event) {
  document.getElementById('result1').textContent = (new Date() - start1) + "ms, " + event.data;
};

job1.js

function fib( num ) {
  var list = {};
  var _fib = function( n ) {
    if( list[n] ) return list[n];
    if( n <= 2 ) return 1;
    return list[n] = _fib(n-1) + _fib(n-2);
  }
  for( var i = 1; i <= num; i++ ) {
    postMessage( _fib( i ) );
  }
  return list;
};
fib( 1000 );

おー何か楽しい。

HTMLとWorkerのやりとりはシンプルで、
Workerから postMessageで HTMLに通知を送り、
HTML側ではWorkerインスタンスの onmessage イベントで通知を受け取れます。
逆にHTMLからWorkerに通知を送ることはできないみたい。
(ストップとかできないのかな?調べよう)
また、HTML側で定義した関数や変数はWorker内で利用できないので、Worker内に全て記述する必要があります。

HTMLとWorkerで相互にデータをやりとりする場合は、
HTML側で
・workerをインスタンス化
・何かトリガーになる関数で、worker.postMessage( value )
・workerからの結果受け取りのためのworker.onmessage( event )
Worker側で
・onmessage( event ) 内で、postMessage( result )

みたいにやれば、相互にやりとりが可能です。
実際に使う場合は、ラッパを作ってしっかり汎用化しないとカオスな感じになりそうですが。。。

ちなみに、WebSocketはまだSafari4でもFF3.5でも未実装みたい。

次はShared Workerを見ていくお。

麻疹

posted by cheesepie on 2009.07.09, under development
09th

元記事

むー、パターン厨とjsで名前空間汚さない厨は絶賛かかり中だー。
最近まで3項演算子厨もかかってました。

JSだと、継承する設計でもないのに this.initialize.apply 厨とか、メソッドチェーン厨とか?

1歩づつ前進

posted by cheesepie on 2009.07.01, under javascript
01st

JavaScriptの高速化はドットの数減らしたり、ローカル変数にキャッシュしたり、再描画がなるべく起きないよう気をつけたりと、地道な作業の連続で成果が出るので、疲れます。。。
とりあえずjQueryのeach()は便利なんですけど、for文で回すようにしよう。
とあるプラグインで使われてたeachをforに変えただけで10%速くなってビックリした。

それはそうと、最近Scalaが気になってしょうがない。
チラッとリファレンス見たところ、キレイで読みやすそうな仕様だった。
Scala勉強会したいなー。

CtagsとVimを使ってJavaScriptのコードリーディング

posted by cheesepie on 2009.06.16, under javascript, vim
16th

Macに始めから付属しているctagsは古いので、portでインストール。

$ sudo port install ctags

ナイスなことにExuberant Ctagsも一緒にインストールされたみたい。

で、そのままCtagsにかけると、

function() { ... }

は解析されるけど、

var Klass = function() { ... };
Klass.prototype = {
 init: function() { ... }
}

のような書き方になってると解析されない。

これでは、Jquery等のライブラリが解析できないので、こちらを参考に、~/.ctagsに以下を記述する。

-regex-javascript=/^[ \t]*(['"]?)([A-Za-z0-9_.]+)\1[ \t]*[:=][ \t]*function[ \t]*\(/\2/I,inner/i
--langmap=javascript:.js
--regex-javascript=/^(.*).prototype *= *(.*)/\1/p,prototype/
--regex-javascript=/^[ \t]*(.*) *: *function/\1/m,method/
--regex-javascript=/^[ \t]*(var | *)(.*) *= *{/\2/o,object/

普通にtagファイルを作る。

$ ctags *.js

taglist.vimで表示するために、.vimrcに以下を追記。

let g:tlist_javascript_settings = 'javascript;v:var;c:class;p:prototype;m:method;f:function;o:object'

これでVimでJSファイルを開いて「:Tlist」を打てば、左側に「クラス、メソッド、関数、オブジェクト」の一覧が表示されます。
1000行超えてくるようなソースを追う場合、超便利です。
ま、Eclipseだとプラグイン入れるだけでリスト出してくれますけど。

JavaScriptの継承メモ

posted by cheesepie on 2009.06.16, under javascript
16th

いつも忘れちゃうのでメモ。

function extend( self, other ) {
 for( var property in other ) {
  self[property] = other[property];
 }
 return self;
}

var Klass = function() {
 return function() {
  return this;
 }
};
Klass.create = function() {
 var f = function() {
  this.initialize.apply( this, arguments );
 };
 f.prototype.initialize = function() {};
 f.isClass = true;
 f.extend = function( other ) {
  extend( f.prototype, other );
  return f;
 };
 return f;
};
Klass.extend = function( base_class ) {
 if( base_class.isClass ) {
  var child = Klass.create();
  child.prototype = new base_class;
  return child;
 } else {
  var base = Klass();
  base.prototype = base_class;
  var child = Klass.create();
  child.prototype = new base;
  return child;
 }
};

使い方。

var Foo = Klass.create();
Foo.prototype = {
 initialize: function( name ) {
  this.name = name;
 },
 getName: function() {
  alert( this.name );
 }
};
var Bar = Klass.extend( Foo ).extend( {
 setName: function( name ) {
  this.name = name;
 }
} );

var f = new Foo( "bob" );
var b = new Bar( "john" );
b.setName( "michel" );

f.getName(); // bob
b.getName(); // michel

Lightboxの設計

posted by cheesepie on 2009.06.10, under javascript, jquery
10th

Lightboxを作るにあたって

・1枚レイヤを被せるかどうか(後ろを触らせない)で話が変わる
  被せるならウィンドウの位置は固定でおk。
  被せないなら、後ろを触らせる設計なので、ウィンドウをドラッグ等
  移動できるようにしないとダメ。

・汎用性を持たせるなら、ウィンドウの中身は生のHTMLで受け取った方がいいかも
  JSONで受け取ると、個別にDOM組み立てることに。
  HTMLで受け取ってDOMに追加後、イベント設定する方がいい。
  (テンプレート作ってもいいけど、それだと遅くなるので)

・よくあるロード中のアニメーションGIFを画面中央に配置する場合
  jQueryを使っているなら、

var loading = $( "<div><img src="./loading.gif" /></div>" ).css( {
  position: "absolute",
  top: 0,
  left: 0
} );
$("body").append( loading );

var _win = $(window);
loading.css( {
  top: ( _win - loading.height() ) / 2,
  left: ( _win - loading.width() ) / 2
} );

これだと、画像の読み込み前に位置が設定され、ローディング要素のwidthが0になることがある。
なので、こうする。

loading.load( function() {
  loading.css( {
    top: ( _win - loading.height() ) / 2,
    left: ( _win - loading.width() ) / 2
  } );
} );

これで、要素が読み込まれた後に位置を設定できる。

jQueryでツリービュー作るなら「dynatree」

posted by cheesepie on 2009.06.03, under javascript, jquery
03rd

久々にキャパを超えそうな仕事量にボーッとしかけている今週でございますが、ここを乗り越えればリリースも近づくし、給料にもつながるのではグへヘ。

と真っ黒なやる気で頑張るしかないっ!
とにかくやることが大事なんだやることが大事。

そうそう、jQueryのツリービューでいいのないかなーと思ってプラグインを調査してたんですけど、すごい掘り出し物がありましたよ!
jquery.dynatree.js

新しいし全然知名度も無いっぽいんですが、超高機能で使いやすい。

  • JSONからツリー構築
  • 子階層をAjaxで読み込んで追加できる
  • Cookieで開いた状態を保存
  • 開閉アイコンとノード部のイベント設定が自由自在
  • ツリーにチェックボックスを付けられる
  • しかも、子階層まとめてチェックとかもできる
  • 全てのオプションをJSONにして一括で指定可能
  • スキンが用意されていて、実装とデザインが分離

もはやYUIのツリーに迫る充実ぶり。
JSONで全てのオプションを指定できるのが使いやすいです。
ライセンスもMITライセンスと言うこと無しですね。

単純なツリーならjsTreeなんかで十分かと思いましたが、大規模Webアプリで何か高機能さを求められた場合は、今のところjQueryのプラグインを使うならdynatree一択では・・!
jQueryUIに取り込んでくれたらいいなー。

入れてるVimScriptとか便利設定のメモ

posted by cheesepie on 2009.05.24, under vim
24th

クリーンインストール時に自分用のまとめとして。

・plugin/fuzzyfinder.vim
  バッファエクスプローラー。
  minibufexpl.vim より個人的に好き。

・plugin/opsplorer.vim
  ファイルエクスプローラー。
  ファイルの各種操作がデフォルト1文字入力で出来たり、
  「↑」で親ディレクトリへ移動出来るのが超便利。

・plugin/autocomplpop.vim
  補完候補を自動で絞り込んで表示

・plugin/sudo.vim
  root権限のファイルをうっかり一般ユーザで開いてしまった時用

・plugin/allml.vim
  HTML編集中「Ctrl+x /」で閉じタグを補完

css_color.vim
  CSS内の色指定にその色を付けてくれる。
  ftplugin/css.vim に追記するだけでおk。

・indent/javascript.vim
  クラスベースのJavaScriptでもインデントを付けてくれる

・plugin/scratch.vim
  スクラッチバッファを作成。
  こちらの神記事を参考に、「,s」でJSLintによるJavaScriptの構文チェック結果の
  表示用に主に使う。
  ※SpiderMonkeyのインストールも必要

・syntax/actionscript.vim
  ActionScript3のシンタックスハイライト用

・autoload/actionscriptcomplete.vim
  ActionScript3のOmnicomplete用

pagetop