トップ 最新 追記

じじぃの日記、ツッコミ可

Twitter: @jijixi_org
Xbox Live: jijixi

初心者が書いた OCaml 入門
Spotlight tips サイト内リンク集
1970|01|02|
2003|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|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|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|11|
2011|05|
2012|01|

2007-12-03 [長年日記]

% [OCaml][雑談] 一気に欲しくなった『プログラミング in OCaml』

まあ著者がその道の権威だってことでわりと期待はしてたんだけど、 (以下、引用の引用でもうしわけない。)

OCamlでは,このような型に関する抽象や型への適用の構文は用意されていませんので,すべて心の中で行います.

[soutaro#nikki()より引用]

何か違う意味で欲しくなった。 これは買わねばならんかもしれん。


2007-12-04 [長年日記]

% [Ocaml][Erlang] 『プログラミング in OCaml』ゲット

ふらっと本屋に寄ってみたら置いてあったんで立ち読み。 とりあえず p70 の『心の中で行います』を見てニヤニヤしつつ、パラパラめくる。

結局『入門 OCaml』は買いそこねてそのまんまなんで比較対象が無いんだけど、モジュールやファンクタ、分割コンパイルのことなんかが結構詳しく触れられてて、好印象。 特に分割コンパイルに関しては初心者殺しの要素が多すぎると思うんで、そこら辺へのフォローがあるのはとても良いと思う。 (まあ、今は ocamlbuild があるから、以前に比べると劇的に楽になってるけど、仕組みを知っておくのは悪くない)

で、まあそんな感じでさらっと眺めた感じ、いくつか心に触れるフレーズを見かけたんで、「いまさら新発見は無さそうだけど、読み物として買おう」と思ってゲットした。

型エラーが発生しないということが, 即プログラムにまったく間違いがない, というわけではありません。

(中略)

しかし, ある種のエラーがない, ということは, プログラムに間違いがあった時の原因が絞られるので, 本当の間違いを発見しやすくなるということにつながります。

[p5より引用]

うんうん。

(前略) 思った通りの型の関数が定義できただけで, それが正しい定義になっている可能性が高い, というのは OCaml プログラマのよく漏らす感想です。

[p56-57より引用]

そうそう、思ったとおりの型でコンパイルされた時点で、気付いたら完成してた…… ってのが OCaml の醍醐味だよね。

ところで『Erlang 入門』もあったんで見てみたけど、あまりにも『入門』すぎるのでスルー決定。 内容的には Programming Erlang の最初の 3 分の 1 辺りという感じ。 関数型言語に馴染みの無い人が最初に読む本としては良いかもしれないけど、そうでなければ Erlang らしさが出てくるのは最後の章のメッセージ通信のところくらいのものなので、もの足りなさを感じそう。


2007-12-05 [長年日記]

% [雑談][OCaml][F#] F# とか

や、随分前に手を出してますよと言ってみるテスト。 この辺の RSS も登録してますし。 まあ、最近はあんまり追い掛けてないですが。

なんでかっていうと、メインの環境 (Mac OS X/ppc + Mono) で動かないから。 一応 Mono に配慮したファイルとかも入ってるんで動く環境もあるんだろうけど、ともかくウチでは動かないのでショボンなのです。 サブの Windows 機にはたまに気が向いたときに、その時点で一番新しいのを入れ直したりしてます。

% [OCaml][DouKaku] 文字列の八方向検索

昨日引用した

思った通りの型の関数が定義できただけで, それが正しい定義になっている可能性が高い

というフレーズにインスパイアされて、一発実行プレイをしてみた。 要するに書き上げるまで一度も実行せずに (さすがに ocamlc -i で型は確かめるよ)、最初の実行で思ったとおり出力されてバンザーイ…… というのをやろうと。

で、ほぼうまく行ったので、そのままリファクタリングとかせずに投稿してみた→ #4616

こういうカタルシスは強い静的型付け言語じゃないと味わえないと思う。 比較的感触が近いのはテスト駆動開発かな。 あれはある意味、型検査に類する何かを自分であらかじめ書いてるようなもんだと思うんだよね。 で、テストを実行するのは OCaml で言えば ocamlc -i するのと同じようなもんで、ちょっとずつ型 (とか、それに類する何か) の整合性を高めていくことで、プログラムを完成させていくというか。

スーパーハッカーな人だと、動的型付け言語でもこれくらいの問題なら一発で書けちゃうのかも知れないけど、わしのような凡人にはそれは無理なわけよ。 でも、OCaml ならわりとできちゃう。 「おれってすげぇー」感を感じることができちゃう。 そんなところも、わしが OCaml の好きなところの一つだなーと思う。

% [Erlang] Erlang R12B-0 released.

出た模様。 リリースのハイライトはこちら

大きな目玉は Windows 版に SMP サポートが入ったことか。 まあ、わしにはあんまり関係無いが。 あとは、

  • 実験的な機能だったバイナリ内包表記を正式にサポート
  • ガード節に使える組み込み関数 (BIFs) を二つ追加 (tuple_size/1, byte_size/1)
  • リストやタプル、バイナリなどのリテラルはモジュールごとに定数としてプールされ、最初の一度しか作成されなくなった (てことは、今までは毎回使う都度に作成してたってことか?)
  • ドライバ API に POSIX スレッドに似たマルチスレッド API を追加

というのが主な要素のよう。(訳は適当なので詳しくは原文を見るように)

新しいアプリケーションとして Test Server, Common Test, Percept の三つが追加された。 先の二つは自動テストのためのツールみたいだけど、詳細はよくわからん。 Percept は新しいプロファイリングツールみたい。

とりあえず、テスト関係がちょっと気になるので、ぼちぼち調べる予定。

本日のツッコミ(全1件) [ツッコミを入れる]

% cooldaemon [>ぼちぼち調べる予定。 wktk]


2007-12-06 [長年日記]

% [Erlang] Erlang 5.6

とりあえずてっとり早く Windows 版バイナリを拾ってきていじってみてるところ。 で、気付いたんだけど、さりげなくも重要な変更があったので書いておく。 昨日もリンクしたリリースハイライトのページの最後の 4.7 のところ。

When an exception occurs the Erlang shell now displays the class, the reason, and the stacktrace in a clearer way (rather than dumping the raw EXIT tuples as before).

どういうことかっつーと、たぶん実物を見た方が早い。 今まではこう↓

Eshell V5.5.5  (abort with ^G)
1> A = 1.
1
2> A = 2.

=ERROR REPORT==== 6-Dec-2007::12:28:06 ===
Error in process <0.29.0> with exit value: {{badmatch,2},[{erl_eval,expr,3}]}

** exited: {{badmatch,2},[{erl_eval,expr,3}]} **

で、今度からはこう↓

Eshell V5.6  (abort with ^G)
1> A = 1.
1
2> A = 2.
** exception error: no match of right hand side value 2

要するに今まで大不評だったエラーメッセージが、かなりわかりやすくなったという話。

% [Erlang] Common Test 事始め

User's Guide を見つつ最小のサンプルを書いてみた。

% ls
hoge.erl  hoge_SUITE.erl
% cat hoge.erl
-module(hoge).
-export([f/1]).

f(S) when is_list(S) -> "_" ++ S;
f(S) -> S.
% cat hoge_SUITE.erl
-module(hoge_SUITE).
-compile(export_all).

all() -> [test_f].

test_f() -> [{user_data, [{doc, "add prefix '_' to arg"}]}].
test_f(_Conf) ->
   %% Foo = "foo",
   Foo = 1,
   case hoge:f(Foo) of
      [$_|Foo] -> ok;
      _ -> ct:fail(bad_return_value)
   end.

hoge.erl がテストされるモジュールで、hoge_SUITE.erl がテストモジュール (Common Test の用語では Test Suite) になる。 テストスイートモジュールは基本的に "_SUITE" という接尾語を付ける決まり。 いくつか ct モジュールからコールバックされる関数があって、その内の all/0 は必ず必要。 この関数はテストケース (テスト関数) 名の atom のリストを返す。

で、Unix 系の OS だとここで、シェルから run_test -dir . とかやれば良いみたいなんだけど、Windows だとそのコマンドは無いので、eshell から実行する。 この時点では、ソースファイル以外このディレクトリに存在しないことに注意 (hoge.erl はまだコンパイルされていない)。 ちなみに、この例ではコメントアウトしている箇所 (%% のところの "foo" という値) を敢えて失敗する値 (1) に替えてある。

Eshell V5.6  (abort with ^G)
1> ls().
hoge.erl           hoge_SUITE.erl     
ok
2> ct:run(".").

Common Test: Running make in test directories...
Recompile: hoge
Recompile: hoge_SUITE

CWD set to: "c:/home/jijixi/tmp/common_test/ct_run.nonode@nohost.2007-12-06_13.46.28"

TEST INFO: 1 test(s), 1 case(s) in 1 suite(s)

Testing tmp.common_test: Starting test, 1 test cases

- - - - - - - - - - - - - - - - - - - - - - - - - -
hoge_SUITE:test_f could not be executed
Reason: {test_case_failed,bad_return_value}
- - - - - - - - - - - - - - - - - - - - - - - - - -

Testing tmp.common_test: *** FAILED *** test case 1 of 1
Testing tmp.common_test: TEST COMPLETE, 0 ok, 1 failed of 1 test cases

Updating c:/home/jijixi/tmp/common_test/index.html... done
Updating c:/home/jijixi/tmp/common_test/all_runs.html... done
ok

ct:run を実行すると、ディレクトリ内のソースが必要に応じてコンパイルされて、テストが実行される。 出力結果は、一般的なユニットテストフレームワークに馴染みがあれば、わりと想像がつく内容だと思う。 要するに、各テストケースで何かエラーが起きれば failed で、起きなければ ok ということ。 で、最後に結果を示す html ファイルが出力されてる。

html の方はちょっとここに貼るには大きすぎるので割愛するが、何をやってどういう結果だったというのがまとめられている。 なかなかステキ。

という感じで、今回はユニットテスト的な使い方をしてみたんだけど、どうやらこの Common Test というやつはそれだけのものではないようで、例えば別のマシン上でテストを実行させたりということもできるみたい。 もちろん、Erlang の特性を活かして、今回みたいに直接モジュールの関数を実行するだけじゃなく、別に稼動しているアプリケーションに対してメッセージ通信を使ったりして、ブラックボックステスト的なこともできたりとか、かなり広範囲なシチュエーションで使えるテストフレームワークになっているっぽいね。 もう eunit とかいらないかも。

% [雑談][OCaml] Haskellなんかだとデバッグがえらい大変なイメージがあるんですが、 OCamlはその辺りはどうなんでしょうか……という件

Haskell のデバッグが大変だというイメージが printf デバッグがしにくいとか、そういう類いの話なのであれば、OCaml ではそういう心配は無いです。 OCaml は正格評価で副作用もアリなので、端末出力の関数を使えば使った順番にちゃんと出力されますんで。

あと、再帰関数の動きがイメージしにくい…… とかなら、対話環境で #trace を使うと便利。 ちょうどプログラミング in OCaml にそのネタが書いてあったんで、引用すると…

# let rec fact n = (* n の階乗 *)
    if n = 1 then 1 else fact (n-1) * n;;
val fact : int -> int = <fun>
# #trace fact;;
fact is now traced.
# fact 4;;
fact <-- 4
fact <-- 3
fact <-- 2
fact <-- 1
fact --> 1
fact --> 2
fact --> 6
fact --> 24
- : int = 24
# #untrace fact;;
fact is no longer traced.
# fact 5;;
- : int = 120

<-- が呼び出された時の引数の値, --> が返した値を示しています。

[プログラミング in OCaml p49より引用]

ちなみにこの本、内容はお薦めなんですが、『anonymous function』の訳語が『匿名関数』になっているのが某一部の方には不評かもしれません :-p

…… でも、ほんとに中身はお薦めです。

% [雑談][OCaml] プログラミング in OCaml 名言集

『集』というほど集まってないけど。 っていうか、まだ三分の一しか読んでないけど、つい『あとがき』を読んでしまって、そこ素晴しいお言葉があったのでどうしても引用したくなったっすよ。

再帰関数, ヴァリアントとパターンマッチングをメインに据えたプログラミングにより, プログラムの文面から, そのプログラムが一体何をするのかが読み取り易くなります。そして, 強い型付けにより, プログラムのつまらない間違いを早期に発見し, しかも, 実行時のつまらないエラーの発生を防ぐことができます。

[p351より引用]

強調は原文のまま。 個人的には『つまらない』をさらに強調したいところ(笑)。 ほんと、あのつまらない間違いとかつまらないエラーとかってウンザリするよね。 例えば単純なので言えばこういう↓のね。

irb(main):001:0> @hoge = [1,2]
=> [1, 2]
irb(main):002:0> if @hage.empty? then "empty" else "not empty" end
NoMethodError: undefined method `empty?' for nil:NilClass
 from (irb):2

テストの網羅性に難があったりでミスに気付かず、実際に使い始めてからレアケースでこんなのが出たりすると死にたくなる(苦笑

% [clip][Python] 3.0a1の新機能 (2) (プログラミング日記)

dictのメソッドkeys()、items()、values()がリストでなく文字列を返す。

というのを見て「はあ?何その謎仕様?」と思って原文を見ると…

dict methods .keys(), .items() and .values() return views instead of lists.

と書いてある、"views" ってなんじゃ? とりあえず『文字列』ではないみたいですが?

Python 3.0a1 (py3k:57844, Aug 31 2007, 16:54:27) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {'hoge':1, 'fuga':2}
>>> d
{'fuga': 2, 'hoge': 1}
>>> d.keys()
<dict_keys object at 0x00B6FEA0>

何だかよくわからないオブジェクト。

>>> ks = d.keys()
>>> ks.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute '__dict__'

__dict__ 属性は持っていない模様。

>>> print ks
  File "<stdin>", line 1
    print ks
           ^
SyntaxError: invalid syntax

print が関数になったことを忘れてた(苦笑

>>> print(ks)
<dict_keys object at 0x00B6FE60>

さっきと同じ表示か。

>>> ks.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute 'next'

イテレータではないらしい。

>>> l = list(ks)
>>> l
['fuga', 'hoge']

list 関数に使えるということは一応シーケンス型なんだろうか。

>>> for i in ks:
...   print(i)
...
fuga
hoge

とりあえず for 文にはそのまま使えるようだ。

なんかよくわかんないけど、map とかがイテレータを返すようになったのと関連して、今までシーケンスを返してたような関数は全般的に遅延評価されるような何かを返すようになったってことなのかも。 まあ、views ってのが具体的にどんなものかがイマイチわからないので、なんとも言いようがない部分がある。

% [Python] 3.0a の話、続き

タプル引数のアンパッキングはなくなる。def foo(a, (b, c)):...と書けなくなる。def foo(a, b_c): b, c = b_cと代わりに書く。

絶望した。 好きな機能の一つだったのに……

アンパック代入が拡張される。a, b, *rest = some_sequenceもしくは、*rest, a = stuffなどの構文が使える。restはリストになる。

これは良い。 引数のアンパックが無くなったのって、これの絡みなのか?

本日のツッコミ(全8件) [ツッコミを入れる]

Before...

% ikegami-- [すみません!わたしごときがErlangのエラーメッセージのわかりにくさに文句を言ってすみません!っていうか、Erla..]

% jijixi [エラーメッセージに関しては reddit とかでも大喜びしてる人がいるみたいです。 http://programmi..]

% okagawa [Python 3.0のdictの仕様変更ですが、↓にGuido師によるproposalがありますね。3.0a2でいじ..]


2007-12-07 [長年日記]

% [雑談] 鼻をかみたいのだが、ティッシュの箱が空なのである。だがしかし新しい箱を取りに行くことができない……

なぜかと言うと、今わしのあぐらをかいた脚の上にはぬこ様がぐっすりであらせられるわけで。

こんな状態で仕事ができるわしって、ある意味勝ち組だな…… 貧乏でも心が満たされてれば良いのさ、ふっ…… とか思いつつも、鼻が、鼻がピンチ!!

% [Rails] Rails 2.0 がリリースされたが…

試しに今主に手をかけているプロジェクトを 2.0 で動かしてみたら大量の F と E が出てぐったり。 deprecate warning は潰してあるんだけどなあ……とほほ。 すぐに直せるものもあるけど、何でエラーになるのかよくわからんものもあるんで、簡単には移行できそうにない。

特によくわかんないのが、ActiveRecord::Base#after_find でちょこっとカラムの内容をバラしたりとかしてるんだけど、そこで何故か ActiveRecord::MissingAttributeError が出るんだよね。

if self.respond_to? :hoge and (hoge = self.hoge)
  # 以下 hoge を使ってごにょごにょ

みたいな感じで書いてるんで、当たり前に考えればこの例外が起きるなら respond_to? の時点で false になって self.hoge は実行されないと思うんだけど、respond_to? は true を返してるみたいなんだよな。 まあ、本来 respond_to? は :select オプションを使ったりして hoge 属性が無い場合のために入れてるんだけど、今回の問題は :select を使ってない状態のときに起きてる (要は実際に hoge 属性にアクセスできるはずの状態) んで、なんか微妙にバグくさい気もするんだが。 や、厳密には find じゃなく exists? で起きてるみたいなんで…… って、あ、そうか exists? が :select 使うようになったってことか?

(ソース確かめ中……)

あー、やっぱそうだ。 AR 1.5.6 までは exists? は :select を使ってなかったけど、2.0.1 では使ってるや。 そんで respond_to? の仕様が変わったっていうなら辻褄が合うっぽい?

(さらにソース確かめ中……)

うーん、respond_to? の定義が base.rb から attribite_methods.rb に移ってて、中身も結構変わってるっぽい。 で、ちょっとソースだけだとすっきりわからなかったんで、実際に試してみたところ、やっぱり今までと違って、:select オプションでカラムを絞ったとしても、元のテーブルが持ってるカラムに関しては問答無用で respond_to? が true を返すっぽい。

…… でもこれって仕様として正しいのか? respond_to? が true を返しても良いけど、それならそれで属性にアクセスしたときは nil を返すとかって方が Ruby っぽい気がするんだが。 今まで respond_to? で判断できたところを、いちいち rescue で拾うように直せっての? それとも、何か別の判断方法が用意されてるのかなあ。 要調査か。

しかし、なんでまた、こんな微妙な変更を…… ふぅ(溜息

% [Python] とかなんとかやってるうちに Python 3.0 Alpha 2 が出てやがるぜ

寝させろw

… と文句を言いつつ、てっとり早く試せる Windows 版をダウンロード開始。 悔しいが、こういうときに Windows は役に立つ。

まあ、一番ユーザの多い OS のくせして、素の状態じゃ C コンパイラが存在しないってのが理由なわけで、オープンソース的な視点で見ると歪んでるなぁという気はするけども……


2007-12-08 [長年日記]

% [Python] 3.0a2 が動か〜ん (at Windows XP)

構成がどうのこうのでなんちゃらかんちゃら… とか言って動かんじゃないか。

まあ、きっとうちの環境は OS の再インストールのときにうっかりミスってなぜかシステムドライブが F になっちゃってるという、あまり一般的じゃない環境なんでその辺が関係してるのかもしれないが、やれやれぐったりだ。

しかたないから a1 に戻そう。 インストーラ残しといて正解だった。

% [clip][Python] PEP 3106 -- Revamping dict.keys(), .values() and .items()

okagawa さんのツッコミより。 情報ありがとうございます。

要点をまとめると、

  • .keys(), .values(), .items() はそれぞれ set のような順序付けの無いコンテナオブジェクトを返す
  • .iterkeys(), .itervalues(), .iteritems() といったイテレータを返すメソッドは廃止
  • 最初は keys() その他がイテレータを返すようにしようと思ってたけど、Java Collections Framework を見ると、それよりも set として振る舞うものを返した方が便利みたいだったので、そうした。

イテレータよりもセットの方が便利なシチュエーションの例として以下のコード。

a = d.items()
for k, v in a: ...
# 後で、もう一度
for k, v in a: ...

要はイテレータだと一回使っちゃうと終わりなので、その場合には

for k, v in d.items(): ...

みたいに毎回 items() を呼ばなきゃならなくなって美しくないってことかな。 どうしてもイテレータが欲しいときは iter(d.keys()) とかって書けば良いし、明示的に iter 関数を呼ぶシチュエーションというのはあまり無いので (for 文とかでは暗黙に呼ばれている。上のコード例でもそのはず)、この方がすっきりしてるでしょ…… という話。 他にも、

if a.keys() == b.keys(): ...

という形で、持っているキーが同じかどうか簡単に調べられるとか。

便利か便利でないかの例が微妙すぎる気がしなくもないけど、まあ、そういうものだとわかってしまえば特に不都合がある仕様でもなさそうだし、そういうものだと思って使えば良いんだろうね。

% [Rails] CSRF 対策

どうやら 2.0 でようやく組み込み機能として用意されたみたいだね。 まだ試してないけど、2.0 でプロジェクト作ると config/environments/test.rb に

# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection    = false

って項目があるから、たぶんこれがデフォルトでは true で、ほっとくと CSRF 対策してくれるんだろう。 逆に考えると、今まで独自の方法で対策をしてきてる場合は、production 環境でもここを false にしとかないとおかしなことになりそうな予感。

% [Rails] rake db:create:all # Create all the local databases defined in config/database.yml

くそっ、せっかく自分で一生懸命 task 作ったってのに、さりげなく同じことするのが追加されてやがる。 結局一回しか出番無かったじゃないか...orz

あー、でも権限の設定とかはしてくれないみたいだから、自作版の方がまだ便利か。 まあ、そこら辺は環境によって色々あるだろうし、しかたないかな。

% [Python] immutable のようで実際はそうではない view オブジェクト

The view objects are not directly mutable, but don't implement __hash__(); their value can change if the underlying dict is mutated.

さっきの PEP 3106 の続き。 ざっと訳せば、

view オブジェクト (.keys などが返すもの) は直接的には書き換え不可だが、(辞書のキーになるのに必要な) __hash__ メソッドは定義されていない。 view は元となる辞書が変更されると値が変わるからだ。

といった感じかな。 試してみるとこんな↓ 感じ。

Python 3.0a2 (r30a2:59397:59399, Dec  6 2007, 22:34:52) [MSC v.1500 32 bit (Intel)] on win32
>>> d = {'hoge':1, 'fuga':2}
>>> ks = d.keys()
>>> for k in ks:
        print(k)

fuga
hoge
>>> d['piyo'] = 3
>>> for k in ks:
        print(k)

fuga
piyo
hoge

この例で ks の要素を固定したい場合は、list() や set() で変換してしまう必要がある。

本日のツッコミ(全2件) [ツッコミを入れる]

% きむら(K) [ランタイムライブラリ忘れてませんか? a2はVC++ 9.0でコンパイルされているので、別途そのランタイムを いれと..]

% jijixi [ぬぉーそんなとこまで見とらんかったっす。 これを入れたら動きました、ありがとございます。]


2007-12-09 [長年日記]

% [Rails] 2.0 の CSRF 対策の仕組みとか利用法とか

まだ実際には試してないけど、とりあえずマニュアル (ActionController::RequestForgeryProtection::ClassMethods) はチェックしたので軽くまとめてみる。 あと、ちょっぴりソースも読んでみた。

  • enviroment の設定で config.action_controller.allow_forgery_protection が true の場合 (デフォルト) session[:csrf_id] にユニークな文字列が自動生成されて設定される。
  • この状態で form_tag メソッドを使うと session[:csfr_id] を種としたダイジェスト値 (デフォルトでは SHA1 を使用) が hidden フィールドに設定される。
    • ちなみに form_for なども form_tag を使っているので、Rails の機能でフォームタグを出力する場合は常にそうなると思って良いはず。

ここまでは何もしなくても、勝手に行われること。 で、実際に機能を利用する場合は、以下の操作も必要。

  • ActionController::Base のクラスメソッド protect_from_forgery を使うことで、verify_authenticity_token という before_filter が設定される。
    • 特定のアクションだけを指定したい場合は、通常のフィルタ設定と同様 :only や :except を使う。
    • 他にオプションとして、自動生成される session[:csrf_id] の代わりに指定した種を使うようにする :secret や、ダイジェスト値の計算に使うアルゴリズムを指定する :digest などがある。
  • verify_authenticity_token は正しいリクエストかどうか判断して、そうでない場合は ActionController::InvalidAuthenticityToken 例外を上げる。判断条件は以下。
    • forgery_protection が有効になっていない場合は無条件で true.
    • GET リクエストは無条件で true.
    • HTML か JavaScript 以外のリクエストは無条件で true. (XML のリクエストは未対応)
    • session[:csrf_id] から計算したダイジェスト値と、params に含まれる値 (form_tag が自動で入れたもの) が一致していれば true.
  • InvalidAuthenticityToken 例外はデフォルトでは Rails が rescue してレスポンスに 422 を返す。

ということで、端的にまとめると、2.0 付属の CSRF 対策を利用するには、

  • 利用したいコントローラのクラス定義中で、protect_from_forgery メソッドを使用する。

だけで良いはず。

ただ、ちょっと気になるのは、この実装だと同一セッション中は常に同じトークンが使われる (ように見える。たぶん。) ところかな。 これって、それで良いんだっけ?

ちなみにわしは、色々調べた結果リクエスト毎にその都度別のトークンを生成すべきだと思って、そういう風に実装したものを使ってるんだが、そこまで神経質になる必要無いのかな。 まあ、そういう実装にすると、使うときにちょっと面倒なのは確かなんだよな。 例えば、POST されたデータがよくないのでフォームページに差し戻し… ってときに、render :action でフォームページを表示したりするときには、その都度手動でトークンを設定してやらないといけなくなるし (この前グチったけど、render :action は実際にはアクションとは関係無いので、フィルタが動いてくれないのだ)。 セッション毎のトークンなら、その辺気にしないで良いしね。

まあ、そういうことなのかな。 厳密さを重視して面倒さと凡ミスが入る余地を残すより、ある程度の厳密さに留めることで使いやすさを重視したというか。

ともあれ、自前で仕組みを用意していない場合には、簡単に導入できて、それなりの効果が期待できるものにはなってると思うので、今まで対策を施していなかった人はとっとと 2.0 に移行するのが吉かも。

% [雑談] JoCaml のメーリングリストが Reply-To を付けて寄こさないのが激しくウザい

おかげで、また ML じゃなく本人宛てにリプライしちゃったよ...orz

% [clip][Rails] Rails 2.0のセッション話 (moroの日記)

どっかに、「いらなくなったセッションファイルを cron で掃除とかしなくて良くなってウマ〜」(かなりうろ覚えの上に意訳) とか書いてあったヤツかな。 つーか、それ以外の利点がイマイチよくわかってないんだけど、どうなんだろか。

% [Rails] 2.0 の小ネタ

ActionController::TestCase というクラスができてて、script/generate が生成する functional test の雛形はそれを継承するようになった。 その結果、今までファイルの頭の方にごちゃごちゃ書いてあったものが無くなって、見た目がすっきり。

でも、裏でやってることは今までとあまり変わらないので、注意が必要なこともある。 例えば、自分で setup メソッドを書きたいときは、super を忘れずに…とか。

他にも script/generate scaffold の挙動が変わってたり (今までのように既存のモデルを元にするのではなく、モデルの生成からするようになった)、微妙な変更が結構あって迷うことが多々ある。

今まで config/environment.rb に書いていた初期処理などは、config/initializers 以下にスタブファイルを用意して書くのが推奨される模様。

% [Rails] 2.0 の小ネタその2

そうそう、Erb テンプレートファイルの拡張子が、.rhtml から .html.erb になってる。 今までの形式も使えるようだけど、自動生成されるのは後者なので、これからはこちらが推奨されるんだろう。

本日のツッコミ(全2件) [ツッコミを入れる]

% cooldaemon [CSRF の対策に関してですが、私は ログイン管理を行っているウェブサービスであれば ワンタイムトークンを使ってませ..]

% jijixi [うーん、二つ目の方のページを読んだ感じだと、Rails 2.0 の方式で十分だって感じはしてきました。 なら、2.0..]


2007-12-11 [長年日記]

% [雑談] インタプリタでも?

きむら(k)さんとこ経由で k.inaba さんとこ。 いやまあ、経由するまでもなく読んではいるんだけど……

Brainf*ckの日本語訳は

のーみそコネコネ としたい。

それは良いですね♪

「それはインタプリタでも良いの?」 と、わかる人にだけわかるネタを思いついただけ。

(念の為追記) k.inaba さんはグーグルの結果にリンクを貼ってるので、わかってて書いてるんだと思うし、きむら(k)さんもたぶんわかってるんだと思う。

% [Rails][雑談] どうせなら 2.0 の方が良いので、新規の (あるいはほぼ新規に近い) プロジェクトは 2.0 で行こうと思い、関係するプラグインの互換性チェックをちまちまと

やっている。 あとまあ、自作のライブラリ (ほんとはプラグインにしたいんだけど、まだやってない) に関しても同様に。

で、おもしろいのが、実際のコードよりもテストコードが原因でテストが失敗する例が結構多いこと。 通常のコードは公開されたインターフェイスを使って書いてるから互換性の問題が出にくいけど、テストの方が結構技巧を凝らして (悪く言えばバッドノウハウ的に) Rails の仕組みの内部に突っ込んだ書き方をしてたりするので、そこら辺が微妙に変わってたりするとアウツなわけね。

みんなテストコードの書き方には苦労してるのね…… とか微笑ましく思った。

それでも、Rails のテストの統合度はかなりのものだと思うけど。 この前 Django をちょろっと調べたときは、機能は Rails に負けてないけど、テストの仕組みが弱そうだなと感じたし (ちょっとしか調べてないから事実に反するかもしれないけど)。 Django のテストを書くんじゃなく、Python のテストを書くって感じなんだよね、Django だと。 Rails はちゃんと Rails のテストを書ける。 この、「テストコードを書くときにフレームワークの内部に潜らないといけないか否か」の比率は結構大きい気がする。 (もちろん、Rails だって内部に潜らないといけないことは往々にしてあるけどね)

やっぱり動的型付け言語を仕事で書くんであれば、TDD のし易さは重要なポイントじゃないかと思う。 静的型付け言語に感じる安心感に近いものを、TDD は提供してくれるから。 …… 微妙に個人的な趣味の話になってる気もするけど(苦笑

その辺、他のフレームワークはどうなのかな。 少なくとも、Django はテストを書くのがめんどくさそうなので、まだ仕事で使うのはちょっとイヤかなと感じた。 Python ならではの安心感というのは確かにあるので、今後に期待はしてるけど。

% [clip] クトゥルフ神話より (アルファルファモザ使い lv.1)

ちょwww この >>565 は天才www

本日のツッコミ(全3件) [ツッコミを入れる]

% k.inaba [出自からして > 開発者Urban M&uuml;llerがコンパイラがなるべく小さくなる言語として考案した。 らし..]

% jijixi [おお、なんかキレイにまとまったw]

% きむら(K) [ああ、なんか置いてきぼりにされた気分w]


2007-12-12 [長年日記]

% [clip] sm1735574 (忙しい人のための 「熱血αドッコイダー」)

キャシャーンでノックアウトされて以来チェックしている mylist/2967614/3339988 は、ニコユーザなら確実にブックマークしておくべき。 まあ、わしの場合、残念ながらアイマスは完全に守備範囲外なので、楽しめるのはおっさんホイホイ系だけなんだが。 で、今回のこれは元ネタを知らないんだけど、

ハイパワーガチンコ裏返しファイヤー

で死んだ。ほんとにそう聴こえるから困るw

% [clip] sm1144128 (忙しい人のためのラジオ体操第一)

鼻水吹いたw

% [雑談][Rails] Pure Ruby で ActiveRecord に使える (簡易的な) データベースアプリは無いものか

特定のモデルに依存しない機能のテストのために、気軽に使えるようなものが欲しいってことなんだけど、何か無いのかねえ。 とりあえず、現状で AR にアダプタが存在する中から考えるなら SQLite が良いのかなという気がするんだけど (DB がファイルだからそれごとテストデータとして配布できるし)、SQLite の本体をインストールする手間はかかるしなあ。 gem だけで完結できるようなものがあれば良いんだけど。

本日のツッコミ(全9件) [ツッコミを入れる]

Before...

% jijixi [つーか、自分でプラグインをいじっちゃうような人は、多少のことは自前で解決しちゃうだろうから、気にするだけ無駄なのかな..]

% cooldaemon [AR 用の Mock って無いんですかね? http://snippets.dzone.com/posts/show..]

% jijixi [単体のレコードとしては使えそうですね。 テーブル作ってないので、たぶん find とかのクラスメソッドを使おうとする..]


2007-12-13 [長年日記]

% [雑談] 宣言通り洗脳電波が発信されたようなので受信してみた

なるほどなるほど、北海道民には縁が無い代物でしたか。 そりゃマニアでもなきゃ知る由もない。 まあ、ぽてまよだって某アレなサービスが無かったら知らないままだったに違いないし、北海道なんてそんなとこっすよ。 グローバルな損得は知らんけど、某アレは少なくともアニメ視聴者の裾野拡大に一役買ってるとは思うよ。

しかし、TSUTAYA DISCAS なんつーサービスがあったなんて初めて知った。 料金も手頃だし、便利なことは便利なんだろうけど、一度に二枚ずつしか手元に寄こさないというのがちょっとわしのライフスタイルに合わないな。 1 クール物だったら、土日で一気に見てしまいたいって感じなんだけど、これじゃそういうのは無理だ。

ま、近所のレンタル屋を物色してみて、ダメだったら考えよう。 …… あれ?なんか見ること前提になってない?良いのかそれで?

% [雑談] なんか試しに某所でちょろっと検索してみたらあるし……

とりあえずこれで良いや。色々説明してくれる人がいるからわかりやすいし(ぉぃ

% [Ruby] Hash の map は Hash を返せという話

この辺

まあ、わしも Hash を返してくれると嬉しい気はするんだけど。 ただ、map/collect メソッドというのは Enumerable モジュールで定義されていて、each メソッドさえあれば共通して使えるということになってるのが、美しいと言えば美しいので、その挙動を敢えて変更するのもどうなんだろうなぁという気もする。 やっぱペアの配列に to_hash するとハッシュができるってのが無難じゃないかな。

ところで ujihisa さんがコメントで書いてる方法は、flatten が罠たっぷりなので汎用的な方法としてはよろしくない。 (参考)

本日のツッコミ(全4件) [ツッコミを入れる]

Before...

% jijixi [元と同じクラスで返してくれる汎用的な map を作るのって難しそうですよね。 結局各クラスで何とかするしかないのかな..]

% takkanm [>map/collect メソッドというのは Enumerable モジュールで定義されていて、each メソッドさ..]

% jijixi [実際、Hash から Hash を作りたいシチュエーションはかなり多い気がするんで、なにかそういうメソッドが組み込み..]


2007-12-14 [長年日記]

% [Rails][ActiveRecord] 型指定名の拡張

ここで言う型指定名というのは、migration ファイルなどで使う、

t.column 'hoge', :string

みたいなのの、:string のことね。

で、例えば MySQL を使ってて、何か大きなバイナリを保持するテーブルが欲しいとき、

t.column 'hoge', :binary

とかだと、実はちょっとよろしくなくて、なぜかと言うと、MySQL の場合 :binary は BLOB 型として扱われるために、'大きな' バイナリにはちょっと向かないのだ (BLOB に保存できる最大値は 2^16 bytes)。 で、もっと大きなデータを扱いたいと思うなら、例えば LONGBLOB 型を使ったりという話になるんだけど、デフォルトではこれに対応する型指定名は定義されていなくて、簡単には使えない。

で、そういうときにどうやってごまかすのが良いのかな〜と色々考えて、結局こうするのが一番すっきりしてるかなというのが以下。 (思い付いたばかりで、ちゃんとテストとかしたわけじゃないので、利用の際は気をつけて)

module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter < AbstractAdapter
      def native_database_types_with_additionals
        native_database_types_without_additionals.merge(
          :long_binary => { :name => 'longblob' }
        )   
      end 
      alias_method_chain :native_database_types, :additionals
    end 
  end 
end

これをどこか最初のうちに読み込まれるような場所に書いておく (config/environment.rb とか、2.0 以降なら config/initializers/ 以下に適当にファイルを用意するとか)。 :long_binary という名前は適当だけど、'longblob' は実際に SQL 文に使われるものなので、ちゃんと該当する DB アプリケーションで正しく使えるものを使う。

ちなみに native_database_types というメソッドは ActiveRecord の connection_adapters/abstract/schema_statements.rb で定義されていて、それぞれのアダプタの定義ファイル (MySQL であれば connection_adapters/mysql_adapters.rb) でオーバーライドされている。 このメソッドは schema_dumper.rb なんかでも利用されてるので、このように追加しておけば、db/schema.rb が作られるときにも、ちゃんと定義したものが使われてくれるはず (実はまだ試してないんだけど)。

追加する型によっては、type_cast 系のメソッドもいじらないといけないかも知れないけど、とりあえずバイナリ系の型ならそのままで良いんじゃないかと思う。 …… でも真偽にほどは不明。

あと、2.0 以降なら t.long_binary みたいに書けるようにメソッドを追加しておいた方が良いかも。 この辺のメソッドは connection_adapters/abstract/schema_definitions.rb で ActiveRecord::ConnectionAdapters::TableDefinition クラスに対して定義されてるので (430 行目付近) 同じようにこのクラスに定義してやれば良いと思う。


2007-12-15 [長年日記]

% [雑談] 住めば都のコスモス荘を一気に見た

これはもっと評価されるべき。 熱血ヒーローものの王道的展開を、ここまで完璧に料理した作品というのはそうそう無いと思う。 絵だけ見れば、どう見たってカッコ悪いのに、なんだあの最後の方のカッコ良さは(笑

中盤のお笑いパートも、勘違いの連鎖で進む話とかそういうお約束が楽しい。 なんか期待値の三倍くらい楽しめた。

んで、まあ、ちょっぴり DVD が欲しくなったんだけども、6,000 円が 6 本で 36,000 円はさすがにキツいなあ。 10,000 円くらいで揃うなら即決なんだけど……

今時はゲームとか大作映画なんかだと、発売後しばらくすると廉価版が出たりするもんだけど、アニメでもそういう商売の仕方ってできないもんなのかね。 パッケージなんぞ安っぽくて良いし、綺麗なブックレットなんかもいらんから手頃な値段で売ってくれよ、と思うんだが。

本日のツッコミ(全2件) [ツッコミを入れる]

% きむら(K) [えー、北米版でよければ安く買えますです。 リージョンコードが違いますが、日本語音声も収録されているはずです。 ht..]

% jijixi [……なんか怒りが込み上げるほどの値段の違いですね(苦笑]


2007-12-17 [長年日記]

% [tDiary] 2.2.0 にアップデート

した。 諸般の事情により RSS が文字化けするという問題が出たものの、とりあえず Quick Hack でしのいだり。

念の為、ことわっておくと、これは tDiary の不具合とかではなくて、ここのサイトの Ruby がわりと微妙なバージョンだからだったりする。 残念ながら、その辺を根本的に何とかする権限はわしには無いので、まあ当面は小手先でしのぐしかないのであった。


2007-12-18 [長年日記]

% [雑談][Rails] 2.0.2 が出たらしいが……

何度やっても例のアレ↓

ERROR:  While executing gem ... (OpenURI::HTTPError)
    404 Not Found

gem 本体もアップグレードすべきなんだろうか。 とりあえず今はこう↓

% gem -v
0.9.4

なんだが、0.9.5 対応がどうのこうのとか書いてたような気もするし。


2007-12-19 [長年日記]

% [Ruby][Rails] gem 本体をアップデートしてみた

やり方はどっかで見たのをうろ覚えでこんな感じで↓

% sudo gem update --system

もちろん、sudo がいらない環境の人は付けんでもよろしい。 んで、あらためて

% sudo gem install rails

でサクっと 2.0.2 はインストールされた。

なんか gem 0.9.5 って 0.9.4 から結構色々変わってるっぽくて、依存する gem はデフォルトだと確認せずにインストールするとか、gem list の出力がすっきりしてるとか、ちょっといじって気付くだけでも、これくらい違う。 全体的に出力されるメッセージがすっきりした感じがするんで、特に理由が無いならとっととアップグレードしてしまうのが吉やもしれず。


2007-12-20 [長年日記]

% [Rails] foxy migration

狐のように狡猾なのか、狐のように美しいのか、どっちの意味なんだろね。 ってのはともかく、今までこんな風に↓ 書いてたのが……

create_table :foos do |t|
  t.column :bar, :string
  t.column :baz, :string
  t.column :hoge_id, :integer
  t.column :created_at, :datetime
  t.column :updated_at, :datetime
end

2.0 以降ではこう↓ 書ける。

create_table :foos do |t|
  t.string :bar, :baz
  t.references :hoge
  t.timestamps
end

型名をメソッドとして使えるのはともかく、同じオプションの場合は複数のカラムを一回で定義できるところや、timestamps で決まり文句の created_at と updated_at を一発定義できるのはすっきりしているね。 で、さらに目玉は references か。 今までは belongs_to のために、わざわざ規約に沿った名前のカラムを自分で設定しなきゃならなかったんだけど、暗黙に決まってる名前を自分で書くって何かイケてない気がしたわけで、今回からはそこら辺ちゃんとやってくれるようになってめでたし。

でもまあ、そういう手当がされてるのって create_table を使うときだけなんだよな。 既存のテーブルに belongs_to 用やタイムスタンプ用のカラムを付け足したいときなんかは、今までと同じように add_column を使わないといかん。 ちょっと片手落ちな感もある。 カラムの定義時に一緒に index を付ける指定とかは、相変わらず存在しないみたいだし。

% [Rails][ActiveRecord] 続・型指定名の拡張

この前のネタの続き。 やっぱりあれだけだと、色々うまくいかないところもあったので、少し追加してみた。

module ActiveRecord
  module ConnectionAdapters
    class MysqlAdapter < AbstractAdapter
      def native_database_types_with_additionals
        native_database_types_without_additionals.merge(
          :long_binary => { :name => 'longblob' }
        )
      end
      alias_method_chain :native_database_types, :additionals
    end

    class MysqlColumn < Column
      def simplified_type_with_additionals(sql_type)
        case sql_type
        when /longblob/i
          :long_binary
        else
          simplified_type_without_additionals(sql_type)
        end
      end
      alias_method_chain :simplified_type, :additionals
    end

    class TableDefinition
      %w( long_binary ).each do |column_type|
        class_eval <<-EOV
          def #{column_type}(*args)
            options = args.extract_options!
            column_names = args
            
            column_names.each { |name| column(name, '#{column_type}', options) }
          end
        EOV
      end
    end
  end
end

MysqlAdapter に関しては前回のまま。 MysqlColumn への追加は SchemaDumper のため。 で、TableDefinition への追加もそのためで、これは例の foxy migration 方式でダンプされることに対する対処。 定義自体は、connection_adapters/abstract/schema_definitions.rb からコピペして、型名のリストを書き換えただけ。

これで多分、単純な使い方の範囲はカバーできたような気がするが、まだ何かある予感の方が強かったりもする(の

% [Rails] 2.0.2 になってから functional test がおかしい

2.0 になって functional test に Test::Unit::TestCase じゃなく ActionController::TestCase というクラスが使われるようになったのはこの前書いたが、2.0.2 にアップデートしたらなぜかこいつの setup メソッドをオーバーライドできなくなってて困った。

オーバーライドできないっつーか、オーバーライドしたつもりなのに実行されない (ActionController::TestCase の setup は実行される)。 2.0.1 ではちゃんと実行されるから、どこか挙動が変わったんだろうけど、一体全体どんな変更があったらこんなことになるんだ? つーか setup 書けないとめんどくさいんだけど、どうやって対処したら良いんだ、これは。


2007-12-21 [長年日記]

% [Rails] 続・2.0.2 になってから functional test がおかしい (対症療法だけは発見編)

昨日の件を未だ調査中。

わからん、なんでこうなるのか全然わからん。 TestCase#run を書き換えてるところがあるのかと思って探してみたけど、そういう箇所は見当たらない。

で、ふと思いついて、setup じゃなく setup_without_fixtures をオーバーライドしてみたら…… う・ご・く...orz

なんだこりゃ。 ちなみに、setup_without_fixtures ってのがどっから出てくるかと言うと、active_record/fixtures.rb だったりして、そりゃ action_controller 以下ばっか探してても見つからんよなと。

で、もう少し調べると setup_without_fixtures の定義は method_added で行なわれていて (method_added ってよく知らないけど、要するにメソッドが追加されたときに呼ばれるコールバックらしい)、こいつの定義が 2.0.1 から 2.0.2 になってちょっと変わっている。 今までは、

  • setup というメソッドが定義されると…
    • setup_without_fixtures が定義されていない場合に
      • setup の別名として setup_without_fixtures を設定
      • 新たに setup_with_fixtures と setup_without_fixtures を呼ぶ setup メソッドを定義

という流れだった。 setup_with_fixtures はすぐそばで定義してある普通のメソッド。 これが 2.0.2 では、

  • setup というメソッドが定義されると…
    • setup_without_fixtures が定義されていない場合に
      • setup の別名として setup_without_fixtures を設定 (ここまでは同じ)
      • 新たに full_setup というメソッドを定義 (中身は setup_(with|without)_fixtures を呼ぶだけ)
    • full_setup の別名として setup を設定

となっている。

最初、「別に今までと変わんないじゃん?」と思ったんだけど、じっくりソースを見てようやく気付いた。 最後の alias 作るところの場所が良くねえよ、これ。 該当する部分のソースを貼ろう。

(active_record/fixtures.rb)
975  unless method_defined?(:setup_without_fixtures)
976    alias_method :setup_without_fixtures, :setup
977    define_method(:full_setup) do
978      setup_with_fixtures
979      setup_without_fixtures
980    end
981  end
982  alias_method :setup, :full_setup

これは、setup というメソッドが定義された場合に実行される部分。 ActionController::TestCase の定義時に setup が定義されているので、こいつを継承したクラスには当然すでに setup_without_fixtures が定義済みになる。 すると、何もせずに問答無用で full_setup の別名として setup が定義される。 この時点の full_setup の定義は、ActionController::TestCase が元々持っているものだ。 そうすると当然、せっかく定義した setup を隠す形になってしまう。

…… アホか、これ、バグだろ。 982 行目の alias_method は unless ブロックの中に入れるのが普通じゃないのか。 それとも、一回しか setup の定義を許さないという意思表示なのか? それならそれで、自分で setup を定義したいときのための手段を用意すべきだろうに。

なんかどっちにしても「死ね」って感じだけど、ともかく、この実装が変更されない内は、ActionController::TestCase のサブクラスで setup を定義したいときは setup じゃなく setup_without_fixtures を定義 (オーバーライド) せよ、というのが当面の回避法のようで。 あと、その場合は、この前も書いたけど super を忘れずに。

% [Rails] 2.0.2 になったら Erubis が使えなくなってて悔しい

2.0.1 までは普通に使えてるっぽいのに。 せっかく新規プロジェクトでは Erubis 使おうと思ってたのに。 つーか、2.0.1 から 2.0.2 で ActionView 関係の変更多すぎ。

テンプレート関係がクラスに分けられてスパッと切り離されてたりするので、その関係で内部的なメソッドの挙動が思いっきり変わってたりすんの。 自作のライブラリもそのせいで一つ修正を余儀なくされたんだけど、Erubis もそこら辺にモロ引っかかったぽいなぁ。

しかしまあ、色々と問題を起こしてくれるバージョンだよ 2.0.2 は……

% [Rails] Erubis の件は…

2.0.2 でのテンプレート関連の変更はテンプレートエンジンの取り替えが容易になるようにするもの…… という印象なので、近いうちに Erubis の方で対処してくれるんじゃないかなーと期待。

ちなみに、どんな風に変わってるのかと言うと、ざっとソースを眺めたかぎりでは、

  • テンプレート文字列を受け取って Ruby のソース文字列を返す compile というメソッドを持ったクラスを用意する
  • ActionView::Base.register_template_handler(extension, klass) で拡張子とクラスを関連付ける

これだけで良いっぽい。 register_template_handler じゃなく register_default_template_handler で登録すると、拡張子に該当するハンドラが無い場合にも使われる。

とりあえず、Erubis::Helpers::RailsHelper のソースを見た感じ、わりと簡単に対応できそうな気がするんで、ちょっくら自分で書いちゃろうかな… とか思ったけど、これだけ簡単そうなら多分とっくに誰かが手を付けてるだろうと思って止めた。 一生懸命書いた後に、gem update したらサクッと Erubis がバージョンアップしてたり…… っていうシチュが目に浮かんで怖い(苦笑

% [雑談][Ruby] 何に気なしに gem update したら gem のバージョンが 1.0.1 になってしまった件

もしかしたら Erubis のバージョン上がってないかなーとか思いつつ、gem update してみたんだけど、なぜか gem 本体も勝手にアップデートされてしまった (残念ながら Erubis のアップデートは無し)。

0.9.5 から gem 本体もデフォルトでアップデートするようになったってことかいな。 まあ、1.0.1 の方が正式版っぽいバージョンだから良いけども。


2007-12-23 [長年日記]

% [雑談] 住めば都のコスモス荘 (マンガ版)

近所で一番大きい本屋 (一応札幌にもそう何件も無い程度にデカい) でなんとなく探してみたら、あっさり見付かったという。 いやぁ、探してみるもんだね。

で、これはこれでおもしろかった。 でもやっぱ、最後の熱さではアニメ版にかなわないな。 つーかアニメ版が反則的にカッコ良すぎるから(苦笑


2007-12-24 [長年日記]

% [雑談] こりゃまたなんとも古いものを(苦笑

ref.

static 変数の件は 0 に初期化されるように保証されてるのが正しいはずです。 たぶんその時点では知らなかったか、何か勘違いしてたんでしょう。 もしかすると、そうじゃなく何か違う意味があったのかも知れないけど、具体的な思考経路は思い出せないや。

ビット演算の結果をそのまま真偽値として使うのは、今でも許せないなあ。 そういうことが「できる」ってことと、実際にそれを「する」ってのは別の話で、データの意味を厳密に区別せずにああいう書き方をしちゃうのはゴルファーだけで良いと思うですよ。

ちなみにこの時どうして Linux のコードなんか読んでたかと言うと、たしか 3mode FDD を使えるようにするパッチがあって、それを自分の持ってる FDD コントローラにも対応させるためだったはず。

% [clip][雑談] kwskk

shinh さんがまた何かおもろいもん作った模様。 OS ネイティブで使えるのが欲しいなあ。

ちなみに「食い合」は「KiaW」で良いんじゃないかなあ (現状でもこれで出る)。 要するにかな一個にキーストローク一回というルールが簡単で良いんじゃないかと。


2007-12-25 [長年日記]

% [雑談] えー、だってアセンブリの条件ジャンプはそもそも 0 かそうじゃないかを比べるじゃないっすか

でも、C は一応高級言語なんだから、例え結果的に同じでもやっぱコードの意味がはっきりするように書くべきだと思うなあ。 昔々の、コンパイラがせいぜい高級アセンブラだった頃ならともかく、今はそこら辺の最適化はやってくれると思うし。

まあ、わしは ML とかにハマる人間なんで、C のこういう良くも悪くも適当なところが必要以上に気になるという部分はあるやも知れず(苦笑

本日のツッコミ(全14件) [ツッコミを入れる]

Before...

% jijixi [ん?なんかこんがらがってきた。 それは FFFF:FFFF というビットパターンが値としての 0 を表わす処理系っ..]

% shiro [後者です。記憶にたよって書いてたらまたぐだぐだになりそうなのでC FAQをチェックしてみました。 http://c..]

% jijixi [ふむふむ、空ポインタ定数がどんな値を持っていたとしても、ポインタとしての文脈における 0 は空ポインタを表わすってこ..]


2007-12-27 [長年日記]

% [game] みんゴルポータブル2なんてのが出ていた件

スパロボ OG 外伝を買いに行ってついでに見付けたんで保護。 こんなの出てたなんて、全然知らんかった。 つか、PSP の存在を忘れてたよ。 当然のようにバッテリーは完全放電しちゃってるし(苦笑

ああ、これで年末年始は、ほとんど OG 外伝とこれやってすごすこと決定だろなあ。 なんとも駄目人間すぎる正月だが、本人は何の不満も持っていないので、まあそれで良いんですよ。(何を他人事のように…)

% [game] OG 外伝のデモを垂れ流し中

BGM というか BGV というか。

Compact3 の主人公機がカッコ良すぎる。 ワンダースワンで見たときはパッとしない感じだったけど、やっぱこういう格闘系の機体は動いてなんぼだなあ。

他にはダイゼンガーがゼネラルブラスターを撃ってたり、エクサランスの最終フレームが出てたりサービス満点やね。 そういやエクサランスは砲撃戦用フレーム (名前忘れた) がまだ出てなかった気がするけど、今回は出るのかな。

% [game] 誘惑に負けて、ちょっとだけ OG 外伝を始めてみた

クライウルヴズ、キタコレ。

どうすんだろ、これ。 ガルムレイドとか出るんかな。 それとも OG3 に向けての顔出しだけかな。

やばい、気になりすぎる。 この辺で止めとかないと、止められなくなっちゃうな(苦笑

% [Ruby] 1.9.0 を入れたので、m17n 関係をいじってみようと思ったんだが

1.9.0 に対応したというリファレンスマニュアルString のページを見てみるも、『マルチバイト文字列の処理』の辺りには以前と同じことしか書いてなくてショボン。 $KCODE なんてもう無いんですけど。

% irb19
irb(main):001:0> $KCODE
(irb):1: warning: variable $KCODE is no longer effective
=> nil

メーリングリストの議論とか全然まじめに追い掛けてなかったんで、なんとなくしか方向性がわかんないんだけど、この辺の仕組みについてまとまってるページとか無いっすかね。 とりあえず、わしが認識してるのは、

  • 内部コードのようなものは存在せず、文字列のインスタンスそれぞれがエンコーディングについての情報を持っている。
  • インスタンスは自分が持っているエンコーディング情報に基いて文字数とかインデックスに関する処理をする。

くらいかな。 で、知りたいのは、

  • 特定のエンコーディングで書かれたソースコードがあったとして、そこに書かれた文字列リテラルがきちんと正しいエンコーディング情報を持って読み込まれるようにするには何をすべきか?
  • エンコーディングが一致しない文字列同士を連結する際には、どのような動作をするのか?

とかかなあ。

% [game] OG 外伝日記、今はいったいいつなんでしょうか編

とりあえず最初の 2 話は OG2 の最終決戦の裏側なんだけど、その次がいつの話をしてるのかよくわからん。 っていうか、カイが「ラミア達についていけるぐらいの技量を…」 とか言ってるってことは、まだラミアが生きてるってことだろ。 とすると 2.5 の前なのか?

デモとかでも 2.5 ですでに死んでる人が出てきてたりするし、時間軸的には 2 の直後から始まってるってことなのかねえ。 つーか、外伝全体が 2.5 という扱いのようだが。

% [game] OG 外伝日記、6 話が 2.5 の 1 話だった模様

えー…… で、なに、この後十数話も前と同じことやらされるの? すげぇかったるいんですけど。

すでに OGs で 2.5 をクリアしてるのはわかってるんだから (最初にクリアデータの確認がある)、その場合はすでにやったとこ飛ばせるようにしてよ。

本日のツッコミ(全2件) [ツッコミを入れる]

% odz [Python と同じでスクリプト先頭に coding: utf-8 とかあると、スクリプトのエンコーディングを認識し..]

% jijixi [おお、情報ありがとうございます。]


2007-12-28 [長年日記]

% [Ruby] m17n お試し

odz さんが教えてくれたので、試してみた。

% cat eucjp.rb|nkf -w
# -*- encoding:euc-jp -*-
EUCJP = "ほげふが"
% cat sjis.rb|nkf -w
# -*- encoding:sjis -*-
SJIS = "ほげふが"
% cat utf8.rb
# -*- encoding:utf-8 -*-
UTF8 = "ほげふが"
% irb19
irb(main):001:0> require 'sjis'
=> true
irb(main):002:0> require 'eucjp'
=> true
irb(main):003:0> require 'utf8'
=> true
irb(main):004:0> SJIS.encoding
=> #<Encoding:Shift_JIS>
irb(main):005:0> EUCJP.encoding
=> #<Encoding:EUC-JP>
irb(main):006:0> UTF8.encoding
=> #<Encoding:UTF-8>

安心設計。

irb(main):009:0> require 'kconv'
=> true
irb(main):012:0> UTF8 + EUCJP
ArgumentError: character encodings differ
 from (irb):12
 from /usr/local/lib/ruby/1.9.0/irb.rb:150:in `block (2 levels) in eval_input'
 from /usr/local/lib/ruby/1.9.0/irb.rb:259:in `signal_status'
 from /usr/local/lib/ruby/1.9.0/irb.rb:147:in `block in eval_input'
 from /usr/local/lib/ruby/1.9.0/irb.rb:146:in `eval_input'
 from /usr/local/lib/ruby/1.9.0/irb.rb:70:in `block in start'
 from /usr/local/lib/ruby/1.9.0/irb.rb:69:in `catch'
 from /usr/local/lib/ruby/1.9.0/irb.rb:69:in `start'
 from /usr/local/bin/irb19:13:in `<main>'
irb(main):013:0> UTF8 + EUCJP.toutf8
=> "ほげふがほげふが"
irb(main):014:0> _.encoding
=> #<Encoding:UTF-8>

ふむ。

irb(main):015:0> UTF8 + "foo"
=> "ほげふがfoo"
irb(main):016:0> _.encoding
=> #<Encoding:UTF-8>
irb(main):018:0> 'foo'.encoding
=> #<Encoding:ASCII-8BIT>
irb(main):019:0> 'foo' + UTF8
=> "fooほげふが"
irb(main):020:0> _.encoding
=> #<Encoding:UTF-8>

そういや、結局バイナリを示すエンコーディングを導入する・しないって話はどうなったんだろね。 バイナリ同士でしか連結できないような仕組みはあった方が便利な気はするけど。

irb(main):022:0> s = open('sjis.rb', 'r:sjis:utf-8'){|io| io.read}
=> "# -*- encoding:sjis -*-\nSJIS = \"ほげふが\"\n"
irb(main):023:0> s.encoding
=> #<Encoding:UTF-8>

IO 関係。自動識別は無いのかな。

irb(main):027:0> s = open('sjis.rb', 'r:sjis'){|io| io.read}
=> "# -*- encoding:sjis -*-\nSJIS = \"????\"\n"
irb(main):028:0> s.encoding
=> #<Encoding:Shift_JIS>
irb(main):029:0> s = open('sjis.rb', 'r'){|io| io.read}
=> "# -*- encoding:sjis -*-\nSJIS = \"\x82\xB0\x82\xAA\"\n"
irb(main):030:0> s.encoding
=> #<Encoding:UTF-8>

何も指定しないと、UTF-8 なのか?それとも LANG が関係してるのかな。

irb(main):001:0> ENV['LANG']
=> "ja_JP.eucJP"
irb(main):002:0> s = open('sjis.rb'){|io| io.read}
=> "# -*- encoding:sjis -*-\nSJIS = \"\x82\xD9\x82\xB0\x82\xD3\x82\xAA\"\n"
irb(main):003:0> s.encoding
=> #<Encoding:EUC-JP>

ふむ、LANG に依存してるっぽい。 なんかこれだと、LANG の設定によらずに同じように動くスクリプトを書こうとすると面倒が多そうな気がしないでもないなあ。 どうなんだろ。

% cat test.rb
#!/usr/local/bin/ruby19
# -*- encoding:utf-8 -*-
s = open('eucjp.rb') {|io| io.read}
p s.encoding
puts s
% LANG=ja_JP.eucJP ./test.rb
#<Encoding:EUC-JP>
# -*- encoding:utf-8 -*-
UTF8 = "ほげふが"

% LANG=ja_JP.UTF-8 ./test.rb
#<Encoding:UTF-8>
# -*- encoding:utf-8 -*-
UTF8 = "ほげふが"

うーん、なんかデフォルトのエンコーディングを設定する方法あるのかな。 まあ、どっちみちエンコーディングの指定無しに読み込んでも、別に正しい設定がされるわけではないし、結局ちゃんと指定して読み込まないと意味が無いとなれば、そんなもの無くても同じかもしれないが。

% [雑談] せっかくこれから休みだというのに、さっそく風邪をひいた件

ツいているのやら、ツいていないのやら、と友達に漏らしたら「それは憑いてるね」と言われたょ。 イヤン。

まあ、どうせゴロゴロしてる予定しか無いわけだし、風邪ひいてても別に良いか。 インフルエンザではないし。

% [game] OG 外伝日記、分岐あったよ

2.5 と同じルートと、その裏側のルートを選択できるらしい。 あー良かった。

まあ、すでに三話ほど同じことやらされてるし、後でまた何話かはやらされるんだろうけど、丸々同じのやらされるよりはマシだわね。

本日のツッコミ(全4件) [ツッコミを入れる]

Before...

% jijixi [デフォルトで勝手に自動識別されると困るでしょうけど、例えば 'r:japan:utf-8' とかって指定..]

% きむら(K) [ん、じゃあそれを提案してもらうという方向で :) あーでも言語(or 国)の指定文字列はISO(幾つだっけ?)のを..]

% jijixi [でも冷静に考えると、実際実装しようとすると困るような気がしてきました。 IO の場合、どの時点で自動識別処理をして..]


2007-12-31 [長年日記]

% [game] OG 外伝日記、ゲシュちゃん mk2 改が良い味出しすぎてる件

最強技の『ジェットファントム』が車田正美テイスト溢れすぎです。 途中のカットインですら、そうなのに、トドメを刺したときに敵がサカサマになって落ちてくるところとか狙いすぎだろw


トップ 最新 追記

日記ってのは本来、自分で読み返すためにあるもんだよなあ……
もしくは有名人になったら死後に本になったりとかか?

RSS はこちら

jijixi at azito.com