忘れたときに備えた記録

トップ 最新 追記
2005|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|11|12|
2009|01|02|03|04|05|06|10|12|
2010|06|07|08|12|
2011|07|09|
2012|09|11|
2013|02|03|09|
2015|10|11|
2016|01|08|11|
2017|02|08|10|
2018|11|

2007-07-02(Monday)

Hiki のプラグインの中で、Wiki記法の変換をする

次のような手順で、Hiki本体がページソースをHTMLに変換するのとほぼ同様の結果を、好きな文字列から得られる。

def tst(src)
   # パースする
   # プラグインに渡される文字列はCGI.escapeHTML済みなのでCGI.unescapeで戻す
   data = @conf.parser.new(@conf).parse(CGI.unescapeHTML(src))

   # HTMLへの変換を行う
   html = @conf.formatter.new(data, @db, self, @conf).to_s
   "<pre>#{CGI.escapeHTML(html)}</pre>"
end

これだけ。


2007-07-10(Tuesday)

MySQLとRailsの組み合わせで、LONGBLOG型を使う

もう1年近く前に、MySQLとRailsの組み合わせで、BIGBLOG型を使うというメモで、 railsでLONGBLOG型のデータを使うにはexecuteメソッドでSQLを直接実行するとか書いていた。

それに対して今日ツッコミが入ってきて、これによると

t.column :bigdata, "lomgblob"

と書けるらしい。なんと!?

早速試しに、こんなマイグレーションを書いてみた。

class CreateItems < ActiveRecord::Migration
   def self.up
      create_table :items do |t|
         # t.column :name, :string
         t.column :bigdata, :longblob
      end
   end

   def self.down
      drop_table :items
   end
end

んで、rake db:migrateして、mysqlで show columns from itemsしてみる。

+---------+----------+------+-----+---------+----------------+
| Field   | Type     | Null | Key | Default | Extra          |
+---------+----------+------+-----+---------+----------------+
| id      | int(11)  | NO   | PRI | NULL    | auto_increment |
| bigdata | longblob | YES  |     | NULL    |                |
+---------+----------+------+-----+---------+----------------+

素晴らしい!!!


2007-07-17(Tuesday)

差分のアルゴリズム

ちょっと興味があって調べてみたメモ。

  1. 文書比較アルゴリズム エディットグラフについて分かりやすく書かれている
  2. AnO(ND) difference algorithm and its variations (springer) 1で挙げられている論文。1のページのリンク先が古くなっているようだったので探してみた。
  3. An O(NP) sequence comparison algorithm (ScienceDirect)

2の論文は、GNU diffのソースで

/* The basic algorithm is described in:
   "An O(ND) Difference Algorithm and its Variations", Eugene Myers,
   Algorithmica Vol. 1 No. 2, 1986, pp. 251-266;
   see especially section 4.2, which describes the variation used below.
   Unless the --minimal option is specified, this code uses the TOO_EXPENSIVE
   heuristic, by Paul Eggert, to limit the cost to O(N**1.5 log N)
   at the price of producing suboptimal output for large inputs with
   many differences.

   The basic algorithm was independently discovered as described in:
   "Algorithms for Approximate String Matching", E. Ukkonen,
   Information and Control Vol. 64, 1985, pp. 100-118.  */

とある。


2007-07-18(Wednesday)

mod_rewriteによるURLの書換えに関するメモ

tDiaryやHikiのhtml_anchorプラグインや、railsで使われるデフォルトの.htaccessで便利に使われている mod_rewrite を自分でも使ってみようかと思い、色々と試行錯誤したメモ。 参考にしたのは

ほか。

以下で使っているCGI env.cgi は、こんなの

#!/usr/bin/ruby
puts "Content-type: text/plain;\n\n"
ENV.sort.each{|k,v| puts "#{k} : #{v}"}

.htaccesで使って無限ループ

http://localhost/~hiraku/http_test/rewrite/path/info というURLにアクセスされたら http://localhost/~hiraku/http_test/rewrite/env.cgi/path/info に書換えたいとする。

で、こんな.htaccessを書いてみる。

RewriteEngine on
RewriteBase /~hiraku/http_test/rewrite/

RewriteRule ^(.*)$ env.cgi/$1

すると、500 Internal Server Errorとか出て、ログを見ると

Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

と言ってくる。ログレベルをいじってもう一回試すと

[Wed Jul 18 20:21:38 2007] [debug] core.c(3027): [client 127.0.0.1] r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/env.cgi/path/info
[Wed Jul 18 20:21:38 2007] [debug] core.c(3033): [client 127.0.0.1] redirected from r->uri = /~hiraku/http_test/rewrite/path/info

どうも、以下のような手順でループになっているらしい

  1. URLを書換える
  2. この段階では.../env.cgi/path/infoというURLに対して「env.cgiに渡されるPATH_INFOが/path/infoである」という評価をせず、単にenv.cgi/path/infoというファイルとして扱う
  3. 書換えた後のURLが .../rewrite/の下のディレクトリを指すので、そこを調べようとする
  4. その前にその1つ上のディレクトリ(つまり../rewrite)の.htaccessを評価する
  5. RewriteRuleを再び見付けて、もう一回書換えに入る(1へ戻る)

そんなわけで、env.cgiがURLに含まれていたらもう書換え処理をしないという指示が必要になる。

それには、

RewriteRule ^env.cgi - [L]

この行を、

RewriteRule ^(.*)$ env.cgi/$1

前に追加する。

'-'は「置換せずに元のURLをそのまま使う」という意味で、"[L]"は「パターンにマッチしていたら、以下の置換ルールはもう行わない」という意味だ。

これで、期待どおりのURLの置換が行われる。

[QSA]の意味

書換えルールの最後に[QSA]と書かれているのがrailsの.htaccessで見付かる。

QueryStringAppendの意味で、これは、書換え前のURLに"?k=v"などのQUERY_STRINGが含まれていたときに、書換え後のURLにもそれを追加の形で渡すという意味とのこと。

例えば、

RewriteRule ^qtest env.cgi?k1=v1;k2=v2 [L,QSA]

という行を例によって

RewriteRule ^(.*)$ env.cgi/$1

前に追加したとする。

すると、 http://localhost/~hiraku/http_test/rewrite/qtest?a=b というURLでアクセスしたときに、QUERY_STRINGは

k1=v1;k2=v2&a=b

となる。区切り記号に'&'が使われる点は要注意かな。

この[QSA]の指定がないと、書換え後のURLには?a=bに該当する部分が渡されない。

置換の有効範囲など

Rubyの正規表現による文字列置換になれていたのでハマってしまった話。

例えば、

RewriteRule ^a A

という行を

RewriteRule ^(.*)$ env.cgi/$1

前に追加したとする。

んで、http://localhost/~hiraku/http_test/rewrite/alpha にアクセスしたとしよう。

Rubyっぽく(Perlっぽくでも可...の筈)考えるとhttp://localhost/~hiraku/http_test/rewrite/Alpha に置換されて最後のルールに渡されるような気がするが、なんとここでの置換の結果は http://localhost/~hiraku/http_test/rewrite/A になる。

では、 http://localhost/~hiraku/http_test/rewrite/alpha/beta にアクセスしたらどうなるだろうか?

これも http://localhost/~hiraku/http_test/rewrite/A かと思いきや、http://localhost/~hiraku/http_test/rewrite/A/beta だった。

この結果は、ルールを

RewriteRule ^a.*$ A

にしても同じだった。

つまり、mod_rewriteの置換は、そのディレクトリの中だけに適用され、特にサブディレクトリに該当する部分には適用されないらしい。

Tags: Apache

2007-07-26(Thursday)

Athron64 X2 で、VMwareでLinuxを動かすと時計が早くなる件

Athron64 X2 4800+を乗せたマシンでホストOSとしてWindowsXPを使い、VMwareServerを使ってゲストOSとしてLinux(Debian4.0)を使っていると時計が2倍くらいに速くなってしまうという問題が発生していた。

今までにも何度か調べてみて、カーネルオプションをいじったり、カーネルをコンパイルしなおしたりBIOSでCool'n'Quitを切ってうまく直ったと思ったらぬか喜びだったり、VMwareToolsの時刻同期オプションを有効にしてもなぜかきちんと同期してくれず、結局別にNTPサーバをローカルで立ててそこに1秒ごとにアクセスして強引に補正するプログラムを作って凌いでいたのだけど、ついに解決できた。 …多分。

そもそもこの問題は、IntelのCore2DUOでは発生しておらず、ホストOSにWinXP、VMwareServerでゲストOSをLinuxというほぼ似たような状況で、同じ構成(VMwareの設定ファイルとかHDDのイメージ(含インストールされているLinuxの各パッケージ))のバーチャルマシンを動作させても、NTPで補正できる程度のずれしか起こらなかった。

それで、これはVMwareではなくAthronの方の問題ではないのかと考え、'Athlon64X2 Linux 時計'というキーワードでググってみたら、こんなページが見つかった。

2つのコアの間でTSCの動作に食い違いが出るというのがいかにも当たっていそうなので、早速

からAMD Dual-Core OptimizerをダウンロードしてホストOSのWinXPにインストールしてみたところ、とりあえずこの15分ほどの間は誤差がNTPで補正できる程度の抑えられている。ひゃっほう!!

Tags: VMware