Bulknews::Subtech RSSフィード

2009/06/04 (木)

MacNicoTunes 14:12  MacNicoTunes - Bulknews::Subtech を含むブックマーク はてなブックマーク -  MacNicoTunes - Bulknews::Subtech

http://brpg.hp.infoseek.co.jp/macnicotunes/

これはすばらしいスタンドアロンプレイヤー。

で、他のアプリからスクリプトで MacNicoTunes で動画開きたいんですが、AppleScript でイベント送るのはどうにもうまくいかなくて、とりあえず

on run argv
  tell application "System Events"
    set the clipboard to item 1 of argv
    tell process "MacNicoTunes"
      set frontmost to true
      click menu item "Open Video.." of menu "File" of menu bar 1
      keystroke "v" using {command down}
      keystroke return
    end tell
  end tell
end run

みたいに無理矢理やってうごいてるんですが、AppleScript の口なり open -a MacNicoTunes で開けるようにするのは難しいでしょうかねー。Dock にリンクをドロップして開く機能はあるので、口はありそうなんですが、ソースをみた感じでは AppleScript から直接イベントを送るのは難しそうでした。

2009/04/08 (水)

DBD::SQLite 1.22_01 と Unicode 16:22  DBD::SQLite 1.22_01 と Unicode - Bulknews::Subtech を含むブックマーク はてなブックマーク -  DBD::SQLite 1.22_01 と Unicode - Bulknews::Subtech

Encountered a 404 error に書いた通りだけど、DBD::SQLite で $dbh->{unicode} オプションをつけたとき、UTF-8 フラグがついていない文字列を渡したときの挙動を変更しました。CPAN に 1.22_01 dev release としてアップロードされてます。

具体的には、いままでは、その文字列の内部エンコーディング(UTF-8 フラグがついてるかどうかにかかわらず)をそのまま保存していて latin-1 の文字列など UTF-8 的に正しくないシーケンスがきたときに DB に壊れた値が入るという問題があったのを、utf8::upgrade を内部的に呼んで、確実に UTF-8 エンコーディングになるようにしました。

もっと日本人のPerlプログラマ的にわかりやすく言うと、UTF-8 な文字列を渡すときはdecode した状態でわたせ、さもなくば二重エンコードになって文字化けするよ、ということです。

これは DBD::SQLite の POD にもずっと書いてあった(unicode オプションのときは文字列は UTF8 フラグつきでやりとりするよ)のだけど、フラグなしで渡したときの動作がドキュメントと食い違っていて latin-1 文字列でバグが起きていました。

これで DBD::mysql の mysql_enable_utf8 とも動作は同じになりますが、以前の(正しくない)動作に依存しているアプリケーションは動かなくなるかもしれません。

具体的に言うと、ちょっと前の Remedie では JSON 文字列をカラムに保存するのに JSON::XS->new->utf8->encode を利用していたので、このパッチがあたった DBD::SQLite では二重エンコードで文字化けしてしまいました。->utf8 オプションを外すか、現在の Remedie のように ->ascii としてそもそも変換を回避するように変更すれば、現状版でもパッチがあたっていてもどちらでも動きます。

というわけで、http://search.cpan.org/~adamk/DBD-SQLite-1.22_01/ にあがっているのでテストよろしく。

2009/03/13 (金)

BEGIN を使わずにコンパイル時にコードを実行する 17:29  BEGIN を使わずにコンパイル時にコードを実行する - Bulknews::Subtech を含むブックマーク はてなブックマーク -  BEGIN を使わずにコンパイル時にコードを実行する - Bulknews::Subtech

use Module VERSION の形をつかって VERSION に式をぶちこむ。

use less sub { ("Dyna"."Loader")->can("dl_find_symbol")->(...) }->();

less.pm はとくに import で何もしていないので sub {} で何を返してもおkだけど、そうじゃないモジュールを利用する場合は return () とかする必要がある、かも。

See also: perl から任意の C ライブラリを呼び出す方法 - kazuhoのメモ置き場

2009/02/08 (日)

メタプログラミングとevalのベンチマーク 06:58  メタプログラミングとevalのベンチマーク - Bulknews::Subtech を含むブックマーク はてなブックマーク -  メタプログラミングとevalのベンチマーク - Bulknews::Subtech

404 Blog Not Found:perl,javascript and more - evalは最後の武器

「evalは最後の武器」というのは、Perlに限らずメタプログラミング可能な言語における鉄則とも言える。たいていの場合、無名関数を生成するだけで同様の目的をより安全かつ高速に行えるのだ。

記事全体には同意するけど、「高速」という部分はどうだろ。Mooseは無名クラスの生成に無名関数ではなくて string eval を使ってクラスをコンパイルしてるんだけど、string eval のほうが実行時に速い、というのがひとつの理由だったとおもう。

こんな単純な例でも、30倍の速度差が出ている。

このコードは benchmark のループ内で毎回 eval を実行しているから、そもそも比較の対象としておかしい。


#!/usr/bin/perl                                                                                                         
use strict;
use warnings;
use Benchmark qw/timethese cmpthese/;

eval 'package FooEval; sub bar { $_[0] + $_[1] }';
*FooAnon::bar = sub { $_[0] + $_[1] };

cmpthese(
    timethese(
        0,
        {   
            eval => sub {
                FooEval::bar( 1, 1 ) == 2 or die;
            },
            anon => sub {
                FooAnon::bar( 1, 1 ) == 2 or die;
              }
        }
    )
);

実際のメタプログラミングの手法を考えると、まずこういう風に subref を eval をつかったほうほうとそうでない純粋な無名関数とでbenchmarkの外側で定義して実行時コストを比較すべき。

Benchmark: running anon, eval for at least 3 CPU seconds...
      anon:  4 wallclock secs ( 3.15 usr +  0.01 sys =  3.16 CPU) @ 1837367.09/s (n=5806080)
      eval:  4 wallclock secs ( 3.23 usr +  0.00 sys =  3.23 CPU) @ 1855530.03/s (n=5993362)
          Rate anon eval
anon 1837367/s   --  -1%
eval 1855530/s   1%   --

となってほとんど同じ。

2009/01/14 (水)

github で人のコードをいじる「前」にforkする必要はない 14:21  github で人のコードをいじる「前」にforkする必要はない - Bulknews::Subtech を含むブックマーク はてなブックマーク -  github で人のコードをいじる「前」にforkする必要はない - Bulknews::Subtech

git/github を使い始めてほぼ1週間ぐらい。よくできた分散SCMだなぁ、とおもう。とくに rebase とか stash なんか、svk でももちろんできるけどこういう機能が最初からついてるのは素敵。

で、github にプロジェクトをおいておくと fork ボタンがあってすぐに fork していじって commit/push して pull request ってのが素敵なわけだけど、とくにコミットもしないのにとりあえず fork だけしておく、っていうのがたまにみかけるのだけど、それって必要ないよね、って話。(や、別にやるなということではなく、単に勘違いしてやっているのもあるのではないか?と思ったりするので)

railsontherun.com -  とかで、「とりあえず "fork" ボタンをおして fork したレポジトリをつくりましょう」とか書いてあるのでそれが原因なのかもしれないけど、git でとってきたプロジェクトにローカルパッチをあてるのに fork は必要ないです。

git clone git://github.com/miyagawa/remedie.git
cd remedie
# ファイルを編集
git ci ...

ローカルにある git の作業用ディレクトリは push されるまで remote (origin) とは関係ないので、パッチをあてていくら commit してもまったく問題ない。し、git://github.com/... で clone しているのでそもそも push することはできない。

You can't push to git://github.com/user/repo.git
Use git@github.com:user/repo.git

ちなみにこうやってパッチをあてた状態で remote からとってくるときは git pull でなくて git pull --rebase したほうが精神的にいいかもしれない(--rebase はローカルのパッチをいったんなかったことにしたあと pull で最新版にして再度アプライする)。

で、このローカルの変更を master に反映したい(してもらいたい)ときにはじめて、github 上で fork ボタンをおして fork をつくり、git remote add myfork git@github.com:username/remedie.git で remote に追加、git push myfork master で fork に対して push、でもって pull request を送るという手順がいいんじゃないかなとおもう(origin, myfork という名前が気に食わなければ .git/config を編集するなりして upstream, origin という具合に変更すればいいんすかね)。

まぁ fork ボタンを押すことで元の作者に「fork したよ」というメッセージが伝わるので、自分に対するモチベーション/プレッシャーをかけるという意味では先に forkしてしまう、というのもアリかもしれませんがね。