JavaScript で FizzBuzz
なんか流行っているみたいだったし、思いついたから。
何番煎じかは不明。
#!/usr/bin/env node var a = ['FizzBuzz', null, null, 'Fizz', null, 'Buzz', 'Fizz', null, null, 'Fizz', 'Buzz', null, 'Fizz', null, null]; for(var i = 1; i <= 100; i++) console.log(a[i % 15] || i);
enchant.jsのクソな部分
enchant.js、いいライブラリなんだけど「これってどうなの?」って思うところもあって、それを箇条書きにしていく。
- リポジトリ
- ブランチに master と develop と develop-env と v0.5.0 がある
- たぶん新機能は develop で開発するんだろうけど、 master にも色々コミットされていたりする
- pull-request はどのブランチにすればいいの
- どうして v0.4.4 とかはタグで管理してるのに v0.5.0 はブランチなのか
- v0.5.0 ブランチは develop ブランチと何が違うのか
- git-flow とか参考にすればいいと思う
- ブランチに master と develop と develop-env と v0.5.0 がある
- コーディング規約
- 場所によって書き方が違ったりする
- if 文の { の前にスペースを入れるか、とか
- ひどい所だとインデントでスペースとタブが混ざってたりする
- 関係ないけれど、コード書くエディタはホワイトスペースと全角スペースとタブを区別できないとダメだと思う
- 場所によって書き方が違ったりする
- テスト
- tests ディレクトリに少ししかない
- ブラウザごとの違いとかバグとか
- DOMのバグとか意識して書かないといけない
- DOM じゃなくて Canvas でレンダリングすれば改善するんじゃないかと思う
- v0.5.1 で DOM と Cavnas 切り替えられるらしいからそれまで待てばいいのかな
- dev/enchant.js
- サイズが大きすぎる
- 読むときスクロールが大変
- jQuery みたいにファイルを分割すればいいのに
- どうせ rake コマンド使うんだし
- サイズが大きすぎる
- スパゲッティ
- ひとつのメソッドが30行超えているのは、よくないと思う
- asset 関係のメソッド追うのに一苦労
- プログラマにソースのよくからまったスパゲッティを見せると死ぬ
- 死なない
- ひとつのメソッドが30行超えているのは、よくないと思う
- rotate() とか scale()
- なんで Entity じゃなくて Sprite のメソッドなの
- transform-origin の指定がやりにくくて不便
- 拡大しても当たり判定はそのままなのが少し面倒くさい
- addEventListener()
- 長い
- どうして addListener() とか on() とかにしなかったの
- DOM に合わせたんだろうけど、そんな必要なかった
- Sound
- クソ
- うんち
Homebrew で何かインストールするとき "Permission denied" と言われたときの対処法
未来の自分の為に書き残しておく。
今日Macで
brew upgrade
したら、coreutils のインストール中に "Permission denied" と出て終わってしまった。
それなら、と
sudo brew upgrade
したら、今度は "Cowardly refusing" と言われて実行すらされない。
調べたら同じ状態になった人がいたみたいだ。
https://github.com/mxcl/homebrew/issues/12297
この人は lame で止まったみたい。
解答されているように
sudo chown -R $USER /usr/local
と権限を治して、事無きを得た。
もしかしたら、ディスクユーティリティで権限の修復をしても治ったのかもしれない。ディスクユーティリティで権限の修復ではダメなようです
最初 coreutils の問題だと思って、数時間はまってしまった。
wise9に記事を投稿して、それが掲載されました
wise9 › ダンジョンマップを生成するアルゴリズムの解説[投稿記事]
ざっくりと自分が何をやったのか、書き残しておきます。
まず、原稿をGoogle Docsで書きました。
図を描いて挿入する機能があるので便利です。
書いたら、HTML(と画像をまとめたZIP)としてダウンロードしました。
(ついでに、マルチバイト文字がすべてエスケープされていて、悲惨なHTMLだったのを直しました)
このページに書かれているアドレス宛に必要事項を書いて、HTMLと画像をまとめたZIPを添付してメールしました。
簡単なので、みんな記事を書いて投稿すればいいと思います。
JavaScriptで関数を非同期呼び出しする
よくあるパターン。
setTimeout(function(){ // 非同期でしたい処理 }, 0);
これ結構パフォーマンス悪いみたい。
node.jsの場合
process.nextTick(function(){ // 非同期でしたい処理 });
それ以外のブラウザ
MessageChannel を使うのがいいっぽい。
var ch = new MessageChannel(); ch.port1.onmessage = function(){ // 非同期でしたい処理 }; ch.port2.postMessage(0);
まとめ
だいたいこんな感じ。
uncurryThis はこの記事で知りました。
var asyncCall = function(){ var _slice = Array.prototype.slice; var _bind = Function.prototype.bind || function(thisObject){ var callee = this; var args = _slice.call(arguments, 1); return function(){ var a = _slice.call(arguments); return callee.apply(thisObject, args.concat(a)); }; }; var uncurryThis = _bind.call(_bind, Function.prototype.call); var slice = uncurryThis(_slice), bind = uncurryThis(_bind), apply = uncurryThis(Function.prototype.apply); return typeof process !== 'undefined'? function(){ var args = slice(arguments); process.nextTick(apply(bind, null, args)); }: typeof setImmediate === 'function'? function(){ var args = slice(arguments); setImmediate(apply(bind, null, args)); }: typeof MessageChannel === 'function'? function(){ var ch = new MessageChannel(), queue = []; ch.port1.onmessage = function(){ queue.shift()(); }; return function(){ var args = slice(arguments); queue.push(apply(bind, null, args)); ch.port2.postMessage(0); }; }(): function(){ var args = slice(arguments); setTimeout(apply(bind, null, args), 0); }; }();
第1引数に非同期で呼び出したい関数、第2引数にthisになるオブジェクト、第3引数以降に引数を指定する。
asyncCall(function(a, b, c){ this.valueOf(); // 0 a; // 1 b; // 2 c; // 3 }, 0, 1, 2, 3);
のように使える。
SConsでJavascriptを組み立てる
JavaScriptでも一定以上の規模のプログラムは、
機能ごとにファイルを分けたほうがいいと思います。
jQueryでもそうですし。
そんなわけで「分割したファイルをひとつにする方法」を簡単にメモしておきます。
Python が好きなので make じゃなくて SCons を使います。
Python の機能を使って色々できるところが make より嬉しいです。
事前準備
簡単なSConsの使い方
プロジェクトのフォルダに SConstruct という名前のファイルを作成して
どういう処理をするか書いていきます。
Command('target.js', ['source1.js', 'source2.js'], 'cat $SOURCES > $TARGET')
と書いて
cd path/to/project/folder
scons
ってやると source1.js と source2.js をくっつけた target.js が作られます。
二回目以降は source1.js か source2.js が変更された時だけ実行されます。
cat とかのコマンドがわからない人は調べてください。
応用
スクリプト全体を匿名関数で囲いたい場合
Command('target.js', ['source1.js', 'source'], [ 'echo "(function(){" > $TARGET', 'cat $SOURCES >> $TARGET', 'echo "})();" >> $TARGET' ])
echo で前後に書き加えているだけです。
Closure Compilerを使いたい場合
Command('target.js', 'source.js', 'java -jar compiler.jar --js $SOURCE --js_output_file $TARGET')
compiler.jarを事前に用意しておく必要があります。
複数のファイルをコンパイルするときはちょっと工夫する必要があります。
まとめ
ファイル分割すると見通しがよくなるし、なにかと便利です。
単体テストもやりやすくなります、たぶん。
はやりの CoffeeScript のコンパイルにも使えるはずです。
話題のソートアルゴリズム「sleep sort」をJavascriptで実装したよ
「sleep sort」については以下のリンクを見てもらうとして
4chan BBS - Genius sorting algorithm: Sleep sort常識を覆すソートアルゴリズム!その名も"sleep sort"! - Islands in the byte streamはてなブログBig Sky :: Sleep sort in Go
まず本題のコード
function sleepSort(array, callback, f){ var l = array.length, result = []; var i = l; if(f == null) f = Number; while(i--) (function(value){ setTimeout(function(){ result.push(value); if(--l === 0) callback(result); }, f(value)); })(array[i]); }
arrayにソートしたい配列、
callbackにコールバック関数、
fに配列の値を数値に変換する関数(省略可)
をそれぞれ指定するとcallbackにソートされた結果が渡されます。
値が負だったり実数だったりすると、
ちょっと工夫しないと使えません。
勢いで書いたコードなので、
whileの中で匿名関数使っているなどの問題もあります。
そもそも、このアルゴリズムに使いどころがあるのか疑問ですが。
最後にサンプル
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> function sleepSort(array, callback, f){ var l = array.length, result = []; var i = l; if(f == null) f = Number; while(i--) (function(value){ setTimeout(function(){ result.push(value); if(--l === 0) callback(result); }, f(value)); })(array[i]); } window.onload = function(){ function randint(){ // ランダムな256未満の整数 return Math.random() * 256 | 0; } var array = [], i = 100; // ランダムな整数100個の配列を作る while(i--) array.push(randint()); // もとの配列を表示 (before : 〜) document.getElementById('array').textContent = JSON.stringify(array, null, 4); // ソート sleepSort(array, function(result){ // 結果を表示 (after : 〜) document.getElementById('result').textContent = JSON.stringify(result, null, 4); }); }; </script> <style> div { margin: 1em 0 } #array::before { content: 'before :' } #result::before { content: 'after :' } </style> </head> <body> <div id="array"></div> <div id="result"></div> </body> </html>
ここまで30分で書けたあたりが、
このアルゴリズムのすごいところかも。