タグ

ブックマーク / reinyannyan.hatenadiary.org (18)

  • 継続渡しによる停止・再開可能な反復処理 - JavaScriptライブラリでお馴染みの$関数を関数スタイルで実装してみる

    ここ最近の Scheme プログラミングで得た感覚を踏まえ、各種 JavaScript ライブラリでお馴染みの $ 関数 (ID による要素検索) を、ごく簡易にですが、関数スタイルで実装してみました。 まずは実装を見ていただく前に、このような例を考えてみてください。 $("id").do_something(); ここで、"id" 要素が確実に見つかるかどうかが保証されていない (do_something が失敗するかもしれない) とします。すると、 var o = $("id"); if (o) { o.do_something(); } のように、いちいちテストをしなければいけませんよね。 これが、関数スタイルでは $("id", do_something); と書くだけで済みます。つまり、$ 関数自身が成否のチェックを行い、成功していればコールバック関数にオブジェクトを渡すように設

    継続渡しによる停止・再開可能な反復処理 - JavaScriptライブラリでお馴染みの$関数を関数スタイルで実装してみる
  • livedoor Reader と livedoor clip の連携機能について - (new Hatena).blog()

    コメント欄が無いようなので…。 確かにクリップとして残しておけるのは便利なんだけれど、「あとで読む」は読んだ後に削除する場合が多いので、「Shift + c」した画面から削除できるといいなー、と思ったり。 ソースを読んだだけですが、出来ますよ。Del キーを押してください。 いちおう以下にまとめておきます: C: クリップ画面のトグル >: 過去ページを表示 <: 新しいページを表示 j / down: 次記事をフォーカス k / up: 前の記事をフォーカス v: 現在記事を開く o: 選択記事を開く t: タグを追加 T: タグを削除 S: 公開・非公開設定をトグル p / space: 選択 (ピンを立てる) shift+space: 範囲選択 (最後に選択した記事と現在記事の範囲を選択) shift+down / J: 現在記事を選択し、次の記事をフォーカス shift+up /

    livedoor Reader と livedoor clip の連携機能について - (new Hatena).blog()
  • Scheme 的多値の実装 - (new Hatena).blog()

    擬似的なものですが、Scheme の多値の受け渡しの仕組みを実装してみました。このようなものです: call_with_values( function(){ values(1, 2, 3) }, function(a, b, c){ // a == 1, b == 2, c == 3 } );call_with_values の第一引数は多値を返す関数で、第二引数はそれを受け取る関数です。 多値と言っても JavaScript ですのでただの配列なんですが、それを関数に渡す際にばらしてやることで、擬似的に多値を実現することが出来るわけです。 実装はこんな感じです: function values() { return list_tail(arguments, 0); // Or, return Array.prototype.slice.call(arguments); } functi

    Scheme 的多値の実装 - (new Hatena).blog()
  • Array#inject を Scheme 的に -> map 関数の実装 - (new Hatena).blog()

    id:reinyannyan:20061127:p1 で取り上げた SICP の accumulate 関数は、まだ Lisp の肝であるリストが紹介されていない段階のものでした。 2章に入り、リストを用いた、より汎用的な実装が示されていますので、前回のアップデートも兼ねて見ておきたいと思います。 // 再帰版 function accumulate(op, initial, lst) { return nullp(lst) ? initial : op(car(lst), accumulate(op, initial, cdr(lst))); }// 反復版 function accumulate(op, initial, lst) { function iter(result, lst) { return nullp(lst) ? result : iter(op(car(lst),

    Array#inject を Scheme 的に -> map 関数の実装 - (new Hatena).blog()
  • Range#inject を Scheme 的に -> 積分への応用 - (new Hatena).blog()

    SICP を読んでいます (まだ 1 章の高階関数のところです)。 練習問題で Smalltalk や Ruby (や prototype.js) の inject メソッドと同等のものが出てきましたので、ピックアップしてみたいと思います。 以下の様な、a から b までの範囲の数列の総和・総乗などの計算式を、高階関数を使って一般化する、という課題です。 function sum(a, b) { return a > b ? 0 : a + sum(a + 1, b); } sum(1, 10); // -> 55 function product(a, b) { return a > b ? 1 : a * product(a + 1, b); } product(1, 10); // -> 3628800上の 2 例を見比べると、形としては全く同じ式であることが分かります。ということで

    Range#inject を Scheme 的に -> 積分への応用 - (new Hatena).blog()
  • アクセサ関数 - (new Hatena).blog()

    同じオブジェクトの同じ要素に何度もアクセスするような場合に便利かなと思って、作ってみました。 function accessor(object, key, initial) { if (arguments.length == 3) object[key] = initial; return function() { return (object[key] = arguments.length ? arguments[0] : object[key]); }; }Synopsis: var object = { key: 0 }; var key = accessor(object, "key"); key(1); key(); // -> 1object は無名の連想配列なんかでも OK ですね。 とりあえず、こんな感じで使っています:

    アクセサ関数 - (new Hatena).blog()
  • Conway's Game of Life - (new Hatena).blog()

    via CodeGolf Game of Life という有名なゲームがあることは辛うじて知っていたんですが、実装については全く分からずにいました。 個人的にこの手のクイズは大の苦手で、まともに解いたことが無いという悔しさと、「生命」というテーマが面白そうだったこともあり、挑戦してみました。 ゲームの詳細は wikipedia 記事を参照していただくとして、ルールのみ引用しておきます。 http://en.wikipedia.org/wiki/Conway%27s_game_of_life Any live cell with fewer than two neighbours dies, as if by loneliness. Any live cell with more than three neighbours dies, as if by overcrowding. Any l

    Conway's Game of Life - (new Hatena).blog()
    tsukkee
    tsukkee 2008/10/10
    ライフゲームをJavaScriptで
  • LDR のクロール頻度が低い?件について - (new Hatena).blog()

    以前から指摘されていることだと思うんですが、LDR ではフィードの更新が反映されるのが結構遅い場合がありますよね? 例えば、久しぶりに更新があったと思ったら一週間も前の記事だったり、といったことが割とよくある気がするんです。 そこで、「更新日時の古いもの」など任意の条件でフィードを抽出し、バックグラウンドで ping を打つ、ということを考えてみました。 まず、条件に合致するフィードを抽出する関数を作ります (LDR の Subscribe.Controller#update をベースにしています): function _filter_all_subs(params) { State.subs_loader && State.subs_loader.cancel(); var list = []; var limit = 200; var count = 0; var canceled =

    LDR のクロール頻度が低い?件について - (new Hatena).blog()
  • (new Hatena).blog() - livedoor Reader でフィード一覧を絞り込み表示

    [20070223] 再アップデート版をファイルとして公開しました。id:reinyannyan:20070223:p1 をご覧下さい。 id:reinyannyan:20061006:p1 で実験的に作ったフィード一覧絞込みスクリプトを改善しました。フォルダ単位でのフィルタリングの他に、任意の JavaScript 式を条件として与えられるようになっています。また、"!" 以外にも !+ !- !# のコマンドを追加しました。 未読フィードが大量にある時に、今読みたいものを確実に効率よく読めるように、と考えて作りました。 特に、フィード一覧の表示数の上限を設定していて、未読フィードがそれよりもたくさん存在する場合に、絞込みを行うことで望みのフィードを漏れなく表示することが (ほぼ確実に) 可能になります。 使用例: :! +news +tech [CR] // フォルダ "news" と

    (new Hatena).blog() - livedoor Reader でフィード一覧を絞り込み表示
  • livedoor Reader のテンプレートをカスタマイズ - (new Hatena).blog()

    LDR では、フィード一覧や記事など、あらゆるデータの表示が JavaScript+HTML のテンプレート・システムによって行われます。 この HTML 側のテンプレートを変更することで、表示を自在にカスタマイズすることが可能になります。 全てのテンプレートは TEXTAREA 内に文字列として格納されています。 単純な変更であれば $("TEMPLATE_ID").innerHTML = $("TEMPLATE_ID").innerHTML.replace(search, replace);のようにすれば良いんですが、一からセットし直す場合は、"<" ">" 等の特殊文字をエスケープする必要があります: $("TEMPLATE_ID").innerHTML = 'HTML コード'.escapeHTML(); /* Greasemonkey の場合は * new unsafeWindo

    livedoor Reader のテンプレートをカスタマイズ - (new Hatena).blog()
  • livedoor clip の JSONP API からタグ・クラウドを生成するデモ - (new Hatena).blog()

    id:secondlife さんの AsyncJSONP (参照: MochiKit で JSONP の利用) を使って、MochiKit の勉強がてら作ってみました。 livedoor clip の JSONP API を利用してタグ・クラウドを生成する、というものです。最近どんなキーワードの話題が注目されているかが分かると思います: MochiKit を使ったのは実は今回が始めてなんですが、(昨今の脳トレブームにも通ずるような) 頭脳を刺激されるような感じがして、とても楽しいです。 OO 言語等との語順の違いとか、高階関数の利用が必然的に求められる点など、個人的に普段使わない頭の使い方をさせられるためなんでしょうね。 とりわけイテレータ関数の利用において、できるだけ中間の変数を作らず関数の組み合わせだけで処理する、というあたりが頭の使いどころになってくるようです。 例: // ふつうの

    livedoor clip の JSONP API からタグ・クラウドを生成するデモ - (new Hatena).blog()
  • LDR で記事データを動的に加工する -> 全文取得への応用 - (new Hatena).blog()

    これまで、イベント・フックを使ってフィード表示を制御する方法について何度か考えてきました: livedoor Reader で記事のリンク先を書き換える livedoor Reader で特定のサイトや記事の文を非表示にする 今回も同様の主旨なんですが、テンプレート・クラス (/js/template.VERSION.js にあります。toString の使い方など、非常に勉強になります) を読んでいて、これまでと違う手法に気付いたのでご紹介したいと思います。 来、フィード記事は以下の様な構造になっており: { "items": [ { "enclosure": null, "link": "http://hatena.g.hatena.ne.jp/hatenarss/20060823/1156305225", "enclosure_type": null, "author": "ha

    LDR で記事データを動的に加工する -> 全文取得への応用 - (new Hatena).blog()
  • for ループ以外での in の利用 - (new Hatena).blog()

    MochiKit で if (uri in allScripts) {みたいなテストの仕方を見て、最初意味が分かりませんでした。 そこで、まさかと思いながらも試しに alert("close" in window);としてみると、true が表示されました。 う〜ん、便利ですね。 てっきり in はオブジェクトのキーに一つひとつアクセスするためのものだと思っていたので、「キーを含んでいるかどうか」のテストに使えるとは全然知りませんでした。 有名なんでしょうか?

    for ループ以外での in の利用 - (new Hatena).blog()
  • escapeHTML の実装 3 パターン (ベンチマーク付き) - (new Hatena).blog()

    ウェブを扱うライブラリやプログラムで必ずと言って良いほど見かけるものに、escapeHTML という関数があります。 "&" 等、特別な意味を持つ文字を、表示等のために実体参照 (&amp;) に変換するお決まりの関数なんですが、実装には色々とバリエーションがあるものです。 1. String#replace メソッドを繰り返す (MochiKit 等) function escapeHTML(str) { return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); }このパターンが最も多く見受けられます。Ruby でも同様に gsub を繰り返す方式を見かけることがあります (例: RSS::Utils.html_escape)。 2. Str

    escapeHTML の実装 3 パターン (ベンチマーク付き) - (new Hatena).blog()
  • (new Hatena).blog() - livedoor Reader での記事サムネイルの表示をサーバーに優しく (+α)

    最速インターフェース研究会 :: livedoor ReaderにSimpleAPIのサムネイルを加えるGreasemonkeyスクリプト に関して、何十もある記事のサムネイルを一気に取得しようとする (可能性がある) のはちょっとマズいのではと思い、改善策を考えてみました。 キューを使うのが良いんじゃないでしょうか?: (function() {with(unsafeWindow){ /* 自分用 (IE 用) に書いたものに with(unsafeWindow) を被せただけです。 * Firefox では未テスト。コマンド等省略 */ var SimpleAPI = Class.create().extend({ initialize: function(feed) { this.feed = feed; }, add_thumbs: function() { var self =

    (new Hatena).blog() - livedoor Reader での記事サムネイルの表示をサーバーに優しく (+α)
    tsukkee
    tsukkee 2008/10/10
    まだ理解できない
  • livedoor Reader で irb (インタラクティブ ruby) - (new Hatena).blog()

    RedHanded 経由で irb のリモート版があるのを知り、早速作ってみました。LDR 上で :ruby 10.times { print "ho! " }なことができます。 また、セッションが維持されますので、前に定義した変数等を参照することも出来ます。 つまり、irb そのものです。 手元に ruby が無い 手元に計算機が無い ruby のお勉強系のブログでその場でお勉強 といった場面での活躍が期待できます。(よね?) ご利用はキーワードの方からどうぞ (user.js ファイルが提供されています)。 一応こちらにも定義部分を再掲しておきます: register_command("irb|ruby", function() { // See: http://redhanded.hobix.com/inspect/rubylessRuby.html var irb = "http:

    livedoor Reader で irb (インタラクティブ ruby) - (new Hatena).blog()
    tsukkee
    tsukkee 2008/10/10
    ldrのふきだしでRuby
  • JavaScript でプロファイリング - (new Hatena).blog()

    追記 [20061103]: ライブラリ非依存なバージョンも書いてみました。id:reinyannyan:20061103:p1 でご覧下さい。 最近自分で書いた JS プログラムが驚くほど重かったので、どこに原因があるか調べたいと思いました。 その方法として、怪しいと思う箇所に (あるいは思わない箇所にも) 手作業でタイマーを仕掛けて、部分部分の実行時間を計測するのも手だと思うんですが、クラスのどのメソッドでどのくらい時間が掛かっているのかが自動的に分かる、というのが理想的かなと思いました。 (以下、prototype.js 的な (OO 的な) コーディングを対象とした話になります) まず思いついたのは、プロファイルしたいクラス (function オブジェクト) を受け取って、メソッドを動的に書き換えるという方法です: for (var m in klass.prototype) {

    JavaScript でプロファイリング - (new Hatena).blog()
    tsukkee
    tsukkee 2008/10/10
    各関数での実行時間を計測したりする
  • galgalgal - (new Hatena).blog()

    Greasemonkey スクリプトで日語の文字列を埋め込む時、私は vim の "ga" というコマンドを使います。これは、例えば「日」という文字上で実行すると以下のようなメッセージを出力してくれるものです: <日> 26085, Hex 65e5, Octal 62745この Hex の値を抜き出して "\u" をくっつけると Unicode エスケープされた文字列の出来上がりです。 ただ、一文字ずつ手作業で書き留めていくのは面倒極まりないので、ちょっと工夫をします。 :redir @aこうすると、表示されるメッセージが "@" の後の名前のレジスタ (名前付き記憶領域) に転送 (redirect) されていきます。 これを利用して、変換したい文字列上を "galgalgal..." と一気に滑らせていくと ("l" はカーソル右移動です) :put aで全部のメッセージを取り出す

    galgalgal - (new Hatena).blog()
    tsukkee
    tsukkee 2008/10/10
    Unicodeを取得する方法
  • 1