Home > Latest topics

Latest topics 近況報告

たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。

萌えるふぉくす子さんだば子本制作プロジェクトの動向はもえじら組ブログで。

宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能! シス管系女子って何!? - 「シス管系女子」特設サイト

Page 23/248: « 19 20 21 22 23 24 25 26 27 »

MozStorageのユーザ定義関数が意味分からん - Feb 06, 2008

mozIStorageConnectionのcreateFunctionメソッドを使うとユーザ定義関数を作れるそうなんだけど、Firefox 2だとユーザ定義関数から値を返せない(返り値が常にNULLになる)。値を返せるようになるのはFirefox 3からだそうな。

const DirectoryService = Components
    .classes['@mozilla.org/file/directory_service;1']
    .getService(Components.interfaces.nsIProperties);
var file = DirectoryService.get('ProfD', Components.interfaces.nsIFile);
file.append('mydatabase.sqlite');

var storageService = Components
    .classes['@mozilla.org/storage/service;1']
    .getService(Components.interfaces.mozIStorageService);
var dbcon = storageService.openDatabase(file);

// mozIStorageFunctionインターフェースを備えたオブジェクト
var func = {
  onFunctionCall : function(aArgs) {
    // 渡ってくるのはmozIStorageValueArrayのオブジェクト
    var data = aArgs.getString(0);
    var pattern = aArgs.getString(1);
    return data.match(new RegExp(pattern)) ? true : false ;
  }
};
// 引数の個数を「-1」にすると可変長引数の関数になる
dbcon.createFunction('match', -1, func);

var extracted = [];
var statement = dbcon.createStatement(
      'SELECT * FROM mytable WHERE match(data_column, ?1)'
  );
statement.bindStringParameter(0, '^foobar');
try {
  while (statement.executeStep())
  {
    extracted.push(statement.getString(0));
  }
}
catch(e) {
}
statement.reset();

alert(extracted.length); // 0

こんなの何に使えばいいんだ?

まあどうせPlacesはFirefox 3からだし、正規表現でのマッチングをやる必要が出てくるのはそれからだと思うんだけど。でもこのコードのようにJavaScript製ユーザ定義関数でマッチングするんだったら、結局は全ての行に対して処理が行われるわけで、それだったら先に全ての行を取り出してからループ回してマッチングするのと、処理速度的には全然変わらないよね……ほんと無意味。標準の関数で正規表現が使えればいいのになあ。

XUL/MigemoでのThunderbirdのフォルダ内検索の高速化とか - Feb 05, 2008

検索を開始したタイミングでヘッダ情報を一気に収集するという現状の仕様だと、フォルダ内に数千件とかメールが溜まってる人はまず間違いなく死亡するので、フォルダの内容を表示したタイミングでバックグラウンドでちまちまとヘッダ情報を収集するようにして、ついでに、その収集結果をMozStorageで保存するようにしてみてるんだけど。

今の所、一つのフォルダにつき一つのレコードとして、「Subjectだけ集めたもの」「Toだけ集めたもの」のような文字列をそれぞれフィールドに保存してるんだけど、これもあんまりでっかくなりすぎるとまずいですよねえ多分。仮にSubjectが10文字のメールが1000件あったとすると、20~40KBとかそれくらいになるのかな? 3000件もあれば100KBはいってもおかしくない。これって大丈夫なんだろうか。

えーと。SQLiteの制限事項によると、SQLiteデフォルトでの文字列の最大長は1ビリオン(1000000000)バイト……えーと、だいたい1GBくらい? Firefoxのソースツリーを検索してもSQLITE_MAX_LENGTHという文字列は登場しないようなので(というのは全然根拠にならんのだけど)、このデフォルト値のまんまなんだとしたら、パフォーマンスはさておきとりあえずこのままでも動くことは動くのかな?

というか別にSQLite使う必要は必ずしもないんですけどね。なんとなく最近無駄に多用する癖が……

About Tabbrowser Extensions - Feb 04, 2008

Hello, thank you for your mail.

The only problem now is the new version, the old one for Firefox 1.5 is a lot better and right now I prefer having Firefox 1.5 with your old extension instead of using the new one.

Have you thought of making the same as for 1.5? If not, will you do it?

Currently I have no plan to develop an extension same as TBE on Fx 1.5. I suffered from too many bugs which are from options I didn't use, so, I decided to keep developing "TBE3" only on features I really need.

Because I was a student and I had a lot of off-time, I could develop huge software like old TBE. But now I'm one of working people. There is less time and motivation.

Now there are nice projects, Tab Mix Plus and Tab Kit, suites of tabbed browsing features. And, userChrome.js is also available to make people's small requirements reality. Lots of people develop user-scripts for the extension on MozillaZine forum. I hope communities of those extensions help you.

regards,

Firefox 3でコンテキストオブジェクトを明示して、日本語などを含むスクリプトを実行するための方法 - Jan 24, 2008

UxUのことで悩み中。

テストケースを実行するとき、コンテキストオブジェクトを指定してスクリプトを実行しないといけないんだけど、色々問題があって悩ましい。

brazilさんが紹介されているとおり、ビルトイン関数のevalに第2引数を渡すか、Objectクラスのメソッドであるevalを使うと、コンテキストオブジェクトを指定してスクリプトを実行することができる。ただ、この両者は若干動作が異なる。

例えばこんなコードを考えよう。

var context = {};
context.eval('var val1 = true; this.val2 = false');
alert(context.val1); // => true
alert(context.val2); // => undefined

Objectクラスのメソッドだと、実行したスクリプトの中で変数として宣言した物がそのままそのオブジェクトのプロパティとなり、外部から後で参照することができる。でも、

var context = {};
eval('var val1 = true; this.val2 = false', context);
alert(context.val1); // => undefined
alert(context.val2); // => undefined

ビルトイン関数の方だと、そうはならない。また、どちらにしてもthisを明示した場合は外部からは参照できない。

言い換えると、「コンテキストオブジェクトを明示して実行したスクリプトの中でvarで宣言された値を外部から取得するには、Objectクラスのevalメソッドを使わないといけない」ということ。

ところが、Firefox 3ではObjectクラスのevalメソッドが存在しない。どうやらどこかの時点で削除されてしまったようだ。

元のMozLabではどうしていたかというと、evalを使う代わりにmozISubScriptLoaderを使っていた。

var context = {};
var loader = Components.classes['@mozilla.org/moz/jssubscript-loader;1']
          .getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript(
  'data:application/x-javascript,'+encodeURIComponent('var val1 = true; this.val2 = false'),
  context
);
alert(context.val1); // => true
alert(context.val2); // => false

こちらは前二者のどっちとも結果が異なり、varで宣言した物もthisを明示した物も両方ともコンテキストオブジェクトのプロパティとして外部からアクセスできるようになる。

ところが。mozIJSSubScriptLoaderを使う方法だと、スクリプトの中に日本語などの非ASCII文字があると化けてしまう。

var script = 'alert("日本語")'; // Unicode

eval(script); // => "日本語"
({}).eval(script); // => "日本語"
loader.loadSubScript('data:application/x-javascript,'+encodeURIComponent(script), {}); // => 文字化けした文字列

encodeURIComponentによってUnicodeの文字列がUTF-8のバイト列に変換されてしまうのでこうなる、のか? とにかく、これではテストケースの説明を日本語で書けなくて(僕が)困る。UxUではこの処理の直前でUTF-8なりShift_JISなりで書かれたテストケースを読み込んで内部コードのUnicodeに変換しているのだけれども、せっかく変換したのに最後の最後で化けてしまうんじゃあしょうがない。

ということでああでもないこうでもないと試していて、以下のような方法に辿り着いた。

var script = 'alert("日本語")'; // Unicode
script = 'eval('+script.toSource().replace(/^\(new String\(|\)\)$/g, '')+')';
loader.loadSubScript('data:application/x-javascript,'+encodeURIComponent(script), {}); // => "日本語"

encodeURIComponentに放り込む前に、一旦全体を文字列リテラルとして評価可能な文に変換して(この時点で日本語などの非ASCII文字は「\uXXXX」のようなUnicodeエスケープに変換される)、encodeURIComponentを通過した後でevalで元に戻す、というトンネル抜けのようなやり方。これによって、日本語で書かれた説明もそのまま利用できるようになった。

でも、これにもまだ問題がある。この方法で実行したスクリプトの中でエラーが起こると、MozUnitテストランナーのUI上でソースを表示してもeval("(元のテストケースのスクリプト)")という1行だけのソースになってしまって、エラー箇所がさっぱりわからない。これ、どうにかならんもんだろうか……

追記。エラーが発生した行の番号自体はこれでも正しく取れてるようなので、とりあえずやっつけ仕事で、MozUnitテストランナーのUI上でソースを表示する時にソースを元の文字列に復元するという方向で手を打とうと思う。

さらに追記。よく考えたら、わざわざ自分でソースを復元しなくても、変換前後で行数その他は変わってないんだから、ソース表示の時に元のファイルの方を読み込ませるようにしたらいいんだな……

さらにさらに追記。mozIJSSubScriptLoaderの仕様変更によってこの方法も使えなくなりました。現在何かいい手は無いか考え中。

さらにさらにさらに追記。上記内容と同じような結果になる代替案を考えてみた。

さらにさらにさらにさらに追記。evalの機能についてFirefox 3.1でまた変更があったようだ

UXU - UnitTest.XUL、1000人スピーカプロジェクト - Jan 21, 2008

amachangの1000人スピーカプロジェクト第1回でお披露目したUXU(うず)のこととか。書くのが遅くなったのは見てたからです。

プレゼンの話

ニコ動に全プレゼンの映像が上がってて僕の奴も見れるんですが、いやー、これはひどいプレゼンですね。

いや言い訳さしてもらうとですね、前日に仕事用マシン(Let's note W2)のHDDが逝ってしまいまして、前日夕方くらいからそれのせいであたふたして徹夜してて、あんまり頭働いてなかったんですよ。だからこの日はマシンは持参してたけどUbuntu 7.10のLive CDで起動してました。隣の人とか後ろの人とか多分CD-ROMドライブの音がぶんぶんうるさかったと思いますが、それはこのせいです。それにしてもUbuntuすごいね。CD起動なのに無線LAN使えちゃったよ。さすがにプロジェクターの認識は再起動が必要みたいだったからプレゼンの時だけamachangにマシンをお借りしましたが。

プレゼンでちゃんと言えてなかったことの補足。自分がテストという物の意義を理解したのがRailsのそれだったので、UXUを最終的にどういうものにしたいのかという目標も、今の所はRailsに置いてます。なので、今は実現できてないけどfixtureみたいな物もできるようにはしたいと思ってます。

それか、もっと根本的なところで、テスト専用のプロファイルにその時だけ切り替えて……みたいなこともできるようにしたいんですが、この辺になってくるとプラットフォーム用のバイナリを作らないといけないような気がしていて気が重いです。もしかしたらProfile Switcherが解決のヒントになるでしょうか?

yieldの変な使い方の話

yieldの読み方は「いーるど」でよかったんですね。でもそれ知ってもどうしても「いぇーるど」と読んでしまう……

昨年頭にごにょごにょしてたのはプレゼン中に書いたお蔵入りバージョンのUXU 0.1のことなんですが、その時は単にウェイトの秒数を指定するだけでした。つい最近になって奥さんのエントリを見て、そうか「復帰条件」と考えれば返り値は数値だけじゃなくてもっとなんでも渡してイイんだな、とインスパイアされて、フラグを保持するオブジェクトを渡すパターンをまず実装し、それから関数を渡すパターンも実装したという次第です。

UXUでやってることの工夫というか特徴的なところは、yieldの本来の用途であるところのジェネレータ・イテレータの生成という役割を隠蔽してしまって、「処理の一時停止」「再開」という部分だけに特化した見せ方をしているところではないでしょうか。内部的には昨年頭に書いた話にあるとおり、setUpとかテストケースとかの関数オブジェクトの返り値がジェネレータであればタイマーを使ってイテレーションを行う、というだけのことなんですが。

amachangが紹介していたJSDeferredの方がもっときっと便利でいろんな事ができるとは思うんですが、プレゼンでも言った通り僕はN88BASICの行番号の呪縛から未だに逃れられていないような人間ですので、これ以上の複雑なことは脳が拒否して受け入れてくれんのですよ……

続きを表示する ...

XULRunnerアプリケーションにアドオンをインストールする方法 - Dec 17, 2007

McCoyの改造を試みるために、XULRunnerアプリでもアドオンを使えるのかどうかという実験をしてみた。

  1. XULRunnerアプリを終了する。
  2. インストールしたいアドオンのXPIパッケージの中にあるinstall.rdfを編集して、targetApplicationにそのXULRunnerアプリのIDを書き加える。ちなみにXULRunnerアプリのIDはアプリケーションのディレクトリにあるapplication.iniに書かれている。McCoyなら「mccoy@developer.mozilla.org」。
  3. XULRunnerアプリのプロファイル内の「extensions」フォルダに、アドオンのXPIパッケージをコピーする。McCoyの場合は「C:\Documents and Settings\ユーザ名\Application Data\Mozilla\McCoy\Profiles\ランダムな文字列.default\extensions」。
  4. XULRunnerアプリを起動する。
  5. Firefoxの物と同じ「ソフトウェアインストール」のダイアログが表示されるので、「OK」ボタンを押してアドオンをインストールする。

これだけでいける。逆に、アドオンをアンインストールしたい時は、アドオンのID名が付いたフォルダをプロファイル内の「extensions」フォルダから削除する。

amachangさんはアプリやアドオンそのものの中身をガリガリ書き換えるやり方を紹介されてるけど、僕はこういうやり方はしない方がいいと思ってる。理由は以下の通り。

  • アプリやアドオンが自動アップデートされる度に、その都度ソースを書き換え直さないといけない。Firefoxの場合特に設定を変えていなければ勝手にそれらが行われてしまうので、「気がついたら変更が失われてた」ということになりかねない。
  • アプリやアドオンの自動アップデートを止めればその心配はなくなるが、今度は、セキュリティアップデートが適用されないので危険なままの状態が続いてしまうという別の問題が発生する。少なくとも僕については、ものぐさなので、毎回必ずコードを書き換え直すのを嫌ってセキュリティホールがあると知りながら古いバージョンの改造版を使い続けてしまいそう。

なので、これらの問題を回避するために、teramakoさんのようにそれ用のアドオンを作って使うか、userChrome.jsを使うかする方がいいと僕は思う。今回McCoy用の改造をアドオンという手法で行うことを試みているのも、そういう理由からだ。

第8回Mozilla拡張機能勉強会のネタ - Dec 17, 2007

第8回Mozilla拡張機能勉強会でFirefox 3で要求されるセキュアなアドオン提供方法について話すつもりですが、話すだけじゃ何なのでMcCoyを改造して何かできたらなぁと思ってますが、できるかどうか分からないのであんまり期待しないでください。と、宣伝になってるんだかなってないんだか分からない宣伝をしておきます。

落ちる - Dec 10, 2007

とよく言われるんだけど自分の環境&自分の見てる範囲のWebサイトでは落ちないので原因が分からない、ということが多い。落ちるか落ちないかのギリギリの所をうまく突くようなコードを知らず知らずのうちに書いてしまっているのでしょうか。そんな能力いらなさすぎる。

Page 23/248: « 19 20 21 22 23 24 25 26 27 »

Powered by blosxom 2.0 + starter kit
Home

カテゴリ一覧

過去の記事

1999.2~2005.8

最近のコメント

最近のつぶやき