gem install opencv

投稿者 nanki 2009-03-15 05:28:00 GMT

portなどでopencvを入れて、普通にやるとcxcore.h がないとか文句言われるので、

⿶ sudo gem install opencv -- --with-opencv-include=/opt/local/include/opencv

とやったらいけた。

参考:

opencvのrubyバインディングが入らない - 橋本詳解


Objective-J および cappuccino とそのvim補完

投稿者 nanki 2009-02-05 23:03:00 GMT

vim objj

しばらくはprototype.js や jQuery、時々はExt JS で楽しく遊んでいたけども、デスクトップアプリケーションのような物を作るのには力が不足していると感じていた。(機能が、ではなく、抽象化の程度が)

年初めくらいに cappuccinoというプロジェクトを見つけてきて、しばらくソースを眺めていたりしたのだけど、これはいい。 久々にピリピリ来るプロジェクト。

最近、iPhone SDK などでObjective-Cに触れて、Cocoa APIに慣れ親しんだせいもあるけど、それを差し引いても、よくできている。 興味と暇のある人は是非、調べてみて欲しい。

実際に、Keynote にしか見えないアプリケーション なんかもこれで作られている。

ちょっとソースを見ると、こんな調子だ。

<script type="text/javascript">
    OBJJ_MAIN_FILE = "main.j";
</script>
<script src="Frameworks/Objective-J/Objective-J.js" type="text/javascript"></script>

main.j というのが、Objective-J 言語で書かれていて、Objective-J.js を読み込むと、その場でJavaScriptにコンパイルされる。

元々、Objective-C は、Objective-Cのランタイム(Cの関数)とプリプロセッサだけでこしらえてある(と思う)のだが、その手の抜けた?実装とは裏腹に強力なオブジェクト指向機能を持っている。

今回、Objective-J がその手法をJavaScriptに対して適用したのを見て、この方法の持つシンプルさと力ににやにやせずにはいられない。(JavaScriptにOOを導入するとは!)

でも、Cocoa APIはフルスペリングでAPIが長いのでとても覚えられない。 IDEなどのコード補完機能がないと書く気が起こらない…ということで、vim の補完関数を作った。

github に置いてあるので、使うなり改良するなりしてください。

関係ないけど、Objective-J ではメソッドの定義に型を書くんだけど、コンパイルの時点で廃棄されている。(ので間違っててもコンパイルは通る) しかし、コード補完を作るにあたって、この型情報は非常に役に立った。

参考:

Web用画像処理言語purlにGyazoモジュール追加

投稿者 nanki 2008-10-30 18:11:00 GMT

purl にGyazoモジュールを追加しました。

デフォルト環境にはロードされないので、自分でロードする必要があります。

Purl::Purl.new のあたり。

# app/controllers/purl_controller.rb
class PurlController < ApplicationController
  caches_page :filter

  def filter
    begin
      result = Purl::StackMachine.new(
        params[:commands], Purl::Purl.new{|p| p.load_feature Purl::Features::Gyazo}).run
      send_data(result[-2], :type => result[-1], :disposition => 'inline')
    rescue => e
      render :status => 500, :text => 'error'
    end
  end
end

コード例

/purl/(a7d96c2ff64900f507ef9c8dab99f983):gyazo:5:round:5:5:5:5:extend:5:dropshadow:to.png gyazo

参考:

決定版! Rails用画像添付プラグインpurl

投稿者 nanki 2008-10-23 10:15:00 GMT

Rails pluginとして動く言語、purlを公開しました。

purl はクライアントサイドから柔軟な画像処理を行うために開発されました。 サムネイルの生成などを行うプラグインはいくつかありますが、そのどれよりも強力で汎用性、拡張性があります。

セットアップ

Rails2.1以上では、

$ script/plugin install git://github.com/nanki/purl.git

それ未満では、

$ git clone git://github.com/nanki/purl.git -- vendor/plugins/purl

gitが無い環境なら、githubのdownloadからファイルを落として、vendor/plugins/ に配置してください。

依存ライブラリ

  • 必須: ImageMagick, rmagick
  • あった方がいい: cairo, rcairo

その他

purl のデフォルトの環境では、画像の保存にデータベースを利用します。 imagesテーブルに、blob型のdataカラムを追加してください。

# app/models/image.rb
class Image < ActiveRecord::Base
  attr_readonly :data
end

その上で、ImageController#upload などに以下のように記述します。

# app/controllers/image_controller.rb
class ImageController < ApplicationController
  def upload
    Image.create(:data => params[:data].read)
  end
end

さらに、config/routes.rbを書き替え、purl が実行されるようにします。 書く場所は先頭に近い方がいいと思います。

# config/routes.rb
  map.connect 'purl/:commands',
    :controller => 'purl', :action => 'filter', :commands => /.*/
# app/controllers/purl_controller.rb
class PurlController < ApplicationController
  caches_page :filter

  def filter
    begin
      result = Purl::StackMachine.new(
        params[:commands], Purl::Purl.new).run
      send_data(result[-2], :type => result[-1], :disposition => 'inline')
    rescue => e
      render :status => 500, :text => 'error'
    end
  end
end

そんなこんなでセットアップは終わり。

言語

purl はURL上で記述されることを前提としています。 常にワンライナーであれ!

文法

purl は逆ポーランド記法を採用しています。 データと命令を書かれた順番にスタックマシンにプッシュしていき、命令が実行された結果がスタックマシン上につまれていきます。 命令列は最初に:で区切られ、数字としてパースできるものは数字へ、()で囲われた部分は文字列へと変換されます。

ポリシー

デフォルトで用意される全ての命令は、外部の値に依存しません。 つまり、命令列が決まれば実行結果は確定します。 このポリシーにより、全ての実行結果がキャッシュ可能になります。

サンプルコード

画像をそのまま表示

次の例では、load はスタック上に既にある数字1を消費して、ID=1のImage#dataをデータベースからロードして、スタック上にプッシュします。 to.png では、スタック上の画像データをPNG形式のバイト列に変換し、mimetypeとともにスタック上に積みます。

/purl/1:load:to.png

画像の形式を変換

次の例では、画像をGIF形式に変換しています。

/purl/1:load:to.gif

画像のリサイズ

次の例では、画像を100x100にリサイズしています。 リサイズ用の命令は、何種類か用意されており、高さを一定に保つ resize.heightや、上限を指定する、resize.upto などがあります。

/purl/1:load:100:100:resize:to.png

画像の合成

次の例ではふたつの画像を合成しています。

/purl/1:load:9:load:composite:to.png

次の例では順番を入れ替えています。

/purl/1:load:9:load:swap:composite:to.png

コメント

スタックに積んだ後すぐにpopすると、単純に無視されるので、コメントとして使えます。 キャッシュのライフサイクルコントロールなどに使えると思います。

/purl/1:load:(daily):pop:to.png

図形の描画

詳しくは解説しませんが、試験的にcairoの描画機能をベースにした図形描画命令を用意しています。 ctx命令で、指定したサイズのcairoコンテキストを準備し、xtc命令で実際にサーフェースへの描画を実行します。

/purl/80:80:ctx:40:40:moveto:40:40:40:-20:20:arc.ccw:1:0.3:0:rgb:fill:60:20:4:circle:0:0:0:rgb:fill:xtc:to.png

制限

実行結果をファイルとしてキャッシュする場合、ファイルシステムによる字数制限を受けます。

拡張

拡張は命令モジュールの追加という形で行います。 詳しくはソースコード見てください。

今後

  • 無名関数的なもの。
  • 外部から直接呼び出せない命令とか?
  • エラーメッセージとか?
参考:

この間の.zshrc - cheat 補完

投稿者 nanki 2008-09-30 00:25:00 GMT

netswitch! | 今日の.zshrc - cheat 補完 の補完関数だけど、なんだか遅いなと思ってたら間違いがあって、毎回cheatコマンドを実行していた。

元エントリ中のコードは修正済みだが、差分は以下の通り。

-    echo $*[1,-2] | sed -e 's/^/compadd /g' > ~/.zsh/completion/$*[-1]
+    eval $*[1,-2] | sed -e 's/^/compadd /g' > ~/.zsh/completion/$*[-1]

-  completion_list `cheat sheets | grep -v All` _cheat
+  completion_list 'cheat sheets | grep -v All' _cheat

遅さに困ってた人ごめんなさい。


今日の.zshrc - cheat 補完

投稿者 nanki 2008-09-25 07:00:00 GMT

cheatsheet を集めた cheat という gem があって、たまに便利である。

გ gem install cheat
გ cheat assertions
assertions:
  # Credit: http://nubyonrails.com/articles/ruby-rails-test-rails-cheat-sheet
  # Use 'cheat assert_raise' for more details
  
  # Standard Ruby Assertions
  
  assert                  boolean 
  assert_equal            expected, actual 
  assert_raise            *args 
  assert_raises           *args, &block 
  …
  …

cheat自身の使い方は

გ cheat cheat

どんなcheatsheetがあるのかは

გ cheat sheets

で見られる。

なんだけど、数が多すぎてもうどうしようもないので、さらに便利にするために、zshの補完を使ってみた。

見よう見まね。

completion_list () {
  mkdir -p ~/.zsh/completion
  if [ ! -f ~/.zsh/completion/$*[-1] ]; then
    eval $*[1,-2] | sed -e 's/^/compadd /g' > ~/.zsh/completion/$*[-1]
  fi

  `cat ~/.zsh/completion/$*[-1]`
}

_cheat () {
  completion_list 'cheat sheets | grep -v All' _cheat
}

compdef _cheat cheat

completion_list は一応再利用できるようにしてあるけど、ちゃんと調べたら既にありそうだ。

追記:

いつまでたってもassertionsの内容が古いままだなぁと思っていたら、キャッシュしてた。

გ cheat --new

でキャッシュをクリア。


iPhone/iPod touch用 JavaScript コンソール

投稿者 nanki 2008-09-09 18:55:00 GMT

iPhone/iPodのキーボードは、まったくもってプログラミングに向かいないけれども、 ちょっとしたJavaScriptを試してみたい時はあるので、どうにかならないか試してみた。

jsconsole for iphone

JavaScript Console for iPhone

若干妙なところもあるけど、一応動く。 ちょっとしたコードなら、思ったよりさくさく?かける。

高度なカーソル移動や、単語境界まで削除、みたいな機能は欲しいなぁ。

やっぱり、touchイベントを使うので、普通のSafariで動かない。めんどい… textareaのスクロールも…

AJAX Libraries API を使って、著名なライブラリをロードできる機能もつけてみた。

http://tools.netswitch.jp/jsconsole/?lib=j,ju こんな感じにすると、jQuery, jQueryUIを読み込んでいる(はず).

j=jQuery, ju=jQuery UI, p=prototype, s=scriptaculous, m=mootools, d=dojo

書き上がったJavaScriptはメールで送信できるらしい。

参考:

<div class="entry">
  <h2><a href="" /></h2>
</div>

このような文書で、aのリンク先を訪れると、div.entryの色が変わるようにしたい。

XPathみたいに、こういう子要素を持つノード、という指定は、CSSではできないっぽいので、JavaScriptでやるのが穏便かと思いきや、

div.entry {
  position: relative;
}
 
div.entry > h2 > a:visited:after {
  content: " ";
  display: block;
  position: absolute;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: 0px;
  z-index: -1;
  background-color:gray;
}

でうまくいった。

iPhone向けなので、Safari限定で考えられるのがうれしいところ。

実際には背景色ではなくて、新たに生成されたノードをdiv.entryにぴったり張り付くようにしている。

で、この情報をJavaScriptから取れるとどのサイトにアクセスしたか、という情報が取れてしまうので色々対策されているらしいんですが… どうやって防ぐんだろう。


今日のPostScript - ujj問題

投稿者 nanki 2008-06-19 18:50:00 GMT

文字列をsplitしてsortしてuniqしてjoinする.(いわゆるujj問題)

array.string#concatはWikibooksから。 .sort はghostscript組み込みらしい。

% [(a) (b) ... (z)] array.string#concat -> (ab...z)
/array.string#concat
{ 0 1 index { length add } forall string
  0 3 2 roll
  {
    3 copy putinterval
    length add
  }
  forall pop
} bind def

% (string) string#chars -> [(s) (t) (r) (i) (n) (g)]
/string#chars {
  [ exch { 1 string dup 0 4 -1 roll put } forall ]
} bind def

% [0 0 1 1] array#uniq -> [0 1]
/array#uniq {
  dup 0 get /prev exch def
  [ prev 3 2 roll
    {
      dup /val exch def
      prev ne {
        val
        /prev val def
      } if
    } forall
  ]
} bind def

[(ujihisa) (jikka) (jissitsu)] array.string#concat string#chars {lt} .sort array#uniq array.string#concat ==
参考:

PostScript FAQ - Wikibooks, collection of open-content textbooks


JavaScript デバッグツール - コードゴルフIE杯

投稿者 nanki 2008-06-12 13:31:00 GMT

先ほどのdebug.jsを読み込むBookmarklet.

debug

javascript:void((function(r){var d=document,w=arguments.callee,v,t=r[0],n=r.slice(1);if(t){v=t.split('$');if(v[1]){try{eval(v[0]);t=v[1]}catch(e){setTimeout(function(){w(r)},100);return}}v=t.split('@');if(v[1]){try{eval(v[0]);w(n);return}catch(e){t=v[1]}}d.body.appendChild(d.createElement('script')).src='http://tools.netswitch.jp/jstools/'+t+'.js';w(n)}})(['Prototype@prototype','Prototype$Effect@effects','Effect$DebugTool@debug']))

外部のJavaScriptを読み込むには、JSONPなどでも使われているscriptタグの動的生成を使うのだが、これが非同期で、prototype.js, effect.js, debug.jsを順番に読み込まないといけない今回のような場合はちょっと工夫が必要になる。

effect.jsはPrototype定数が定義されるまで読まない、debug.jsはEffect定数が定義されるまで読まない、など。

それとは別に、すでにprototype.jsが読み込まれている場合は、prototype.jsの読み込みをご遠慮する機能もつけてある。 ブックマークレット中の最後の方の@とか$とかにはさまれているあたりがそれ。 evalして例外が上がらなければ、あるいは上がれば、ロードして、次へ。

しかし、どういうわけか、一番使いたいIEで動かない。 alertを追加するしないで、syntax errorがでたりでなかったりするあたりで、ようやく、bookmarkletの文字数制限を思い出した。

というわけでそこから先は、コードゴルフIE杯。 今では、400台前半に落ち着いて、無事動くようになり、IE6SP2でも余裕がある。

参考:

Rules for Bookmarklets