2007年 10月 01日

CocProxy

CodeRepos にコミットしてどきゅめんとかいた
http://coderepos.org/share/wiki/CocProxy

全然関係ないけど (なんか自分こういうのおおいんだけど、なんでだろ……)、今回 MatchData#begin と MatchData#end をはじめてつかった。
あと String#[a..b] = c もはじめてつかった。begin/end にいたっては今回はじめて知った。MatchData のリファレンスとかあんま見ないですよね。(ですよね?)

それにしても、なんか頭がおかしい。頭がおかしいって、ソレではなくて、なんていうんだろ、うまく回っていかない感じがする。もちろん前から回っていないのだけど、それに拍車がかかって、自動的に動いている感じがする。寝すぎなんだろうか。とか、今こうやってまた「全然関係ないこと」を書いてしまうぐらい頭が回ららないというかおかしい。頭悪いのは、どうしたらいいんだろ。なんだろもっと自重して生きていこう……もう遅いかもしれない。

OS X のネットワーク設定

ずっと ~/Library 以下を探してたけど、ない。 /Library/Preferences/SystemConfiguration/preferences.plist に書いてある。

  • Sets/* 以下に各ネットワーク設定が入ってる。
  • Sets/*/Network/Service/* は NetworkServices/* へのリンク
  • NetworkServices/* 以下に各サービスの情報
  • NetworkServices/*/Proxies/* にプロキシ設定
  • サービス情報は (各ネットワーク環境 * 各インターフェイス)

これ、この plist を直接いぢくる以外の方法でプロキシ設定って変更できないのかなぁ。なんか API とかないのかな。だいぶ探したけどないっぽくて困る。osascript で SendKey っぽいことしながら書きかえるのはちょっとみかけたけど、ださすぎる……
直接いぢるっていっても、root:admin 0644 だから sudo 必須で、結局あぷりけーそんがわから自動設定ってのはめんどいんだよなぁ。

あと疑問なのは、admin 権限もってないユーザってプロキシ設定の変更ってできないのかな。やってみろって話だけど余計なユーザつくりたくないなぁとおもってやる気なくしぎみ。というかもしそうだとしたらプロキシ設定必要なときどうするんだろ。Safari 使わない、とかになるのかな。まさかそんなわけないよなぁ……


もし直接変えるとすると、

  1. /CurrentSet を読む (/Set/0 だとしよう)
  2. /Set/0/Service のリンクをたどって /NetworkServices を列挙
  3. アクティブなインターフェイスのサービスを取得
  4. プロキシ設定

なんかでも、NotificationCenter とかになんか投げないと反映されなそうだなぁ。それに直接いぢるのはやっぱこわいしやりたくない。

Ruby でドキュメント書くとき

RD が好きじゃない、という内容でごたごた書いたけど、眠いからやめよう。Markdown/TracWiki スキー

=begin TracWiki

= Test =

 * hoge
 * [http://example.com/fuga fuga]

=end

=begin Markdown

Test
====

 * hoge
 * [fufa][1]

[1]: http://example.com/fuga

=end

でいいや……
Markdown にちょい修正加えられたのをよくつかう。けど、修正加えると Markdown じゃなくなるから困る。デフォで dl が書けないのが痛すぎる。

Markdown も TracWiki も Ruby じゃないっていう

>

法律に疑問を抱かない人っていっぱいいるんだなぁ。現状の法律に疑問を持たなければ、良い方向への改善なんてするわけない。法によって罪が作られる国なのだから、罪人がたくさん出る法はおかしい。そこにひずみがある証しなのだから、そのもとを正さず表向きに法律だけ変えてもしかたない。罪人をつかまえまくってもしかたない。

議員は目の前の利益しか考えず、バカな法律を作って、法の信頼度を下げていってしまう。国民が「もう法律は信用できない」といって、法治国家が壊れていくのが一番怖い。今声がでかい古い人たちが勝つならば、考えているより早くそういう自体が起こるかもしれない。そういう人達がみんな死ぬのが先なのか、だめになるのが先なのか。

2007年 10月 02日

おれ……

「おれ……はてなさんのこと……好きだ」
「え…………」

少し前夢で見た好きな娘も、時間が経てば顔や、雰囲気も忘れてしまうものだ。残るのは、明確に文字に起こせる所謂属性のようなものだ。かなしい。

夢と現実

おれは言語によって思考が制限されるとは考えていない。これは高校のときに結論を出してから変わっていない。結論を出したのは改装工事中の小田急成城学園前駅の改札 (当時は片方しか改札がなかった) を入り、階段を降りていく途中だった。

さらに言えば、このことは人間が想像できるもので創造できないものはないというのと繋り、最終的には、人間ごっこに繋る。僕らが生きているのは想像の世界であって、それに感覚がついてきている。感覚は想像によって創造されている。御互いの影響、関係は無意識下で機械的に行なわれる。ある意味ではプログラム済みだ。メモリエラー (突然変異) が起きないかぎり (パリティチェックとエラー訂正がついていたらそれも起きないだろう)、定められたアルゴリズムで伝播がされ、未来へ動いていく。しかしながらその次元での影響は僕らが感じている時間に因っているわけではない。僕らの時間もまた、僕らが想像し、感じとっている要素の一つであり、その無意識下の影響の進みとは違う。

僕らは僕らが想像する「人間像」によって制限されている。所詮ゲームにも関らず、昔に誰かが必死wwwになったせいで、まきこまれ、人間ごっこ (=人間であることを演じること) をせざるを得なくなった。しかも長い時間をかけてそれがあたりまえになり、現代の人々、すなわち僕らは人間ごっこをしていることに気付けず、やめる方法を忘れている。

僕らは今、どちらかと言えば感じている所謂「現実」ないし「物質」をより重要視している。けれどもちろんそれは本来間違いである。僕らが想像した「人間」なるものがそういう世界で生きるゲームをしているだけで、本来そういったものはそのゲームを制限する要素でしかないからだ。ゲームマスターはなんでもできてつまらないから、ある程度制限を設けてその中でゲームをしているわけだ。僕らがストーリーを考え、想像し、設定によって制限するとき、そこには僕らのような存在ができる。同じように、僕らはメタ世界の住人によって作りだされている (この表現は適切ではない、そのメタ世界の住人と僕らは同じ存在だからだ)。

君がこの文章を読むとして、読めるとするなら、この文章を書いて、ここでの「僕ら」を想像したものがどこかにいる。そして君がこの文章を読んだときに想像する「僕ら」がまた生まれ、君はメタ世界の住人として彼らに想像される。僕らは君と同じだが、他人の想像した僕らとは違う。

にこにこ動画

歌ってみた系とか好きだけどなぁ。ああいうのは嫌いな人ってニコニコで何見てるんだろ。

ああああああああああああああああああ

あああああああああるうううううでぃいいいいいいいいいいいいえふううううううううううとーりーーーーーぷーーーるうううううううううううううを
発射!! しまくる!!

gerry++

scrubyt

なんか結局うまくいかなくてソース読むっていう……
Extractor.define が返すのは Scrubyt::ScrubytResult で (Scrubyt::Result ではない)、ScrubyResult は ResultNode のサブクラスになってる。
ResultNode は Array のサブクラスになっているんだけど、Array#inspect が空の Array を表示してしまっていて混乱する。実際には中身があったりする。ドキュメントおうよりソース読んだほうがいいことを実感した……

あと mechanize が 1.8.5 以上要求する。ubuntu LTS は ruby1.8.4 なのでエラーでる。(1.9 は入れてるけど、まだ 1.9 で gem を入れたくない)

/usr/lib/ruby/gems/1.8/gems/mechanize-0.6.10/lib/mechanize/inspect.rb:44: undefined method `pretty_inspect' for class `WWW::Mechanize::Page' (NameError)

めんどいので

class Object; def pretty_inspect(*); self.inspect; end; end

書いてほうち。

#!ruby -Ku

class Object; def pretty_inspect(*); self.inspect; end; end

require "rubygems"
require "scrubyt"

mixi_community = Scrubyt::Extractor.define do
	fetch "http://mixi.jp/"
	fill_textfield "email",    config["user"]
	fill_textfield "password", config["pass"]
	submit

	fetch "http://mixi.jp/view_community.pl?id=26374"

	# member_num "#communityInfo .contents03 .memberNumber"
	member_num "//dl[@class='communityInfolistMiddle clearfix memberNumber']/dd[1]"
end

num = mixi_community.to_hash[0][:member_num][/¥d+/].to_i

あたらしくなった mixi でコミュニティの参加人数とるやつをかいた。慣れればかなり早くすくれいぱー書けそうだなぁ。
でも自動解析みたいなのは読みにくいと思う

2007年 10月 03日

泣けるドラマ・アニメ・映画を作る最も簡単な方法

誰もいない (ないし、モブだけの) 学校、というシーンを入れる。

例えばスウィングガールズは冒頭でうえをやってのけるのですぐ泣ける。
例えば時かけは7:25と56:32あたりで二重にやるのですぐ泣けて最後のほうでも泣ける。

今日も仕事が全くすすまなかった。しんだほうがいい気がする。まだ

>

中に誰もいませんよ

最終話以外殆ど見てないけど、あのセリフは印象に残るなあ。

XPath でドキュメント順に複数の要素とってくる

たとえば getElementsByTagName だと、"*" わたして自分で配列つくってやるか、それぞれに要素名を渡したあとにドキュメント順にソートしたりしなくちゃいけないけど、XPath のときはそういうのする必要がない。

$X("//body | //html | //link ")
//=> [html, link, link, link, link, link, link, body]

パイプ演算子はオペランドにノード集合をとる。どうでもいいけどパイプとバイブは似てる。

でも true / false をオペランドにしてもエラーがでない。"//html | false" は html をかえすし、"//html | true" もかえす。数値や文字列だとだめ。実装依存なのかな。

自分は $X を unsafeWindow にエクスポートしてる。

ぐりもんのアイデア

かたっぱしからはてなスターを 801 個つける GM

cvs screen memo

http://subtech.g.hatena.ne.jp/antipop/20071003/1191410798 みながらやってみた。256color はつかってないのでオンにしてない。make とかもふつうにとおる @ubuntu LTS

http://lists.gnu.org/archive/html/screen-users/2007-02/msg00000.html に書いてないサブコマンド
process.c を case RC_LAYOUT を検索したらでてくる。というか ML に続きあった http://lists.gnu.org/archive/html/screen-users/2007-02/msg00009.html

layout の削除がないのかな。どうやって消すんだろ。

screen のソースはタブとスペース混ざってて読みにくい。:set tabstop=8

http://lab.lowreal.net/trac/changeset/897 resize -v は右側でやると操作感が逆になってしまう。

思ったより軽いかなぁっておもったけど、やっぱおもい…… vsplit

2007年 10月 04日

irssi

ustreamer の join/part を表示しないプラグインを書くべきだ……とおもって書いた。/ignore でできるのかもしれないけどわかんない。

use strict;
use warnings;

use Irssi;
use vars qw($VERSION %IRSSI);

$VERSION = "0.01";
%IRSSI = (
	authors     => "cho45",
	contact     => "cho45¥@lowreal.net",
	name        => "all",
	description => "ignore ustreamer join/part",
	license     => "Public Domain",
	url         => "http://irssi.org/",
	changed     => "2007-10-04T01:15:00+09:00"
);

sub message_join {
	my ($srv, $channel, $nick, $addr) = @_;
	Irssi::signal_stop() if $nick =~ /^ustreamer/;
}

sub message_quit {
	my ($srv, $nick, $addr, $reason) = @_;
	Irssi::signal_stop() if $nick =~ /^ustreamer/;
}

Irssi::signal_add_first("message join", "message_join") ;
Irssi::signal_add_first("message quit", "message_quit") ;

Irssi::signal_stop() よべばなんか止まるらしい。

徹夜

結局ナチュラルに徹夜してしまった……眠いし寝たいけど眠れない……眠りにつこうとできない。

もづるぷらがぶる

ホスト間で SSH トンネリングと Rinda つかって簡単な情報 (IRCの通知情報とか、クリップボード内容とか) を簡単にやりとるするフレームワークを簡単に書こうとおもっていたのに、プラグイン機構が欲しいなぁと思ってそっちを書きはじめる罠

Rinda はタプルの要素数を3個に制限することでおてがるなトリプルサーバとして使えそうだなぁ。正規表現マッチもできるしというか === の比較をしてくれるから入れるオブジェクト (URI) さえ考えてあげればうまいことつかえそう。もちろんこれは全然関係のない話なんだ!
タプルの要素数を制限してしまえば、完全に notify で傍受できるから、デバッグしやすいし、削除とかも <invalid_resource> <rdf:type> <hoge::InvalidResource> とか投げてやるとサーバ内で take して削除したりとかできそう。SPARQL の実装つくんないとだめだけど……SPARQL とかパーサつくるのからしてめんどくさい……

キーボードすりきれ度

一年ほど MacBook を使ってみて

  1. E
  2. T
  3. S
  4. A
  5. H
  6. G
  7. J
  8. N
  9. D

の順ぐらいにキートップが削れてる。他のキーは差がわからない。

2007年 10月 05日

ruby, クラスのインスタンス変数と、クラス変数

なにがちがうんだって思ったらリファレンスマニュアルに書いてあった……

  • サブクラスから参照/代入が可能
  • インスタンスメソッドから参照/代入が可能
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=%CA%D1%BF%F4%A4%C8%C4%EA%BF%F4

サブクラスからの参照/代入が大きな違いかな。クラスのインスタンス変数はあくまでそのクラスにしか属さないから、サブクラスからは頑張って superclass 探すしかアクセスする術がない。

無駄だけど以下のようにすればだいたいクラス変数と同じことがクラスのインスタンス変数でできる。

class Hoge
	@@test = :CV_test
	@test = :IV_test

	def hoge
		[
			@@test,
			self.class.ancestors.find {|c|
				c.instance_variables.include?("@test")
			}.instance_variable_get(:@test)
		]
	end

end

p Hoge.new.hoge #=> [:CV_test, :IV_test]
p Hoge.new.hoge #=> [:CV_test, :IV_test]

class Fuga < Hoge
end

p Fuga.new.hoge #=> [:CV_test, :IV_test]
p Fuga.new.hoge #=> [:CV_test, :IV_test]

サブクラスからはアクセスされたくない場合だけクラスのインスタンス変数をつかうべきかな (具体的にはどういうケースだろう)

instance_eval のスコープ と class_variable_set を使わないクラス変数の代入方法

ただし、ローカル変数だけは instance_eval の外側のスコープと共有します。

http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=Object#instance_variables
class Hoge
	@@hoge = :hoge

	def initialize
		@test = :Nice_boat
	end
end

o = :test
Hoge.new.instance_eval do
	p o #=> :test
	p @test #=> :Nice_boat
	p @@hoge #=> uninitialized class variable @@hoge in Object (NameError)
end

クラス変数も外側のスコープになってるような。module_eval のほうでは : version 1.6.8 以降でブロックが与えられた場合は、定数とクラス変数のスコープも外側のスコープになります。 って書いてあるけど、instance_eval もそうなのかな。
だとすると、ruby 1.8.3 で class_variable_set/get が実装されるまで、クラス変数に直接オブジェクトをセットする方法ってなかったのかな。Mac の ruby は 1.8.2 なのだけど、クラス変数を外から代入するのをどう書いたらいいかわからない……

とここで思いたって、たぶん同じことを ML できいたひとがいるだろうと class_variable_set を検索すると、[ruby-talk:144741] に "Why no class_variable_set?" という投稿があった。ML のアーカイブが全部 not found になっててリンクはれないけどキャッシュでみたところ、アクセサメソッドを定義してた。なるほど……

未定義にするところまで含めると以下のようにすれば一応できる。きもい。

class Hoge
	@@hoge = :hoge

	def t
		@@hoge
	end
end

o = :test
Hoge.class_eval %{
	def self.hoge=(val)
		@@hoge = val
	end
}
Hoge.hoge = o
(class << Hoge; self; end).instance_eval do
	remove_method(:hoge=)
end

p Hoge.new.t #=> :test

Hoge.hoge = :aaa # undefined method `hoge=' for Hoge:Class (NoMethodError)

なんか更めて読みなおしてみるとあたりまえすぎる……べつに定義されていないなら、class_variable_set/get を定義すればいいだけじゃん
あれでも、結局 eval するはめになってだめか。おれあたまわるい……もうやだ

特異クラス

なんかひさしぶりに特異クラスを意識して、あぁ Ruby はクラスベースなんだなぁってなんだか実感した。普段使う分にはインスタンスにメソッドが直接定義されてるように見えて特異クラスを意識しないもんなぁ。
特異メソッドは全て特異クラスに定義されているんだから、特異クラスも間接的に使いまくってるんだよなぁ。Class.new も特異クラスのメソッドだもんなぁ。Class さえ Object のインスタンスであるから特異クラスを持ってる。特異クラスもクラスのインスタンスなのだから、特異クラスを持ってる。

なんとなく思いついて特異クラスもクラスなんだからインスタンスつくれんのかなぁって思ったけど作れなかった。(clone からデータコピーをのぞいた感じになるのかなぁと漠然と想像した)

in `new': can't create instance of virtual class (TypeError)

SQLite3::SQLException: SQL logic error or missing database

CGI で AR つかってたらこれがでてすすまなくなった。一時間ぐらいハマった……

and that the folder that the DB file is in is also readable and writeable by the Apache user

http://www.kryogenix.org/days/2006/09/17/operationalerror-sql-logic-error-or-missing-database

オーナーシップと該当ファイルのパーミッションだけじゃなくて、ディレクトリのパーミッションもだった……

gems

別に gems じゃなくてもそうだけど、ああいうパッケージシステムのウェブのほうは、ドキュメントが表になってるべきで、rubyforge みたいにプロジェクトがいきなりでてくるようになってるべきじゃないと思う。だってプロジェクトの情報なんてそのモジュールを使うためには全く必要ない。
gem のサーバってどうなってんのかな。おれおれサーバつくったほうがいい気がしてきた。

http://jp.rubyist.net/magazine/?0010-PackageManagement
に書いてあった。

2007年 10月 06日

明るくならないと眠れないみたいだ

なんていうんだろう。ここ最近そんな感じだったから、じゃあカーテン締めて暗いままだとずっと眠れないんだろうかと思ってしめっぱにしていたらやっぱ眠れない。

ちらし

UNIQLO とニトリのちらしが、派手さと落ちついた感じのバランスと、情報量の多さと余白のバランスがなんかよくて、すげーって思った。
たまには折込チラシも見るべきだなぁ。

作家の印象

読んでると、感じるような気持ちが、作家によって違う。あたりまえなのかもしれないけど、結構不思議だ。作品によって、じゃなくて、作家によって違う。

「Ruby の勉強をはじめました」

っていうのを見るとなんかムカついて目を反らしてしまう。Ruby は勉強するものじゃない。そうなって欲しくないと思う。

JS とか C とか Java にはそういうの感じない。なんなんだろう。

RDoc テンプレート Resh

RDoc のデフォルトテンプレとか、出回ってるテンプレみたかぎりとか、なんていうか、色が濃すぎて、みんな嫌いなので RDoc のソースよみながら書いてみた。
http://safeeval.rubyforge.org/ こんなかんじになります。safeeval はちいさすぎていまいちだけど、ローカル gem の rdoc とかにつかうといいと思う。

配色とかは search.cpan.org っぽい感じにした。Ruby カラーの赤ってなんかドキュメントにいれるとイライラしてしまうので、というかドキュメント見てるときってだいたいイライラしてるので心を落ちつかせる青系がいいと思う。

svn co http://svn.coderepos.org/share/lang/ruby/rdoc/generators/template/html/resh/ resh

local gem の rdoc をアップデートするには

$ cat ~/.gemrc
rdoc: --template ~/coderepos/lang/ruby/rdoc/generators/template/html/resh/resh.rb --inline-source
$ sudo gem rdoc --all --no-ri --config-file ~/.gemrc 

もし gem つくったときにデフォルトのテンプレートにしたいなら、Rake::RDocTask にオプション設定

        rdoc.template = "#{ENV["HOME"]}/coderepos/lang/ruby/rdoc/generators/template/html/resh/resh.rb" 

最初に表示されるページは指定されたオプションをガン無視して、README (あれば) と、クラス・メソッド・ファイルのインデックスをあわせたみたいなのにした。わりとうまくいく。
あと --inline-source オプションも常に無視して、常に inline-source 表示するようにしてる。でも邪魔は邪魔なので、JS で見えたり消えたりするようにしてる。ボックスが目立たないから最初はとまどうかもしれないけど、目立つべきじゃないのでこうしてる。慣れる。


実装は hate rdoc/template って感じでわざわざ ERB つかうように RDoc のメソッドをオーバーライドしてる。だから html_generator の実装が変わるとバグるかもしれない。generator ごと新しく作ろうと思ったけど、名前に困ったのでやめた。どっちにしろほとんどコピペになるし……互換性なくなったらそうしよう。

module-pluggable リリース

http://modulepluggable.rubyforge.org/

sudo gem install module-pluggable

Module::Pluggable っぽいのをつくろうとおもったのだけど、よくわかんないのでほしいのつくった。中身は chokan の plugin 機構とほとんど同じ。なので、スクリプトロード後のリロード (デーモンっぽいやつでの動的リロード) とか、多数のインスタンスをつくったり、リロードしないまんまのプラグインの状態を保持ったりできる。そのかわり直接プラグインのクラスにはアクセスできない (匿名モジュール内にロードされてインスタンス化される)。

それはともかく
なんか rubyforge config すると

package_ids: 
  modulepluggable: 5722

とかなってしまって

package_ids: 
  module-pluggable: 5722

にしないとリリースできない。これ config するたびに書きかえないといけないのかなぁ

ヒアドキュメントのマーカ

EOF (End of file), EOS (End of string) を一番つかう。
これ以外のときも EOx にするようにしてる気がする。
タブインデントだとヒアドキュメント書くときに楽ができる

classs Hoge
     def hoge
         <<-EOS.gsub(/^\t+/, "")
             hoge 
               hoge
                               aaaaa
         EOS
     end
end

optparse で banner 書くときによく使う。

$HOME の構成

  • bin/
    • app/*/bin/* への symlink だったり
    • ruby1.9 系とかへの symlink だったり
  • app/
    • appname/*
  • src/
    • tmp/ とかあんまり住みわけできてない
    • 定期的に svn up したりしながらインストールするかな? ってときはこっち
  • tmp/
    • test.{rb,pl,lua} つかいまくる
  • config/
    • svn からチェックアウトした config
    • $HOME から symlink
  • repos/
    • 個人公開リポジトリの svk co パス
  • private/
    • 個人非公開リポジトリの svk co パス
  • coderepos/
    • CodeRepos の svn co パス (なぜか svk つかってない)
  • www/
    • /srv/www への symlink だったりちがかったり
  • sdk/
    • AS の SDK とか
  • lib/
    • AS のライブラリとか
  • swp/
    • vim の .swp おきば
  • project/
    • 自分のじゃないプロジェクトで自分が関わっているもののチェックアウトパス
  • graphic/
    • web/
      • *.psd

あと晒せないけどごちゃごちゃ。鯖もローカル (Mac) も共通なのはこれぐらい

index_gem_repository.rb memo

http://jp.rubyist.net/magazine/?0010-PackageManagement の generate_yaml_index.rb はいまはこのなまえ。
カレントディレクトリの gems/* を見て、

  • yaml
  • yaml.Z
  • quick/
    • index # 一行ごとに gem のファイル名が書いてある。
    • index.rz
    • name-version.gemspec.rz

を生成する。yaml には gems/* 以下の Gem::Specification をあつめたやつが入ってる。キャッシュらしい。.rz/.Z は zlib で圧縮されたやつだけど gzip ではない。


rubygems

  • remote_installer.rb
      uri = source + "/gems/#{spec.full_name}.gem"
      response = Gem::RemoteFetcher.fetcher.fetch_path uri
  • incremental_fetcher.rb
109:      zipped_yaml = fetch_path("/quick/" + spec_name + ".gemspec.rz")
123:    def get_quick_index
124:      zipped_index = fetch_path("/quick/index.rz")
  • source_index.rb
300:    # Get the quick index needed for incremental updates.
301:    def fetch_quick_index(source_uri)
302:      zipped_index = fetcher.fetch_path source_uri + '/quick/index.rz'
306:            "No quick index found: " + ex.message
355:          spec_uri = source_uri + "/quick/#{spec_name}.gemspec.rz"

なんか似たようなのがふたつ。

よくみる Bulk updating Gem source index for: は yaml.Z/yaml の更新 (source_index.rb)
quick/* を利用した incremental な source index の更新は

use_incremental = missing_gems.size <= INCREMENTAL_THRESHHOLD

で決まってる。INCREMENTAL_THRESHHOLD = 50。missing_gems はサーバの quick/index[.Z] と、ローカルの spec を比べたときにサーバがわにしかない spec。差分 spec が 50 以上のときと、quick index が利用できないときは常に bulk update により yaml[.Z] が取得される。

yaml[.Z] のサイズは rubyforge のもので .Z が 855KB, 圧縮していないのは 11MB (!) もある (単純に http://gems.rubyforge.org/yaml[.Z] にアクセスすればわかる)。リリースごとに spec は増えていくはずだから、あんだけ大きい gem サーバだとすぐ 50 を超えて bulk update になるだろうと思う。というかおれの使いかただと gem install するごとに毎回 bulk update してる感じだ。quick/index は 140KB。1行に1gem だから、rubyforge がホストしている gem の数は

wget http://gems.rubyforge.org/quick/index
wc -l index

すればわかる。現在だと 8555 gems のようだ (バージョン違いの gem を含む)。

quick/index + 1M ぐらいダウンロードしてきて、伸張して YAML.load してるんだからそりゃ遅いよなぁ。gem の名前ごとに gem サーバをわけるとか、あるいはもっと根本的に解決しないとどんどこ遅くなっていくなぁ。なんか昔の RO のパッチクライアントを思い出した。


>

2007年 10月 07日

腕に違和感

昨日の夕方2時間寝たいがいずっと PC つかいっぱのせいか、左腕に違和感がある。腱鞘炎フラグ?
とりあえず冷やしてみた。というか寝ようよおれ……

gem で RDoc が生成されないやつを強制的に生成する (ちゃんと gem のディレクトリに)

確実、とは言えないけどだいたいうまくいくほうほう

# てきとうに doc.rb とでもつける
require "rubygems"
require "rubygems/doc_manager"

class Gem::DocManager
	alias :origi_initialize :initialize
	
	def initialize(*args)
		origi_initialize(*args)
		def @spec.has_rdoc
			true
		end
		def @spec.rdoc_options
			t = super
			p t
			[] # --exclude . とか排除
		end
	end
end
sudo ruby -rdoc `which gem` rdoc --no-ri --config-file ~/.gemrc --backtrace capistrano

-r で上の読みこんだ上で gem を実行する。capistrano は rdoc あるのになんで生成されないんだろ。あと rails は rdoc 生成しようとすると ruby が暴走する。なぞい。

memo vim configure

./configure --prefix=/usr/local/vim7 --enable-multibyte --enable-rubyinterp --enable-gpm --enable-cscope --with-features=huge --enable-fontset --disable-gui --without-x --disable-xim --enable-pythoninterp --enable-perlinterp

cutagem - Yet Another newgem っぽいなにか

http://cutagem.rubyforge.org/ - Cut a Gem をリリースしました。

sudo gem install cutagem

昨日

*newgem を使ってない。
最近つかってない。Rakefile はカスタマイズがすぐできるように Hoe を使わないようにしてる。(Rakefile が何やってるか全然わからなくなるのがいやだ。task が生で書いてあってほしい。こういうのは DRY よりコピペのほうがやりやすいと思う。Hoe からコピペしてるタスクはある)

なので、newgem が生成する Rakefile は使えなくて、あと History.txt じゃなくて ChangeLog にしくて (RDoc 書くっていう意味では間違ってるんだけど、ChangeLog のほうが数倍書きやすいし……)、あとあと version.rb がきもちわるいから嫌で、あとあとあと、newgem hoge-gura とかやったときキモいファイル名ができるし、なんかもう全部カスタマイズ済みのを newgem で生成したいなぁとおもったんだけど、できないみたいだ。(ちなみに最近つくった gem は「前につくった gem を cp -r して頑張って置換」してつくってる)

bin/newgem を読んでみると、全部決めうちなのよね。~/.newgem/template があったら読んでくれてるんだろうとか漠然と思ってたけどそんなことなかった。完全なる決めうちだった。清々しいぐらい決めうち。

こういうのってパッチ送るより自分で書いたほうがはやい。

というところまで書いたところで (コメントアウトして保存して)、じゃあ書こうっていう話に脳内でなったので書いた。

LustyExplorer

http://www.vim.org/scripts/script.php?script_id=1890
lookupfile 関係さがしてたら id:secondlife さんところで見つけて、ためしてみたらやばかった。これはやばい。やばいよ。文乃さんなみにやばい。いやそこまでいかない。zsh でディレクトリ cd していくのがめんどくさくなるぐらいやばい。

nmap bg :BufferExplorer<CR>
nmap bG :FilesystemExplorerFromHere<CR>
nmap gb :FilesystemExplorer<CR>

タブきりかえの gt gT (タブばっか使ってるので) を意識した感じ

]

なんか気が付いたら本編も何度か見直してた。いいよ! いいよ! 自由にやりな! 勝手にやりな!
なにが見所なのかよくわからないけど、たぶんたまちゃんなんだよね?

体育嫌いだなまじであんなのなくなればいい

おれはもう終わったことだからいいけど、もし子供ができたらなんとかしないといけない。陸上とかスキーとか飛び箱とかだけにすりゃいいのになぁ。チームプレー入れんなよ。


それにしても「そんなの気の持ちよう」とかいう人間のクズは今すぐ首つって死ねばいいのになぁ……だいたい体育教師もそういやつだから、さらに絶望的な感じになる。

2007年 10月 08日

生年月日

が近い人とはうまがあいやすい。

2007年 10月 07日

LustyExplorer つかうと unnamed register がぶっこわれる

:registers                                                                                                                                                              
--- Registers ---
""   M    ^JM    ^JM    ^JM    ^JM    ^JM    
"0   ^I^I^I<div id="footer">^J^I^I^I^I<% require
...

unnamed がこわれる。paste 系のコマンドは ("0 を使うって説明されてるのを見掛けたけど、少くとも vim7.1においては)、"" が使われる。LustyExplorer は他のレジスタは復元するけど " だけ復元しないっぽい。

--- lusty-explorer.vim.orig	2007-10-07 22:50:11.000000000 +0900
+++ lusty-explorer.vim	2007-10-07 22:51:27.000000000 +0900
@@ -957,6 +957,7 @@
     @sidescroll = eva "&sidescroll"
     @sidescrolloff = eva "&sidescrolloff"
 
+    @reg  = vim_single_quote_escape(eva('@"'))
     @reg0 = vim_single_quote_escape(eva("@0"))
     @reg1 = vim_single_quote_escape(eva("@1"))
     @reg2 = vim_single_quote_escape(eva("@2"))
@@ -1000,6 +1001,7 @@
     exe "set sidescroll=#{@sidescroll}"
     exe "set sidescrolloff=#{@sidescrolloff}"
 
+    exe "let @¥" = '#{@reg}'"
     exe "let @0 = '#{@reg0}'"
     exe "let @1 = '#{@reg1}'"
     exe "let @2 = '#{@reg2}'"
2007年 10月 08日

Pathname.home がほしい

class Pathname
    def self.home
        new(ENV["HOME"])
    end
end

ENV["HOME"] って大文字ばっかりでつかれる。

word_complete.vim

http://vim.sourceforge.net/scripts/script.php?script_id=73
ちょっと使ってみたのだけど、ときどきすごく重くなったり、挙動不審だったりして微妙……便利なんだけどなぁ……SELECT モードから戻らなかったりする。
使い続けるかもう少し様子見

使うかどうかはともかく gem のあれをつくった

http://lab.lowreal.net/gems/
scp で特定のディレクトリに投げつける Raketask を書いて ( http://coderepos.org/share/changeset/427 )、更新された gem の rdoc を生成して gem index を更新するスクリプトを叩く。

#!/usr/bin/env ruby
puts "Content-Type: text/plain"
puts

$stderr = $stdout

require "pp"
require "pathname"
require "rubygems"
require "rubygems/doc_manager"

begin
	class Gem::Format
		def extract_to(dir)
			dir = Pathname.new(dir)
			self.file_entries.each do |info,content|
				path = Pathname.new(info["path"])
				if path.absolute?
					raise "Damedayo"
				end

				f = dir + path
				f.parent.mkpath
				f.open("wb") do |o|
					o.write content
				end
			end
		end
	end
	Gem::DocManager.configured_args = ["--template", "/Users/cho45/coderepos/lang/ruby/rdoc/generators/template/html/resh/resh.rb"]
	Gem::DocManager.configured_args = ["--template", "resh", "--line-numbers"]

	load "/usr/bin/index_gem_repository.rb"
	path = Pathname.new("/srv/www/lab.lowreal.net/public/gems")
	options = {
		:directory => path.to_s,
		:verbose   => true,
		:quick     => true,
	}
	prev = (path + "quick/index").read.split(/¥n/) rescue []
	#prev = []
	indexer = Indexer.new(options)
	indexer.build_index
	diff = (path + "quick/index").read.split(/¥n/) - prev
	diff.each do |gem|
		puts gem
		g = path + "gems/#{gem}.gem"
		gem = Gem::Format.from_file_by_path(g.to_s)
		dir = path+"gems/#{gem.spec.full_name}"
		dir.rmtree rescue nil
		gem.extract_to(dir)
		#gem.spec.loaded_from = "docs"
		spec = gem.spec
		spec.instance_eval { @path = path }
		def spec.installation_path
			@path.to_s
		end
		p spec.full_gem_path
		doc_manager = Gem::DocManager.new(gem.spec)
		doc_manager.generate_rdoc
	end

rescue Exception => e
	puts e
	puts e.backtrace
end

ブラウザでアクセスしたときに表示されるインデックスはてきとうに gem spec よんで表示してるだけ

URI::FILE Ruby / file: スキームと Pathname のあれそれ

なんかなにをしようとしていたか忘れた……ねむくなってきた。ついでにお腹痛い。Win 環境でもシームレスにつかえるようにするにはどうしたらいいのかなぁ。URI::File.path(path) を定義して URI 化とかかなぁ。でもあんま意味ない気がしてきた。

require "uri"
require "pathname"

# file scheme syntax:
#     file://<host>/<path>
class URI::FILE < URI::Generic
	DEFAULT_PORT = nil
	COMPONENT = [:scheme, :host, :path].freeze

	def self.build(args)
		tmp = Util::make_components_hash(self, args)
		super(tmp)
	end

	def initialize(*args)
		super(*args)
		@pathname = Pathname.new(@path)
		# delegate
		(@pathname.methods - self.methods).each do |m|
			instance_eval <<-EOS
				def #{m}(*args, &block)
					r = @pathname.__send__(:#{m}, *args, &block)
					if r.class == Pathname
						@path = r.to_s
						self
					else
						r
					end
				end
			EOS
		end
	end

	def to_s
		"#{scheme}://#{host}#{path}"
	end
	alias :to_str :to_s

	def set_path=(s)
		@pathname = Pathname.new(s)
		@path = s
	end

	def set_host(s)
		@host = s
		if !s.nil? && !s.empty?
			raise NotImplementedError, "Host is not supported"
		else
			@host = nil
		end
	end

	def check_host(s)
		if s.empty? || HOST =~ s
			true
		else
			raise InvalidComponentError, "bad component(expected host component): #{v}"
		end
	end

	@@schemes['FILE'] = URI::FILE
end

if $0 == __FILE__
	require "test/unit"

	class TC_URI_FILE < Test::Unit::TestCase
		def setup
		end

		def test_windows
			uri = URI("file:///c:/Windows")
			assert_equal nil, uri.host
			assert_equal nil,  uri.port
			assert_equal "/c:/Windows",  uri.path
			assert_equal "file", uri.scheme
			assert_equal "file:///c:/Windows",  uri.to_s

			uri = URI("file:///c:")
			assert_equal nil, uri.host
			assert_equal nil,  uri.port
			assert_equal "/c:",  uri.path
			assert_equal "file", uri.scheme
			assert_equal "file:///c:",  uri.to_s

			uri = URI("file:///c:/Documents%20and%20Settings/")
			assert_equal nil, uri.host
			assert_equal nil,  uri.port
			assert_equal "/c:/Documents%20and%20Settings/",  uri.path
			assert_equal "file", uri.scheme
			assert_equal "file:///c:/Documents%20and%20Settings/",  uri.to_s
		end

		def test_delegate
			uri = URI("file:///Users/cho45")
			assert_equal URI("file:///Users"), uri.parent
			assert_equal false, uri.root?

			uri = URI("file:///c:/Documents%20and%20Settings/cho45")
			assert_equal URI("file:///c:/Documents%20and%20Settings"), uri.parent
		end

		def test_inteface
			assert_equal URI("file:///path/to"), URI::FILE.build(["", "/path/to"])
			uri = URI("file:///Users/cho45")
			uri.path = "/hoge/hoge"
			assert_equal URI("file:///hoge/hoge"), uri

			uri = URI("file:///Users/cho45/tmp/")
			assert_equal URI("file:///Users/cho45/tmp/test"),  uri + "test"
		end

		def test_with_host
			assert_raise(NotImplementedError) do
				URI::FILE.build(["host", "/path/to"])
			end
			assert_raise(NotImplementedError) do
				uri = URI("file://host/Users/cho45")
			end
		end
	end
end
2007年 10月 09日

.

なんだかやっぱり、漠然とした不安がある。

vim の補完

いいかげんどうにかしたいので必死で調べてるんだけどうまくいかない。ちなみに使いにくいのであんまり補完使ってない。

  • C-n しただけではソロでマッチしたとしても絶対に insert (確定) しない

という挙動にしたいだけなんだけど、なんでできないんだろ。ソロでマッチしている場合必ず確定してしまう。

だめだまったくだめだ。

<C-R>=Fun()<CR>

して自力で complete() よべばいいのかなぁとおもったけど、どうやって補完リストとってくればいいのかわからない。

なんでこんな素朴な挙動ができないのかなぁ……

てか complete() もソロマッチだと勝手に補完しやがるな
表示するだけってないのかなほんとに

vim の補完

ソロマッチの insert は諦めた。ほんとどうやってやるんだ……

補完のヒット率をあげるために dict を充実させるようにしようとおもった。で、これもずっと疑問だったんだけど、css とか、キーワードにハイフンを含めたりできるやつの補完ってどう書けばいいんだろう。emacs は記号として認識する範囲を指定する変数があったと思うけど、vim にはないのかな。ヘルプざっとみてるけど、なんか見つけかたが全くわからない。

iskeyword か。
CSS は ftplugin/css.vim で

set iskeyword+=-

してみた

RDoc template Resh gem

gem にしました。

sudo gem install resh

でインストールできます。--template resh のように書くことができるようになりますが、rubygems を読みこんでいないとテンプレート読みこみに失敗するので、RUBYOPT="-rubygems" をつける必要があります。ただし ~/.gemrc の rdoc: とか、RDocTask の書いたりするぶんには、既に rubygems が読みこみされたコンテキストで require が発生するので問題ないです。つまり直接 rdoc コマンドを叩かない限りだいたい大丈夫

今だに光合成ではなく食物で動いているあたり。。。

人間ってだめすぎるな

2007年 10月 10日

当然のこと

そうだなぁ……たかがスクリプト言語ちょろっと書けるぐらいじゃプログラミングできるなんて言わないよなぁ。やだなぁ……やっぱり生きていける気が全くしない。でもやっててつまんない言語なんてやりたくないしなぁ。時期がくるのかな。でも時期があわなかったら、やっぱり、就職先なんてないし、どうしたって、おれの頭じゃだめなことがある。

ヘッドフォン

KOSS UR/40 と AKG-271s は万能選手だなぁ。

2007年 10月 09日

svn ci のときの

-- この行以下は無視されます --

M    .zshrc

ってでたとき、下の無視されますのところを削除するとそのファイルはこのチャンジセットではコミットしない、みたいな機能があった気がするんだけど、今日ためしてみたらできなかった (TortoiseSVN のコミット画面のチェックボックスみたいなイメージ)。なんだろ。

vim の補完

コメントをもらった。
http://subtech.g.hatena.ne.jp/cho45/20071009#c1191925480
できた! できた! 神すぎる!!!

でもってすこし変更して小文字入力時に常にメニュー出すように (word_complete.vim は捨てた)

set completeopt=menuone,preview
function! CompleteWithoutInsert()
	return "¥<C-n>¥<C-r>=pumvisible() ? ¥"¥¥<C-P>¥¥<C-N>¥¥<C-P>¥": ¥"¥"¥<CR>"
endfunction
inoremap <expr> <C-n> pumvisible() ? "¥<C-n>" : CompleteWithoutInsert()
" 小文字入力で常にメニューだす
let letter = "a"
while letter <=# "z"
	execute 'inoremap <expr> ' letter ' "' . letter . '" . (pumvisible() ? "" : CompleteWithoutInsert())'
	let letter = nr2char(char2nr(letter) + 1)
endwhile
inoremap <expr> <CR> pumvisible() ? "¥<C-Y>¥<CR>" : "¥<CR>"
inoremap . .<ESC>a
inoremap ( (<ESC>a
inoremap [ [<ESC>a
set lazyredraw

なんかこのコードははてなコード記法でハイライトおかしくなるみたいだ。vimcolor だからかな

textarea で TAB おしたときにTABとか入力するようにする。

たまに生で code block 書くときにめんどかった。TAB で移動はつかわないし

	$X("//textarea").forEach(function (t) {
		t.addEventListener("keypress", function (e) {
			if (e.keyCode == 9) {
				e.stopPropagation();
				e.preventDefault();
				var s = t.selectionStart;
				var content = t.value;
				var str = "\t";
				var newstr = content.substring(0, s) + str + content.substring(s, content.length);
				t.value = newstr;
				var pos = s + str.length;
				t.setSelectionRange(pos, pos);

			}
		}, true);
	});
2007年 10月 10日

「熱さを嫌う若者たちは冷え切った場所へ逃げてゆく」

また徹夜

関係ないうえに違うやつだけど「ニットのセーターのそのふくらみが」もなんか切なげに性的で好きだなぁ。

リリースプロセス

よくわかんないなぁ。変更して「まだあるかもしれない」とおもってリリースしないでいると、「あれどこまでの変更をリリースしたっけ」とか思ってしまう。うーん

ホームページ

まだホームページ (ウェブサイト的な意味の) を家に比喩する人っているんだなぁ。しかもそういうのを記事にして「これからのウェブは」とか言ってしまえるのはすごい。

rubyforge にリリースできない

リリースしようとするとエラーでるなぁ。普通にウェブからやってもエラーでる。rubyforge (gem のほう) は、hpricot とか使って Error: の部分を出すようにすべきだ……

gem って post-installed フックできないのかしら

gerry++

2007年 10月 11日

光の路

ひさしぶりに歌詞見たら短くてうけた。これってなんかどっかの唄だとおもってたけど、ほんとに(謎)スカウトソングなのね。

記事タイトルを二段で

どこに設定あるのかわかんなくて困る……デザインと記事の設定ってどういう基準で分割されてるんだろう……

カテゴリテスト

二段にしてもカテゴリとか設定していないと、時刻だけになって殺風景だなぁ。上から読んでいくとき時刻が目線に入るのはちょっと思考を妨げる気がする。逆にカテゴリをちゃんと設定しているなら、どのカテゴリに属しているかが楽に目に入るようになってちょうどいい感じ。


一段

  1. カテゴリとタイトル読む (同列になってる)
  2. えっと、これがカテゴリだっけ……と脳内パーサーが走る
  3. 読むかどうか決める
  4. 本文読みはじめる

二段

  1. タイトル読んで内容を想像する
  2. カテゴリで補完する
  3. 読むかどうか決める
  4. 本文読みはじめる

その場編集は便利なんだけど、RET がきかなくて入力するのがめんどうくさい。Shift-RET なら効く。うちだけなんかなぁ。

Fx 再起動したら RET 効くようになった。
セクションタイトルのスタイルを変えてみた。ここの日記は本文みじかいからあんまこういうブログっぽいのは向かないな

n ly n nazo

#!ruby

require "nkf"

data = DATA.read.split(/¥n/)

def copy(str)
	puts str
	str = NKF.nkf("-s", str)
	IO.popen("pbcopy", "w") do |io|
		io.print str
	end
	str
end

copy(data.shift)
board = `pbpaste`
loop do
	boardn = `pbpaste`
	boardn = nil if  boardn.empty?
	unless board == boardn
		str = data.shift
		copy(str)
	end
	board = `pbpaste`
	sleep 0.3
end

__END__
1
2
3

NSPasteboard はデータ取得がいまいち安定しない。

2007年 10月 12日

外で遊ぶより手芸や工作のほうが好きだった

趣味で友達と一緒にサッカー、とか一切やったことがない。鬼ごっことか隠れん坊ならある。
外で遊ぶのが嫌いだったわけじゃない。でも日が暮れてからは外では遊べない。

デートに麦茶凍らせて持ってきそうな女の子がタイプ

404 Not Found 久しぶりに短い文で破壊力のある表現を見た気がする。

スレの途中でいろいろ書いてあって不安になるけど、結局、スレの最後のほうに書いてある

天然じゃない、アホの子じゃない、カーチャンじゃない

なんというか・・・ちょっと一般の常識とは違うけど決して間違った事はしてなくて
かつ自分の考えをしっかり持ってる賢そうな子というかだな
とにかく違うんだよ。

これだと思う。というか、読みながら「違うちがうんだよ」って日記に書こうとしていた内容がほんとにまるっきりこれと一緒で「おお」って思ってしまった。笑ってしまう。(もちろん途中のを否定してるわけではなくて、スレタイから想像したのが、おれの場合はこうだな、っていうことで)
ほんと、天然でも、のほほんでもない。惑わされずに生きてる日常に生きる子だと思う。

日記でまとめブログに言及したのは初めてな気がする。

素朴に日常的に、強く生きる女の子の表現

そういうのは、記号的に表現できない。例えば「ツンデレ」や「どぢっこ」みたいに、一言でうまくいい表せたりできない。特徴がないから、そういう子たちを描写するには、まわりのものを正確に表現してやる必要がある。「形」を表現するには、形をそのまま作る以外にも、それの「型」を作ってあげることでもできる。形がそのまま作れないなら後者を選択するしかない。型を精密に表現しさえすれば、その型の空洞部分の抜けおちた形が見えてくる。透明人間に砂をかけていくみたいに、表現をまぶしていく。

「看守は奴隷にパンを売りつけ 天使は太った裁判官に身体を預ける」

1st Full Album "the GOLDENBALLCITY"

ネギは完全におくら入りかw GOLDENBALLCITY って感じではないし仕方ないかなぁ。そのうちでるのかなぁ。

Apple star storyS がスタジオ収録になるのかな。楽しみだなぁ。あと Judgement; と黄金の鐘は結構前からあるやつだなぁ。前の公式に歌詞があったやつだ。

駄目人間衝動

駄目人間衝動

よくわからないけれど、駄目人間ってのは、駄目人間に向かおうとしてそうなると思う。とにかく全部駄目にしたい感じだ。もう駄目だって状況がどうしても必要だと思うようになることへ、こいつはもう駄目だと思われるように、本当はゼロへリセットしたいのだろうけど、それはうまくいかない。ゼロにするための努力があると、それができるとゼロへリセットする必要がなくなってしまうからだ。結果的に、誰かと関係を持ってしまった人間というのは、リセットしようとするとマイナス方向にまでいってしまう。そこで一度死に戻るか、本当にこの世界からいなくなる必要がある。

おれは今いまいち現実に生きているという感じがしない。ずっと夢の中にいるような感覚だ。どんどん駄目になっていく感じだ。しかし外に出て散歩をすると、風の匂いや虫の音、そこらの家から聞こえる生活音、肌に感じる空気の冷たさ、地上の明りに照らされる雲に幸せを感じてしまう。彼女なんていらないし、他の楽しいこともなくていいと思えてしまう。完全だ。維持できないが、このまま死んでもいいとさえ、感じられる。けれど生きている。

たぶん今日おれはそういうことからまた引き戻され、沈んでいくだろうけれど、それもまたおれが、ぼくが望んだことなんだろう。どうせまた徹夜をする。眠れないからだ。

集中せよ。なぜおれがやるべきことをできないのか。なぜ自分に甘えているのか。行動できないこと。「行動すればいい」がなぜ通用しないのか。努力すればいい、がなぜ通用しないのか。そういう彼らがどうしてそういうシステムを手に入れることができたのか。

でも大丈夫だ。どんなときだって死んだら全てが終わる。とことん駄目になっても、まだ生きたいと思うならそれでいい。

恥かしいと思うこと

そうだね。そうだ。

中学のときはまだ、友達っぽい人が今よりいて、自分の書いた文章とかを読まれるのは恥ずかしくて嫌だった。だから書かなかった。でもいつのまにか、そういう「友達」と付き合うことがなくなってから、恥ずかしさをあまり感じなくなった。同時に、誰か特定の人に何かを言うというのがひどく苦手になったので、どこかでそれを書かざるを得なくなった。いまでも「これは恥ずかしいことなんだろうなぁ」っていうのが解ったりはするし、まだ名残で書けないこともあるけど、なんだかどうでもいいことに思えるようになった。これによって相手がひいてしまうなら、別にそれでいいと思うようになった。彼らはぼくと違って急がしいから、ぼくの話を聴く暇はないし、ぼくもわざわざそれをひきとめて相手の時間を使ってまで何かを話そうという気持ちにはならなくなったのだ。会話の殆どはくだらないことだ。めんどうくさい愛想笑いをされるのは嫌だし、こちらだってしたくない。

into the headphone

私って少し異常なのかなって少し思って、ううん、こんなの誰でもあるんだって思いなおす。こんな下らないことにでも、アイデンティティを見出そうとして、馬鹿みたいだなぁって少し自己嫌悪。

私は音楽を聴くのが病的にって言える程好きで、だから、家でも外でもヘッドフォンをして、もう少し時代遅れのプレイヤーから音楽を流してる。私はこうしていないと落ち着かないみたい。一度プレイヤーの電池を切らしちゃって、そのまま出かけたことがあるのだけれど、どうしても不安でしかたなかった。小学生のころ一人で留守番したときのような、そんな不安。もう、あんな気持ちになるのは嫌だなぁ、なんて思いながら、私は今日も学校へいく。

少しだけ歩いて、少しだけ電車に乗って、また少しだけ歩く。そうすると私が通っている学校。教室に入る。誰もいない。一番乗り。少し嬉しい。少し寂しい。自分の席に座って、窓から空をみて、いい天気だなぁって思う。そしたら急に、頭に唄が浮かんで、聞きたいなぁって思いはじめて、まだ途中なのに、曲を変えてしまう。ごめんね前の曲さん。

そうやってぼーっとしてると、みんなが教室に入ってくる。担任の先生が来て、ホームルームをする。私はヘッドフォンをとる。そういえばこの前、ヘッドフォンしたまま眠ってしまって、先生に叩き起こされたなぁ。とか思い出してみたり。少し笑ってしまう。馬鹿だなぁ。

放課後になって、私は部活に入ってないから、家に帰る。別に入りたくないわけじゃなかったんだけど、なんだかタイミングを逃してしまった。だから、放課後は少し詰まらない。家に帰っても、やることなんてない。

セーラー服もそのままで、部屋に横になって、天井を見る。白い天井に、お母さんが作ったかさに包まれて、白熱灯がぶら下がってる。そして、もっとちゃんと笑えれば、男の子も寄ってくるのかなぁ、でも、もとがだめかなぁ、なんて、自分の恋について、考えてみたり。まあ、そんな日もあるのですよ。

そんなこんなで、ご飯を食べて、お風呂に入って、髪を乾かす。私の髪の毛は、自慢じゃないけど綺麗って褒められる。私も綺麗だと思う。って、やっぱり自慢だね。でも、ときどきこの髪を短く切ってしまいたいなぁ、なんて考えてしまう。なんでだろう?

寝る前に、ふとんに仰向けになって、好きな唄を少し聴く。目を閉じて、ヘッドフォンの奥の風景を想像する。そうやって見える風景がすごく好きで、なんだか、また明日も生きていけるかなって思う。そんなこんなで眠くなって、また明日。

明日は、何かいいことがあるかなぁ?

もともと lowreal.net は out of the headphone であった。しかしながらいつ変えたか忘れたけれど out of the washer になっている。ここは into the headphone であり、もう一つは in the headphone だ。分ける意味なんかない。もっとごちゃごちゃいいはずだ。そして一番ここが書くのがめんどうくさくない。自動的に手が動く。

さっさと仕事しろ

はいはいだめだめ。おれだめだめ。集中しろもっと。

外明るい。すこし赤い。「すこし赤い」という繋がりは、夏祭りと浴衣を着た女の子を想像させる。よくある想像だ。鳥居 π

人間的であることを忘れる。ずっとずっと。もうなんも書くことなんてない。いつも全部書いている。DEL おすといい。おれは恵まれすぎた。たくさん消費した。生み出すことができない。芸術的センスがないことが嫌だ。それはだれだって、本当は持っているはずなのに、たぶんおれだって持っていたはずなのに、ぜんぜんいまはない。どこ消えたんだか。センスがない。高校のときにはじめて気付いた。ずっと感じている。みんな羨ましい。

表面的なことができたってしかたがない。意味がない。誰にも伝わらない。

知らない。ずっと逃げ続けている。いつからだかわからない。こうならない方法があったかわからない。これからどうすればいいかずっとわからない。笑いながらこういう文章を書き続ける。ずっとノスタルジック。たしかに。無限ループたのしい。変わらない。灰羽思い出した。あれは DVD 欲しいよなぁ。

誠にさわやかな朝です

誠死ね。「真に」と「誠に」ってどう違うの。

資源ゴミの日なのでゴミ置き場までひとっぱしりしてきたのだけれど、やはり朝の空気というのは気持ちいい。SC440 のダンボール↑を捨てた。でかい。清々しい朝だ。チョコレートをいくつか食べた。今は漉し餡のもなかを食べている。

ソドシラソ / Syrup16g

ひさしぶりに聴いたらグッっときた。これ、なるほどなぁ。なるほど。

こういう発見があるものが大好きだ。

スルー力について言及してる。さすがイガラス。時代を先どり。

誰か何か言ってるぜ
聞き流す
振りして真に受ける

僕は自分の言葉なんて全く持っていません。全て誰かから借りられた言葉です。

戦争

ぼくは戦争をしにいくわけじゃない。これからもずっと、そんなことする気はない。でも、多かれ少なかれ、戦争のようなものを日々続けていくことになるだろうと思う。ぼくの状況はいつもいつも「大したことじゃない」

あまり本を読んでいない。でも本は好きだ。読まないのに本が好きなんておかしい。数えられるぐらいしか本を持っていないし、読んでいない。一番読んだ時期がそもそも高校のときで、大学に入ってから今まではもうぜんぜん読んでない。ラノベと今まで買った本と再読しかしてない。でも再読するたびに本に発見がある。頭が悪いから、一度じゃ絶対に理解できない。再読といっても最初から全部読むわけじゃない。「あのシーンってどこだっけ」と思ったときにそこから読みはじめる。

この大きな掌のような夜が一切の星座を統べながら次第にそのひろがりを閉じ、やがては暁の爽やかな薄明が東の空に星々のまどろみを消し去って行くその時に、

あの本なんだっけ

従兄弟の少年とバス停と病院がでてくる話で、冒頭の季節の描写がなんか印象に残ったやつがあったんだけどなんだっけ。短編だったはずなんだけど……

と書いたところで、どうせ持っている本が少ないのだから全部冒頭だけ読んで探せばいいだろと思いさがしたら、いよいよこれになかったら分からないなってところで発見できた。めくらやなぎと眠る女 (蛍・納屋を焼く・その他の短編) だった。内容をぜんぜん覚えてなかったので (女の子が病院にいることは覚えていた) 今読んでみたけど、よくわからなかった。そのうち分かるのかな。一生わからないかもしれない。

日記

おれはこんなこと書くことで何がしたいんだ? 誰かに「あいつってはあんなこと考えてるぅ」とでも思われたいのか。本当におれは気持ち悪い。でもやめることができない。日記により死ぬことを考えられるようになる。おれが死んだときに「あぁこいつ死んだのか」とそのうち誰かが思えばいい。そう思うことで、「いくらか悔いはあるけれど、死んでもいいか」という気持ちになれる。もちろん実際死ねるかどうかは関係ない。たぶん死ねないだろう。でも死んでもいいか、という気持ちになれることが大切だと思う。

これから、ネット世代が死んでいくと、ブログサービスはどうなるんだろう。もちろん運営会社が潰れない限り、リソースはもとの位置に残りつづけ、潰れたとしても、あらゆるところにキャッシュされたリソースが残るだろう。インターネットがなくならない限り。死んだ人のミームがインターネットをさまよい続け、誰かに影響を及ぼす。面白い。

でもインターネットもいつかはなくなる。想像しているより早くなくなるかもしれない。おれが生きている間に失くなるかもしれない。そういうものだ。基盤はみんなが思っているより全然ゆるい。

さらにいつか人類も地球もなくなってしまう。そのとき、そのあとまで、この宇宙ないし世界に、何か残せるだろうか? 何も残せない。形のあるものは残せない。内なる何かをどこかに留めらるかもしれないけれど、今の時代ではそれはないことになっている。どっちでもいいか。

髭剃り

ひさしぶりに髭を剃った。伸びすぎていて電動のやつでは無理なので普通の剃刀 (というのはおかしいか。ホテルとかでもらってきたやつ) で剃った。痛い。若干血がでた。若干若くなった。

もっとさがさないといけない

ano日記はやっぱりすごかったんだよなぁ。ほんとに残念だ。

ハルヒは実際にはデレているけれど、キョン主観なので表現されていないだけ

キョン主観なのにキョン対してデレているのが描写されていたら「あいつっておれに惚れてるんだぜ」ってキョンが言っているのと同じ意味です。ハルヒは実際にはもうすこしアプローチをかけていますが、キョンが逃げているため、それが描写されず、ちょっとおかしい言動が目立つ変な女が強調されているのです (「いやいやいや、こんな女だぜ。ないないない」みたいに必要以上の表現をしている)。完全に眼がそむけられない事実だけ語られているわけですね。

と考えたけど、作品の文体をよく覚えていないのでちゃんと終始キョン一人称なのか覚えていないのでした。(鶴屋さんのなんちゃらの描写があったからところどころに神視点が入っていたような気もする)

It's All Text! 使うことにした

C-f (Vim の Command モードとかのバインド) で開くようにしてみた。

でも input type="text" には無力なんだなぁ

今日の ~/tmp/test.rb

require "rubygems"
require "pathname"
require "active_record"

ActiveRecord::Base.establish_connection(
	:adapter => "sqlite3",
	:database => "test.db"
)

class Article < ActiveRecord::Base

end

~/tmp を定期的に晒すとか面白そう。でもだいたい公開できない。

2007年 10月 13日

もっと効率的にネットをフィルタリングしたい

全く有用じゃないエントリ (ただ叩いているだけとか) を効率的にフィルタリングしたいなぁ……

うまく自動化するのは言語解析しないとむりっぽいから、有用じゃないエントリ書いてるのを見たらチェックつけて、人ベースでサービスを横断して拒否できればいいかなぁ。はてなでそういうの書いてる人ははてな以外であんま見ないから、はてな内だけで id ベースのフィルタリングつくったらよさそうだ。

  • ブックマークコメを非表示にする
  • id ふくむパスを全て場合ページ内容を空に
  • LDR で id ふくむエントリをスキップ (ほってんとりとか)

あと、GM_setValue とかだとマシン間で同期するのがめんどいから、どっかに保存しておきたいなぁ。はてブの非表示ユーザを共有すればいいか。

2007年 10月 12日

gerry++

はらいたい

2007年 10月 13日

Erubis

gems 使えるコンテキストでは全部 Erubis 使うようにしよう。Erubis::EscapedEruby つかおう。
デメリットがない

gems

なんで gem spec のファイルを YAML にしちゃったのかなぁ。Ruby で eval できるコードを吐けばもっと高速で YAML への依存が減らせるのに
この場合 YAML 使う理由ってなんだろう。他の言語から読みかきするわけじゃないしというか結局吐く YAML が Ruby 依存になるし……

とおもったら、ローカル spec は Ruby で eval できるコード吐いてた (キャッシュは Marshal)。すいませんすいません。サーバとのやりとりだけ YAML なのかな

おかね

最近は前よりはビジネスについて興味を持てるようになった気がする。どうやって収入を得て、どこから出ていくのかみたいなのがすこし気になるようになった。でもとても気になるという感じではなくて、むずかしい話になるとカットされる。

Ruby に use を実装する。

RubyGems みたいに、あらかじめ spec をキャッシュしておく、みたいなのが許されるなら、こういうのもありなんじゃないかなぁと思った。以下の実装はいろいろだめなところがあるだろうけど…… (プラットホーム依存のところがほげほげとか)

# module 名 -> ファイル名へのハッシュテーブルを作る
# ruby 起動しまくって時間がかかるので前もってキャッシュする
require "pathname"
module_files = {}
$LOAD_PATH.each do |path|
	path = Pathname.new(path)
	next if path.relative?
	Pathname.glob(path + "**/*").each do |t|
		next unless t.file?
		next if t.to_s =~ /tk/
		puts t
		ENV.delete("RUBYOPT")
		ret = nil
		IO.popen("ruby", "r+") do |io|
			io.puts <<-CODE
				# 自分自身はロード済みにしないと、ループして require している場合にまずい
				$LOADED_FEATURES << '#{t.relative_path_from(path)}'
				$depend_lib = []
				def __modules
					ret = []
					ObjectSpace.each_object(Module) do |o|
						ret << o
					end
					ret
				end

				alias _require_orig require
				def require(lib)
					prev = __modules
					ret = _require_orig(lib)
					if ret
						$depend_lib.concat(__modules - prev)
					end
					ret
				end

				def set_trace_func(*)
				end

				prev = __modules
				stdout = STDOUT.dup
				STDOUT.reopen($stderr)
				begin
					_require_orig '#{t}'
				ensure
					STDOUT.reopen(stdout)
					print Marshal.dump((__modules - prev - $depend_lib).map {|i| i.to_s })
					STDOUT.flush
					exit!
				end
			CODE
			io.close_write
			ret = io.read
			ret = Marshal.load(ret)
		end
		ret.each do |m|
			(module_files[m] ||= []) << t.to_s
		end
	end
end

require "pp"
File.open("module.cache", "wb") do |f|
	Marshal.dump(module_files, f)
end

本体

def use(mod)
	mod  = mod.to_s
	mods = Marshal.load(File.read("module.cache"))
	raise LoadError, "#{mod} is not found." unless mods[mod]
	mods = mods[mod].map {|i|
		[i, i.split(File::ALT_SEPARATOR || File::SEPARATOR).size]
	}.sort_by {|i,ii|
		ii
	}
	mods.select {|i,ii| ii == mods.first[1] }.each do |i,ii|
		require i
	end
end

use %(Test::Unit::AutoRunner)
use %(Test::Unit::TestCase)

class UseTEST < Test::Unit::TestCase
	def test_success
		use %(Pathname)
		assert_kind_of Class, Pathname

		use %(Test::Unit::AutoRunner)
		assert_kind_of Class, Test::Unit::AutoRunner

		use %(ERB)
		assert_kind_of Class, ERB

		use %(ERB::Util)
		assert_kind_of Module, ERB::Util

		use %(WEBrick)
		assert_kind_of Module, WEBrick

		use %(Net::HTTP)
		assert_kind_of Module, Net
		assert_kind_of Class, Net::HTTP

		assert_raise(LoadError) do
			use %(NotInTableModule)
		end
	end
end

Test::Unit::AutoRunner.run($0 != "-e" && $0)

テーブルは require しているファイルに定義されているクラスを除いているので、test/unit.rb みたいな require をしている場合、そのファイルにいくら定義があっても「クラスの再定義/上書き」という判断しかできないので、use "Test::Unit" とかしても test/unit.rb は読みこまれない。

あとは webrick なんかを例にとると webrick.rb は他のファイルを require するだけなので、直接はこのファイルはモジュールハッシュ上にあらわれない。use では同じ深さを持っていて、WEBrick を定義している全てのファイルを require してる。

もっとたくさんテスト書いて、実装精密にすればつかえるかなぁ……

どっかのサーバで rubyforge の gems をミラーして解析して、このテーブルをつくっておいて、パッケージ検索できるようにするとか、あるいはそのままパッケージシステムにしてしまうとかがおもしろいかなぁ。既存の gems をそのままもってこれてたのしそう。

2007年 10月 14日

曜日べつゲリ統計

Mo   13 (18.1%)
Tu   14 (19.4%)
We   10 (13.9%)
Th   9  (12.5%)
Fr   11 (15.3%)
Sa   6  (8.3%)
Su   9  (12.5%)

ひさしぶりにとった。土曜日にむかうにつれて減るようだ

パッケージシステム

たとえば use みたいな感じのシステムをつくるとしても、あんまり使うイメージがうかばない。require "use" みたいなのは必要になってしまうし、require とは全然違う挙動をするから、なじむまでこまるし、中で何をやっているのかパっと見わからないから、ちょっとこわいし……(require はなにやってるのかわかりやすい)

というか RubyGems の何がいやか。なにを改善したらいいのか。パッチかけばすむのか。それでできるならそれにこしたことない。

  • パッケージ名 (gem.spec.name) と require で使う名前と、実際使う名前がそれぞれ関係ない。
    • auto_require つかって gem メソッド使えば少しはいい?
    • 1.9.1 で標準添付になったら、もっと gem メソッド活用してもいいかもなぁ
    • 実際使う名前がちがうのはどうしたらいいんだ。
      • でもこれは gem に限ってない。ostruct とか optparse とかも実際使うなまえと違うのでときどき混乱する。さすがによく使うから覚えたけど……
      • Python では import, Perl では use がある
      • require で読みこまれるファイルに新しいクラス/モジュールが定義されているとは限らない
      • autoload ってどういうケースを想定してるんだろう。
      • あるクラス・モジュール・メソッドがどこで定義されたものなのか簡単に知る方法がない
      • ビルトインの拡張とかどうするの
      • クラス定義のよみこみと機能の拡張はわけて考えてもいい?
      • require "test/unit" と use "Test::Unit" は後者だと定義されるだけみたいなの。実装できない
  • パッケージ名に統一感が全くない
    • camelcase だったり、そうじゃなかったり、アンダースコアいれたりいれなかったり
    • foobar-ruby とか ruby-foobar みたいなのおおい。 RubyGems って時点で ruby つかうのに
    • 政治的だから諦めるしかない?
  • rubyforge がダサい。
    • 機能での検索がしにくい。カテゴリわけされてない
    • プロジェクトだけあって中身がないのが割とある
    • 他にカッチョいい source があって、デフォルトで使用できればいい
      • gem とドキュメントだけホストして、カテゴリわけされていればいい
  • gem コマンドがいちいち遅い
  • require "rubygems" に抵抗がある
    • なんか一杯読みこむ
    • ほんとに読みこむだけでこんなに使ってるの?

require "rubygems" で定義される Module(Class) と読みこまれるファイル

["Gem::OperationNotSupportedError", "Gem::Exception", "Gem::LoadError", "Gem"]
["rubygems.rb",
 "rbconfig.rb",
 "rubygems/rubygems_version.rb",
 "thread.rb",
 "rbconfig/datadir.rb",
 "rubygems/source_index.rb",
 "rubygems/user_interaction.rb",
 "rubygems/remote_fetcher.rb",
 "net/http.rb",
 "net/protocol.rb",
 "socket.bundle",
 "timeout.rb",
 "uri.rb",
 "uri/common.rb",
 "uri/generic.rb",
 "uri/ftp.rb",
 "uri/http.rb",
 "uri/https.rb",
 "uri/ldap.rb",
 "uri/mailto.rb",
 "yaml.rb",
 "yaml/syck.rb",
 "syck.bundle",
 "yaml/basenode.rb",
 "yaml/ypath.rb",
 "yaml/baseemitter.rb",
 "yaml/constants.rb",
 "yaml/encoding.rb",
 "yaml/error.rb",
 "yaml/loader.rb",
 "yaml/stream.rb",
 "yaml/rubytypes.rb",
 "date.rb",
 "rational.rb",
 "date/format.rb",
 "yaml/types.rb",
 "zlib.bundle",
 "rubygems/digest/sha2.rb",
 "digest/sha2.bundle",
 "digest.bundle",
 "rubygems/digest/digest_adapter.rb",
 "forwardable.rb",
 "time.rb",
 "parsedate.rb",
 "rubygems/specification.rb",
 "rubygems/version.rb",
 "rubygems/security.rb",
 "rubygems/gem_openssl.rb",
 "openssl.rb",
 "openssl.bundle",
 "openssl/bn.rb",
 "openssl/cipher.rb",
 "openssl/digest.rb",
 "openssl/ssl.rb",
 "openssl/buffering.rb",
 "openssl/x509.rb",
 "rubygems/custom_require.rb"]

けっきょくいい方法がおもいつかなくて require にもどっていくのだなぁ……飽きるまで考えてみよう

依存ライブラリは次のバージョンから?かなり減るらしい。6ファイルぐらいに

Ruby で、メソッドがどこで定義されたか外から知る方法

「あるクラス・モジュール・メソッドがどこで定義されたものなのか簡単に知る方法がない」と書いたけど、ホントにホント?という切っ掛けで、メソッド内側の binding なら caller つかえば簡単にとれるけど、外から名前を指定してはとれないよなぁと思うので考えてみた。

class Object
	def location_of_method(name)
		c = nil
		ret = callcc {|c| false }
		unless ret
			m = self.method(name)
			args = [nil] * m.arity.abs
			set_trace_func Proc.new {|event, file, line, id, binding, klass|
				case event
				when "c-call"
					if id == name
						set_trace_func(nil)
						c.call([:native, nil])
					end
				when "call"
					set_trace_func(nil)
					c.call([file, line])
				end
			}
			m.call(*args)
			set_trace_func(nil) # attr_* 系で定義されたメソッドは call が trace できない?
		end
		ret
	end
end

class Class
	def location_of_instance_method(name)
		self.allocate.location_of_method(name)
	end
end

p Object.location_of_method(:new) #=> [:native, nil]
p Object.location_of_instance_method(:instance_eval) #=> [:native, nil]

require "pathname"
p Pathname.location_of_instance_method(:absolute?)
#=> ["/usr/lib/ruby/1.8/pathname.rb", 404]

require "ostruct"
p OpenStruct.location_of_instance_method(:initialize)
#=> ["/usr/lib/ruby/1.8/ostruct.rb", 46]

class OpenStruct
	def initialize
	end
end
# 直前の
p OpenStruct.location_of_instance_method(:initialize)
#=> ["test.rb", 44]

o = Object.new
def o.singleton_method_foo
end
# 直前の
p o.location_of_method(:singleton_method_foo)
#=> ["test.rb", 51]

require "webrick"
p WEBrick::HTTPServer.location_of_instance_method(:mount)
#=> ["/usr/lib/ruby/1.8/webrick/httpserver.rb", 111]

set_trace_func と callcc (継続) を使ってる。activesupport の Binding#of_caller の実装を少し前にみて「うわきめー」って思って使う機会があったら使ってみたい、とか考えていたら意外にホイホイあった。やってみてわかったことは set_trace_func 内のデバッグがすごくむずかしいということだった。
もっと簡単にやる方法があるかなぁ……

しかしモジュール定義とかはどうやってとるかがわからなすぎる。現在のファイルと require してるファイルを全部見てくしかないよねたぶん……

Delegater 使ってるときにうまくいかないなぁ。そもそも call がよばれてこない。なんでだろう。

require "tempfile"
p Tempfile.location_of_instance_method(:unlink)
__END__
(eval):3:in `__send__': undefined method `unlink' for class `NilClass' (NameError)
        from (eval):3:in `location_of_method'
        from test.rb:32:in `location_of_instance_method'
        from test.rb:85

Tempfile にも unlink が定義されているはずなのに、それが呼ばれない?で、スーパークラスのデリゲートが呼ばれているように見える。どういうことだろう……

なぜか Tempfile.allocate が nil になる

むーどうして allocate が nil になるかわからない。ちゃんと Class.allocate がよばれてるみたいなのに……

もうちょい改良

  • エラーができるだけでないように
  • スレッドセーフ
  • DelegateClass みたいなのに対応
class Object
	def location_of_method(name)
		old_state = Thread.critical
		Thread.critical = true
		name = name.to_sym
		c = nil
		ret = callcc {|c| false }
		unless ret
			m = self.method(name)
			args = [nil] * m.arity.abs
			set_trace_func Proc.new {|event, file, line, id, binding, klass|
				case event
				when "c-call"
					if id == name
						set_trace_func(nil)
						c.call([:native, nil, binding, klass])
					end
				when "call"
					set_trace_func(nil)
					c.call([file, line, binding, klass])
				end
			}
			begin
				m.call(*args)
			rescue Exception
			end
			set_trace_func(nil)
		end
		ret
	rescue ArgumentError
		false
	ensure
		Thread.critical = old_state
	end
end

class Class
	def location_of_instance_method(name)
		ret = nil
		old_state = Thread.critical
		Thread.critical = true
		self.ancestors.each do |c|
			break if c == Object
			[:location_of_method, :method_missing, :allocate].each do |m|
				[c, (class <<c; self; end)].each do |klass|
					begin
						klass.module_eval <<-EOC
							alias __location_temp_#{m} #{m}
							remove_method :#{m}
						EOC
					rescue NameError
					end
				end
			end
		end
		begin
			ret = self.__send__(:allocate).location_of_method(name)
		rescue NotImplementedError, TypeError, NoMethodError => e
			p e
		end
		self.ancestors.each do |c|
			break if c == Object
			[:location_of_method, :method_missing, :allocate].each do |m|
				[c, (class <<c; self; end)].each do |klass|
					begin
						klass.module_eval <<-EOC
							alias #{m}  __location_temp_#{m}
							remove_method :__location_temp_#{m}
						EOC
					rescue NameError
					end
				end
			end
		end
		ret
	ensure
		Thread.critical = old_state
	end
end

class Module
	def location_of_instance_method(name)
		c = Class.new
		# included を実行させない
		self.__send__ :append_features, c
		c.location_of_instance_method(name)
	end
end

#-- Test

def __modules
	ret = []
	ObjectSpace.each_object(Module) do |o|
		ret << o
	end
	ret
end
before = __modules

require "rubygems"
require "active_support"
require "active_record"

module_files = {}
(__modules - before).each do |o|
	next if o.name.nil? || o.name.empty?
	o.instance_methods(false).each do |m|
		r = o.location_of_instance_method(m.to_sym)
		if r
			(module_files[o.to_s] ||= []) << r.first unless r.first == :native
		end
		module_files[o.to_s] &&= module_files[o.to_s].uniq
	end
end

require "pp"
pp module_files

ri ひく Lusty-Explorer 拡張

http://lab.lowreal.net/trac/browser/config/.vim/plugin/lusty-explorer.vim.ext-ri.vim

\li でひらくようにデフォ設定。選択して RET で、そのまま補完候補バッファで ri のドキュメントを表示する。hjkl はプロンプトの入力にとられてしまっているけど C-p C-n で動ける。(ri のコマンドを ri にきめうちしてるので変えないとだめ。二箇所ある)

ほんとはもうちょい違う挙動にしたかったのだけど、めんどいので既存のを拡張する方向にした。Lusty-Explorer は Ruby だし簡単にできてよいよい。

ってかちょっと重すぎるなぁ……gems でライブラリいれてるとやばい

あれ、なんか C-c とか C-g で消えてくれない。なんでだろう

バッファ名がまずかったらしい。[LustyExplorer-ri] だとなぜか t という名前に変わってしまう。[LustyExplorer-Ri] だと大丈夫。よくわかんないな……vim のほうがそういう仕様なのかなぁ……

2007年 10月 15日

末尾再帰とか継続とか

解説ページをかなり前に一回、結構前に一回読んだんだけど、その二回とも「うーん、よくわからない……」でおわった。ループへの変換とかそういうのが、いまいちよくわかってなかった。

でも読んでから、ときどきそれを思い出して、反芻しているうちに理解できてくる。あぁそうかって思える。わけのわからないものだったけど、「こういうもの」っていうのがだんだん実感できてきて、継続なんかは末尾再帰のループ化にも繋ったりしておもしろい。継続は継続なんだなって思えてくる (ちゃんと理解して使えているかというと、ぜんぜんそんなことはないんんだけど、イメージができてくる)。本とか文書を読んで、そこでちゃんと理解する、っていうのは、頭が良くないとできないんだと思う。

そうなってから更めて Wikipedia とか見てみると納得できる。この確認作業も好きだ。

切ないに近いけれど、もう少し重い感情

っていうのは言葉にすると何になるんだろう……

AKG のケーブル

K271s のケーブルがミニプラグ側で断線ぎりぎり……

商品が見つかりません|サウンドハウス

たけー! 暇なときにミニプラグ側切ってそこらのステレオプラグにはんだ付けしよう。

他人の日記の生データみるやつ

見えない部分への考えかたがわかってしまいますね。

はてな記法は、例えば

aaaaaaa
bbbbbbb

aaaaaaa

bbbbbbb

は同じ (どっちも段落二つ) なので、どっちで書くかは人によったりたり。

Class.new(DelegateClass(Object)).allocate が nil を返すように見える問題 (あるいは inspect の上書きは慎重に)

--- delegate.rb.orig	2007-10-15 03:54:11.000000000 +0900
+++ delegate.rb	2007-10-15 04:01:23.000000000 +0900
@@ -95,7 +95,7 @@
   klass = Class.new
   methods = superclass.public_instance_methods(true)
   methods -= ::Kernel.public_instance_methods(false)
-  methods |= ["to_s","to_a","inspect","==","=~","==="]
+  methods |= ["to_s","to_a","==","=~","==="]
   klass.module_eval {
     def initialize(obj)
       @_dc_obj = obj
@@ -137,6 +137,11 @@
       raise NameError, "invalid identifier %s" % method, caller(3)
     end
   end
+  klass.module_eval do
+    def inspect
+        "#<#{self.class}:#{"%#0x8d"%self.object_id}:DelegateClass->#{@_dc_obj.inspect}>"
+    end
+  end
   return klass
 end

実際にはちゃんとインスタンスが返ってた。でも inspect まで丸投げしてるのでそれがわからなかった。inspect をそのまま委譲するのは正しいとは思えない。inspect が信用できなくなる。

require "delegate"
p Class.new(DelegateClass(Object)).allocate
#=> before: nil
#=>  after: #<#<Class:0x1ef50>:0xe6b48d:DelegateClass->nil>

location_of... がエラーでるのはこれとはまた別の問題……ここまで気付くのに数時間かかった……

そういえば tmpdir が予想と違った

なんとなく Tempfile の親戚だとおもって /tmp/hoge.9999.1 とかかえすとおもったら、たんに /tmp とか返すだけだった。

で、そういうディレクトリが欲しいときって自分で $$ とか書かないといけなくて嫌なんだけど、Tempfile はファイルを作って返すので使えず残念な感じになってしまう。個人的には Pathname に一時的なパスをつくるメソッドがあればいいと思った。

require "tmpdir"
require "pathname"

class Pathname
	@@tempname_number = 0
	def self.tempname(base=$0, dir=Dir.tmpdir)
		@@tempname_number += 1
		name = "#{dir}/#{File.basename(base)}.#{$$}.#{@@tempname_number}"
		path = new(name)
		at_exit do
			path.rmtree if path.exist?
		end
		path
	end
end

# ファイル
Pathname.tempname.open("w") do |f|
	f << "aaaaa"
end

# ディレクトリ
path =  Pathname.tempname
path.mkpath
10.times do |i|
	(path+"test#{i}.rb").open("w") {|f| f << "test" }
end

こんな感じのやつがほしい。特別ファイルをつくったりせず (Pathname なら作るの簡単だし)、ファイルでもディレクトリでもつかえる。

at_exit とファイナライザだと at_exit のほうが簡単な気がするけど、なんか問題あるのかな。デーモンだとたくさんできすぎるからかな。

そういえば、Pathname#mkpath が nil を返すけど、self を返してほしいと思うなぁ。

dir = Pathname.tempname.mkpath

みたいに書けると幸せ

GM

alert(document.getElementById("flvplayer"));
//=> [object XPCNativeWrapper [object HTMLEmbedElement]]
alert(unsafeWindow.document.getElementById("flvplayer"));
//=> [object HTMLEmbedElement]
alert(unsafeWindow.document.getElementById("flvplayer") === document.getElementById("flvplayer"));
//=> false
alert(unsafeWindow.document.getElementById("flvplayer") === document.getElementById("flvplayer").wrappedJSObject);
//=> true

ちょっと前に GetVariable でごにょごにょしてたときハマった……(XPCNativeWrapper 経由だと呼べない)

Ruby 書くとき

クラスを独自に拡張したのをどこに書くかで悩む……

そういうのに依存してしまうとコード単体で日記にはりつけたりがやりにくくなるしなぁ……ファイルの最初に書くぐらいしかないよなぁ

スター

消せないほうがいいなぁ、消せても今回の変更程度がぎりぎりだなぁと思う。まとめて消せるようになったら絶対嫌だなぁ。あくまでミスって一個つけちゃった、に対応できる、がいいと思う……

連打しといてあとでやっぱ消したいってのはなんかなぁ。

2007年 10月 16日

ネタ

「ネタなのかどうか、パッと見よくわからない」というネタが好き

あるいは、逆に「パッと見明かにネタなのに、中身は普通」というのも好き

はてなのマルチアカウントをうまくつかう userChrome.js スクリプト

http://svn.coderepos.org/share/lang/javascript/userchrome/hatena-multi.uc.js

はてなツールバーにも一応機能があるんだけど、よくわからないタイミングでクリアされたりする (クッキーの使いまわしで実装してるから?) ので tumblr のやつコピペして作った。

このスクリプトは Fx 全体へのフックとかは一切かけていないので、Window の初期化がちょっと遅くなる以外はパフォーマンスに影響しないはず

たたくべき相手間違ってるもんなぁ

テレビを日常的に見てああいうのに影響されたりする「友達」を多く持つ方々は、さぞリアル生活が充実しているのだろうなぁ。

いんぷれーす

お、グループにもその場編集機能だ。

2007年 10月 17日

Vertigo on Mac

なんかうまく表示されないのですよ

@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);


.tabbrowser-tabs * {
	width: 100% !important;
}

.tabs-stack {
	width: 10em !important;
}

とりあえずこうしたらちゃんとした。DOMInspector をインストールする方法さがすほうが大変だった……

「嫌いじゃないけど好きじゃない」
「好きじゃないけど嫌いじゃない」

は違う。


こうすると解りやすい

「嫌いじゃないけど好きじゃない (^^;)」-> リアル
「好きじゃないけど嫌いじゃない (#//)」-> ツンデレ

2007年 10月 18日

ngram 類似度 Ruby

無駄なことやりまくる

require "enumerator"

def ngram(data, n)
	ret = []
	data.split(//u).each_cons(n) do |a|
		ret << a.join
	end
	ret
end

def sim(a, b, n)
	agram = ngram(a, n)
	bgram = ngram(b, n)

	all  = (agram | bgram).size.to_f
	same = (agram & bgram).size.to_f

	same / all
end


require "rexml/document"
require "open-uri"
include REXML

entries = []
doc = Document.new(open("http://d.hatena.ne.jp/cho45/rss").read)
doc.elements.each("//item") do |e|
	title = e.elements["title"].text
	link  = e.elements["link"].text
	text = e.elements["content:encoded"].text
	text.gsub!(/<[^>]+>/, "")
	text.gsub!(/¥s+/, " ")
	entries << {
		:title => title,
		:link  => link,
		:text  => text,
	}
end

results = {}
entries.each do |a|
	entries.each do |b|
		next if a[:link] == b[:link]
		key = [a[:link], b[:link]].sort
		next if results[key]
		results[key] = {
			:a => a,
			:b => b,
			:sim => sim(a[:text], b[:text], 3)
		}
	end
end
results.sort_by {|k,i| i[:sim] }.each do |k,v|
	puts "%s: %s" % [v[:a][:link], v[:a][:title]]
	puts "%s: %s" % [v[:b][:link], v[:b][:title]]
	puts v[:sim]
	puts
end
2007年 10月 19日

なぜやればいい、という単純なことができないのか

なんなんだろう。こいつ死ねばいいのになぁ……自分っていう人間とは一生つきあっていかなきゃいけない。やだなぁ……

というまた安易な逃げに走る、という、悪循環

眠い

よくわからないのだけれど、昨日、今日と、なんだかめちゃくちゃ眠くてしかたがない。昼からコーヒー飲みまくっているにも関らず、そしてごちゃごちゃとプログラムを書いているにも関わらず、眠い。でも寝ると頭が痛くなる。よくわからない。寝ないと眩暈がする。

HTML/XHTML on Vim

タグ自動で閉じるやつ入れてから書くのが苦じゃなくなったなぁ。xyzzy のときぐらいいい感じ。surround.vim もあるからそれより楽かも

2007年 10月 20日

僕はオタクではありません。

「興味を持てるものがありません」とか「うちこめるものがなにもありません」とかと同じで、恥ずかしいと思うなぁ。できるだけオタクでありたいなぁ。オタクっていえるほどまだまだやりきっていないけど、プログラミング言語ヲタでありたい。 (これを自分の口から「そうです」っていうのはかなり勇気のあることだと思う。あらゆる言語をまぁ知っていますよってことだし……)。

はてスタ

一日経ったら削除できなくなる、とか

memo

秋大根は柔らかい/春大根はかたい。春大根は隠し包丁をいれよ

水 -> 大根 -> くしがとおるまで -> しょうゆ/シーチキン -> 15min -> さます

  • やわらかくなるまでは調味料を加えない

Vim のキーワード補完

ヒットしたキーワードが書かれているファイル名が preview されるけど、意味ないから引数とか表示させたいなぁ……
でも簡単にはできないっぽいなぁ。

Io-2007-10-10.tar.gz addons のロードメモ

libs/iovm/source/IoVMInit.c (.c だけど実際は Io でほとんど書いてある) に書いてあるけど、

searchPaths := list("io/addons", System installPrefix .. "/lib/io/addons")"

から searchPaths/#{addon-name}/build.io があるやつをよむみたい

Io> AddonLoader addons map(name)
==> list("AVCodec", "AppleExtras", "AsyncRequest", "BigNum", "Blowfish", "Box", "CFFI", "CGI", "Cairo", "ContinuedFraction", "Contracts", "Curses", "DBI", "Flux", "Fnmatch", "Font", "GLFW", "Image", "LZO", "LibSndFile", "Libxml2", "Loki", "MD5", "MySQL", "NotificationCenter", "ODE", "ObjcBridge", "OpenGL", "PortAudio", "PostgreSQL", "Postgres", "Python", "QDBM", "Random", "Range", "Rational", "Regex", "SGML", "SHA1", "SQLite", "SQLite3", "SampleRateConverter", "SkipDB", "Socket", "SoundTouch", "SqlDatabase", "Syslog", "SystemCall", "TagDB", "TagLib", "Thread", "UUID", "User", "Zlib")

使えるかどうかはロードしてみるまでわからない。トップレベルで参照しようとするとロードされる。

なので、

mkdir -p io/addons/FooBar
touch io/addons/FooBar/build.io 

とかやって FooBar を評価すると

Io> FooBar
  Exception: unable to read file 'io/addons/FooBar/depends'
  ---------
  contents                            AddonLoader.io 27
  Object FooBar                        Command Line 1

とかでて、なんかやってるのがわかる。

Io squareBrackets ちんこ演算子その他の雑多メモ

[1, 2, 3] は squareBrackets(1, 2, 3) と同じっぽいのだけど、デフォルトだと何にも割りあてられてない。

Io> squareBrackets := getSlot("list")
==> # io/A2_Object.io:401
method(
    call message argsEvaluatedIn(call sender)
)
Io> [1, 2, 3]
==> list(1, 2, 3)
Io> list(1, 2, 3)[0]

  Exception: List does not respond to 'squareBrackets'
  ---------
  List squareBrackets                  Command Line 1

Io> List squareBrackets := List getSlot("at")
==> List_at()
Io> list(1, 2, 3)[0]
==> 1
Io> [1, 2, 3][1]
==> 2

Io ではいろいろメッセージセンドになってる (てきと)。:= は setSlot の言いかえである。すなわち

Io> setSlot = method( "This is penis operator.\n" print )
==> method(
    "This is penis operator.\n" print
)
Io> seme := uke
This is penis operator.
==> This is penis operator.

Io> seme

  Exception: Object does not respond to 'seme'
  ---------
  Object seme                          Command Line 1

ということができる。もちろん上書きしているので変数への代入 (に見えるスロットへのセット) は行なわれない。ついでに uke も評価されないため、エラーが発生しない。仮引数を書かなければ暗黙的な評価はされない。

評価されるケース (仮引数を書いた場合)

Io> setSlot = method(a, b, "This is penis operator. Uke: #{b}\n" interpolate print )
==> method(a, b, 
    "This is penis operator. Uke: #{b}\n" interpolate print
)
Io> seme := "aaa"
This is penis operator. Uke: aaa
==> This is penis operator. Uke: aaa

Io> seme := uke

  Exception: Object does not respond to 'uke'
  ---------
  Object uke                           Command Line 1
  Object setSlot                       Command Line 1

あるいは call evalArgAt(n) で明示的に評価できる。( call sender doMessage(call message argAt(1)) の簡易版 )

Io> setSlot = method(uke := call evalArgAt(1); "This is penis operator. Uke: #{uke}\n" interpolate print )
==> method(
    uke := call evalArgAt(1); "This is penis operator. Uke: #{uke}\n" interpolate print
)
Io> seme := uke

  Exception: Object does not respond to 'uke'
  ---------
  Object uke                           Command Line 1
  Object setSlot                       Command Line 1

Io> seme := "uke"
This is penis operator. Uke: uke
==> This is penis operator. Uke: uke

interpolate というメソッドがでてきたけど、これは #{name} をローカル変数で置換するメソッド (式は書けないっぽい)


ブロックあるいはメソッドは、そのコンテキストに入るときにオブジェクトが一つ割りあてられる。これは JS でいうところの Activation Object (Io でも変数オブジェクトとして使われる) で、やはり直接それをとりだすことはできない?

Io> block( slotNames ) call
==> list("updateSlot", "call", "self")

とやると、上の call evalArgAt(1) で出てきた Call オブジェクトが入った call スロットがあることがわかる。



ちんこ演算子が使える言語なのでおもしろいですね。

2007年 10月 21日

Io で ERB みたいなの

EIo := Object clone do (
	string := ""
	compiledString := ""

	setString := method(string,
		self string = string asMutable
		self compiledString = self compileString(self string)
		self
	)

	doInObject := method(obj,
		# 汚さないように clone
		obj clone do (
			h := method(v,
				v asString asMutable replaceSeq("&", "&amp;") ¥
				                     replaceSeq("<", "&lt;") ¥
				                     replaceSeq(">", "&gt;")
			)
		) doString(self compiledString)
	)

	compileString := method(string,
		ret := "_eio_string := ¥"¥" asMutable¥n" asMutable
		n   := 0
		p   := 0
		while (n = string findSeq("<%", p),
			s   := string slice(p, n) replaceSeq("¥"", "¥¥¥"")
			n = n + 2
			c   := string findSeq("%>", n)
			mes := string slice(n, c)
			ret appendSeq("_eio_string appendSeq(¥"#{s}¥")¥n" interpolate)
			if (mes beginsWithSeq("="),
				if (mes beginsWithSeq("=="),
					ret appendSeq("_eio_string appendSeq(#{mes slice(2)})¥n" interpolate)
				,
					ret appendSeq("_eio_string appendSeq(h(#{mes slice(1)}))¥n" interpolate)
				)
			,
				ret appendSeq("#{mes}¥n" interpolate)
			)


			p = c + 2
		)
		s   := string slice(p) replaceSeq("¥"", "¥¥¥"")
		ret appendSeq("_eio_string appendSeq(¥"#{s}¥")¥n_eio_string" interpolate)
		ret
	)
)

# data := File openForReading("test.eio") contents
data := """
<p><%=hoge%></p>
<ol>
<% list("aaa", "bbbb", "ccccc", "ddddddd") foreach(i, v, %>
	<li><%=i+1%>. <%=v%></li>
<% ) %>
</ol>
"""

eio := EIo clone setString(data)
# eio compiledString print

context := Object clone do (
	hoge := "hogeog&e<>"
)
eio doInObject(context) print

出力

<p>hogeog&amp;e&lt;&gt;</p>
<ol>

        <li>1. aaa</li>

        <li>2. bbbb</li>

        <li>3. ccccc</li>

        <li>4. ddddddd</li>

</ol>

ヒアドキュメント書けた。トリプルクオートだった。ので修正

Io の解釈

Message fromString(code) code print

すると、Io がその文字列をどうやって解釈しているかわかる。

Message fromString("<p class='hoge'>aaaaa</p>") code print
#=> <(p class =' hoge '> aaaaa </ p) >

ol や p とかっていう呼びだしを method_missing みたいのでキャッチできれば E4X もユーザレベルで実装できそう。だけど method_missing 相当のことをどうやってやるのかわからない。

Io における演算子拡張

Io は演算子の Map を内部に持っていて、パース時にそれを参照する。

例えば =~ は定義されていないので

Message fromString("\"abc\" =~ \"a.\"") code print
#=> "abc" =~ "a."

となり、これだと =~ というメッセージを定義しても、後ろの文字列 (Sequence) は =~ メッセージの引数とは解釈されない。"abc" =~ と "a." は別の文になるわけです。

しかしながらこれは拡張することができて

OperatorTable addOperator("=~", 7)
Message fromString("\"abc\" =~ \"a.\"") code print
#=> "abc" =~("a.")

ということができる。7 は演算子の優先順で、OperatorTable print すれば登録済みの演算子とその優先順位がわかる。

Operators
  0   ' ( ) . ? @ @@
  1   **
  2   ++ --
  3   % * /
  4   + -
  5   << >>
  6   < <= > >=
  7   != ==
  8   &
  9   ^
  10  |
  11  && and
  12  or ||
  13  ..
  14  %= &= *= += -= -> /= <- <-> <<= >>= ^= |=
  15  return
  16  ,

Assign Operators
  ::= newSlot
  :=  setSlot
  =   updateSlot

To add a new operator: OperatorTable addOperator("+", 4) and implement the + message.
To add a new assign operator: OperatorTable addAssignOperator("=", "updateSlot") and implement the updateSlot message.

ところで若干のハマりどころなのは、

Object =~ := method(s,
	call message print
)
OperatorTable addOperator("=~", 7)

"abc" =~ "a."

とやっても、"abc" =~ "a." をパースする時点では addOperator はまだ評価されていないので、演算子にはならない。doString とかでこのあとにパースされるようにしないといけない。実際つかうとするとファイルをわけて doFile みたいになると思う。

Io かっけー

Io における method と block の違い

一番大きいのは doc に書いてあるとおりスコープの違い (というか、ローカルオブジェクト (=変数オブジェクト) がどこからクローンされるか) だけれど、それだけじゃなくて、call が必要かどうかもあるみたいだ。

a := Object clone do (
	aBlock  := block("called block")
	aMethod := method("called method")
)

a aBlock print
#=>
# # test.io:3
# method(
#     "called block"
# )
a aBlock call print  #=> called block
a aMethod print      #=> called method
a getSlot("aMethod") print
#=>
# # test.io:4
# method(
#     "called method"
# )

block の場合は自動的に呼ばれない。

Io × Vim

対応言語いっぱいの Vim でも io は色付けしてくれない。はてグに書くときは ruby としてシンタクスハイライト (意味的にどうよ)

ちなみに Io の do は Ruby でいうところの instance_eval で、レシーバをローカルオブジェクトにしてメッセージを評価する Object のメソッド

構文っぽくなる do, if, while とかはメソッド名のあとにスペース入れるようにしてる。

2007年 10月 20日

2007年 10月 21日

手編みのマフラー

手編みのマフラーというのは、愛情の大きさと継続性をあわせると考えうる限り最強のアイテムなので、安易に使用してはいけない。(別に恋愛に限らず親子愛であれ姉弟愛であれ)

ださ☆きも

はてなをダサキモということにしておくと、その程度でつかうのをやめるような人を効率的にフィルタリングできるので悪いとはいえない。

Io ObjcBridge

Io は ObjcBridge が最初からついてきててなかなかおもしろそう……と思いきやうまく動かなかった。

ObjcBridge autoLookupClassNamesOn
ObjcBridge debugOn

AppDelegate := Object clone do (
	applicationDidFinishLaunching: := method(aNotification,
		"launched" print
	)
)

app := NSApplication sharedApplication
app setDelegate:(AppDelegate clone)
app run
Io -> Objc (id)sharedApplication()
Io -> Objc (void)setDelegate:(id)
[Objc2Io respondsToSelector:"applicationWillBecomeActive:"] = 0
[Objc2Io respondsToSelector:"applicationWillResignActive:"] = 0
[Objc2Io respondsToSelector:"applicationWillFinishLaunching:"] = 0
[Objc2Io respondsToSelector:"applicationDidUpdate:"] = 0
[Objc2Io respondsToSelector:"applicationDidUnhide:"] = 0
[Objc2Io respondsToSelector:"applicationWillUnhide:"] = 0
[Objc2Io respondsToSelector:"applicationWillUpdate:"] = 0
[Objc2Io respondsToSelector:"applicationWillTerminate:"] = 0
[Objc2Io respondsToSelector:"applicationDidChangeScreenParameters:"] = 0
[Objc2Io respondsToSelector:"applicationDidBecomeActive:"] = 0
[Objc2Io respondsToSelector:"applicationDidResignActive:"] = 0
[Objc2Io respondsToSelector:"applicationDidFinishLaunching:"] = 1
[Objc2Io respondsToSelector:"applicationWillHide:"] = 0
[Objc2Io respondsToSelector:"applicationDidHide:"] = 0
[Objc2Io respondsToSelector:"validRequestorForSendType:returnType:"] = 0
Io -> Objc (void)run()
[Objc2Io respondsToSelector:"application:runTest:duration:"] = 0
[Objc2Io respondsToSelector:"application:openFiles:"] = 0
[Objc2Io respondsToSelector:"application:openFile:"] = 0
Objc -> Io (void)applicationDidFinishLaunching:(id)

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00000000 in ?? ()

debugOn だとブリッジのメッセージのやりとりがみれる。delegate 呼ぶときにおちてる。深く追ってない (追えない)

みてのとおり obj-c との名前の変換はない。

squareBrackets が未定義なのはこれのためってのもありそう? (実際 ObjcBridge では squareBrackets が定義されてる。けどいまいち使いかたがわからない)

.vim/syntax/io.vim

http://lab.lowreal.net/trac/browser/config/.vim/syntax/io.vim

で、ですね、書いたあと気付いたのですが、Io-2007-10-10/projects/SyntaxHighlighters/Vim にあったんですよ。どうしよう

Suddenly the Dungeon collapses!! - You die...

screen がおちた。はじめてだ。

2007年 10月 22日

Vim で blosxom クローン書いてみた

なんかいくつかの意味にとれますね。でもちゃんとうごくまでいくまえにめんどくなった (トップページだけなんとなく動く、っていう微妙な感じ)。

http://coderepos.org/share/browser/lang/vim/blosxom.vim.cgi/blosxom.vim.cgi

#!/bin/sh
""exec /usr/local/vim7/bin/vim -u NONE -i NONE --noplugin -e --cmd ":so $0"
" vim:ft=vim:
" -e で ex モードにすることで、エスケープシーケンスを排除してる。
"  完全じゃないっぽい?

で起動して、ダブルクオートは vim script ではコメントなので、vim に処理がうつったあとは exec が無視され、あとにつづくスクリプトが実行される。

開いた Vim 上で出力を生成して、

" Output
silent exe "w " . tempname()
silent exe "!cat %"
q!

最後に保存して cat で出力してみた (cat は反則な気がするけど、echo だとエスケープシーケンスがでてしまう)。もっと簡単な方法あるのかなぁ……


もうちょいアグレッシブに、

  • テンプレートをよみこむ
  • ヘッダ部分を s/// で置換する
  • エントリ部分を /entry-start^MV/entry-endYp でコピーしながら置換する

とかやったほうがおもしろいかも

Emacs で CGI 書く

#!/bin/sh
#@56
exec /usr/bin/emacs -Q --batch --no-unibyte --kill -l $0
; #@count は count 文文字をよみとばす elisp の機能
; vim:ft=scheme:expandtab:
; ↑ vim で elisp かよぷぷぷ scheme モードのほうがインデントがいい

(require 'cl)

(defun list-files (dir)
  (let ((ret '()))
    (loop for f in (directory-files dir t) do
          (let* ((attr (file-attributes f))
                 (dir?  (eq (car attr) t))
                 (file? (null (car attr)))
                 (mtime (nth 5 attr)))
            ;(print (list f dir? file?))
            (if (null (string-match "\\(\\.\\|\\.\\.\\)$" f))
              (progn
                (if dir?  (setf ret (append ret (list-files f))))
                (if file? (setf ret (append ret (list f)))))
              )
            )
          )
    ret)
  )

(princ "Content-Type: text/html; charset=utf-8\n\n")

(princ "<h1>aaaa</h1>")
(princ "<pre>")

(princ "Hello\n\n")

(print (pwd))
(print (list-files "data"))

(print system-configuration)
(print system-name)
(print (emacs-version))

(print (format-time-string "%Y-%m-%d %H:%M:%S" (current-time)))

(print (getenv "PATH_INFO"))
(print invocation-name)
(print process-environment)

(princ "</pre>")

Scheme と同じノリで書けるかと思ったら全然違う。Blosxom クローンつくろうとおもったけど途中までしか書いてない。続き書くかわからない。

2007年 10月 23日

zsh で blosxom クローン

http://coderepos.org/share/browser/lang/shellscript/blosxom.zsh/

entries[$i]="foo 1 bar 2"
typeset -A entry
: ${(AA)entry::=${(z)entries[$i]}}

とかやると、entry に { foo => 1, bar => 2 } みたいな連想配列が入る (実際には Perl みたいには書けない) 連想配列のキーをとりだすには ${(k)aarray} する。

typeset -A は連想配列の宣言 typeset -a だと配列の宣言になる。基本的に宣言なしで変数は使えるけど、連想配列は絶対に宣言しないといけない。

(AA) は連想配列をつくるやつ。(A) だと配列になる。(z) はコマンドラインにそれが書かれたかのようにアンエスケープしながら分割する。: は何もしないコマンド。引数評価だけされる。

エスケープは (q) でできる

foo="aaa  (aa)  "

echo ${(q)foo}    #=> aaa\ \(aa\)\ \
echo ${(qq)foo}   #=> 'aaa (aa)  '
echo ${(qqq)foo}  #=> "aaa (aa)  "
echo ${(qqqq)foo} #=> $'aaa (aa)  '

foo が空のとき (q) だとなんもなくなるのでまずい。(qq) のほうが安全

man zshall /Parameter Expansion Flags

2007年 10月 24日

RubyCocoa で chm 読むアプリケーションつくりはじめた

Mac でつかえる chm (HTML Help) よむやつでまともなのがないので作ってみた、けど、微妙にうまくいってない。

NSSearchField にフォーカスがあるとき、それ自身をサブクラスにしても親の NSWindow をサブクラスにしてもキーイベントがとれない。なんでだろ。これが解決しないことにはつかえないお……全部メニューコマンドにしちゃうかなぁ……Cmd+L でサーチエリアにフォーカスあたるようにしてる。ぎりぎり使えるかつかえないかレベル。HHK だと使う気にならない。


まともなのっていうのは

  • インデックスのインクリメンタルサーチができる
  • ストレスないぐらいには速い
  • 日本語がおかしかったりしない
  • キーバインドがまとも

っていう最低最低限レベルであって、なんか特別なことやりたいわけじゃない。探しかたがわるいだけなのかほんと見つからない。

作るなら Ruby で書きたいなと思って、chmlib っていう C のライブラリの ruby binding を swig 使って作って、それを利用して RubyCocoa 使ってすかすかつくった。chmlib をやるまえに pure ruby で書いてたんだけど、途中でめんどくさくなってやめた。swig は思ったより簡単だったけどめんどかった (でも一部の関数は使わないのもあって使えるようにしてない)

本体の処理は Chmox からだいたいパクってて、chmlib のバインディングのほうは PyCHM からパクってる。ぜんぶパクり。

あとユーザ CSS ほしいですね。すぐ実装できそう。

あとあと、ぜんぜんどうでもいいかもしれないのだけれど

url = "#{SCHEME}://#{doc.object_id}#{path}"
NSURL.URLWithString_relativeToURL(url, "#{SCHEME}://#{doc.object_id}/")

って感じで内部 URL を作るのに object_id を使っているのに萌えませんか! せんか!

URL はクラスを横断したりするから、ObjectSpace._id2ref だけでとれるとすごいスッキリ! 後処理も doc の参照はずすだけでいいし!

dylib をアプリケーションバンドルにふくめるにはどうしたらいいんだろう

static link しようとおもったらできないしなぁ。どうやるんだろう……
ld の仕組みもいまいちよくわかってない…… .a が static アーカイブ? でも直接指定しても otool -L するとシステムのほうを参照してるしファイルサイズ増えないしなぞい。OS X はリンクするときフルパスでリンクするんだなぁ……

DYLD_LIBRARY_PATH つかうのかなぁ。ruby の require の前に DYLD_LIBRARY_PATH をバンドルの Resource dir にしたらいけるかなぁ……わかんないけどやってみよう……

あれもしかして standaloneify ってこれもやってくれるのかな。やってくれるのかな、っていうか、実行すると dylib もあつめてつかってるライブラリとおなじディレクトリにほうりこむみたいだ。これでうごくの?

sudo mv /usr/local/lib/libchm.0.dylib /usr/local/lib/libchm.0.dylib.t 

とかやって standaloneify 後のアプリひらいてみたけどちゃんと起動した。すげ

CHM メモ

Gauche のへるぷで落ちまくってたけど、がんばってデバッグしたら (うそ。Chmox では読めたので (同じライブラリつかっているのに) ロジックをパクってきた) みれるようになった。よいかんじ

Gauche とか、あんまり知らない言語はほんとにリファレンスをひきまくるから、かんたんにひけると超絶早く言語が習得できそう。

2007年 10月 25日

Chemr

今日のスナップショット

http://lab.lowreal.net/test/chemr/Chemr.2007-10-24.dmg

全部入りの dmg です。RubyCocoa さえ同梱してあります (svn head にちかめ)。たれかです。


あとキーバインドを設定からよむようにして (たぶん ~/.chemr/chemr-keys あたりを eval するだけ)、ユーザ CSS はかなぁ。実装自体よりどうやったら簡単かで悩むむ。

キーバインドはいまのところ

keybinds = {
	"C-j" => self.method(:nextCandidate),
	"C-n" => self.method(:nextCandidate),
	"C-k" => self.method(:prevCandidate),
	"C-p" => self.method(:prevCandidate),
	"¥r"  => self.method(:jumpToCurrent),
	"¥t"  => self.method(:completion),
	" "   => Proc.new {|s|
		@webview.stringByEvaluatingJavaScriptFromString <<-JS
			window.scrollBy(0, 200);
		JS
	},
	"C-u" => Proc.new {|s|
		@search.stringValue = ""
	},
	"G-[" => Proc.new {|s|
		@webview.goBack
	},
	"G-]" => Proc.new {|s|
		@webview.goForward
	},
	"G-=" => Proc.new {|s|
		@webview.makeTextLarger(self)
	},
	"G--" => Proc.new {|s|
		@webview.makeTextSmaller(self)
	},
}

こんなかんじにしてある。.call! .call! Duck Typing! JS よんでるのがすこしきもいけど、WebView の API しらべるより簡単だし、いろいろできそうな感じがしてこれはこれでいい気がした

とにかくもう Ruby で書いてあるからもうなんでもできますね。ってかんじだけれど、トピックツリーを処理させるようにすると、NSOutlineView のよびだし (でも delegate メソッドではない) で頻繁に落ちようになったり、あと謎のタイミングで落ちるようになったりしたので機能を無効化してある。どうせキーワード検索しかつかわない。

2ファイルにしか分離せずクラスに機能をめっさ詰めこんでる (デリゲート対象になりまくってる)。これたぶんよくないんだろうけど、めんどいしなぁ。

Enumerable#group_by

なんでないんだろう。いままで partition がこれだとおもってた。

module Enumerable
	def group_by(&block)
		self.inject({}) {|r,i| (r[yield i] ||= []) << i; r}.values
	end
end

foo = Array.new(10) { rand(40) }

require "pp"
pp foo.group_by {|i|
	("%02d" % i)[0]
}

partition より汎用的で、partition にするにも ! 一個足すだけだからこっちがあったほうがいいと思うんだけどなぁ

検索してみると既出すぎる……ActiveSupport にもあるんだ

Chemr どうにかしたいリスト

  • ページ内検索
  • 全文検索 (chmlib binding のほうに API だけは移植した)
  • InputMethod の変換中はキーバインドを無効にしたい (IM の有効無効をどうやってとるか謎い)

実装メモ

  • WebView の performFindPanelAction はうごかない
    • なんでっておもってたけど、そういうもんみたいだ。リファレンスにのっけておくなよ><
  • 全文検索で日本語が検索できない。
    • binding の実装がわるいんだろうけど (文字コードを NKF で変換できる範囲で変えてみたけどだめだった)
    • 実装しなおすにはフォーマットをちゃんと理解しないといけない
    • 閉じた仕様でなおかつ消えていきそうな仕様の理解を深めても……
    • とはいえ実装おったり、http://www.nongnu.org/chmspec/latest/Internal.html#FIftiMain 読んだりした……めんどくさい
  • OutlineView はやっぱ落ちまくる
    • Tree 表示のタブを選択するまで、データソースを設定しないようにしてみた
    • 表示させちゃうと (しかもたくさん CHM ひらいていると) 落ちやすくなる
  • IM 変換中のキーバインド無効はコメントをいただいたのをそのまま条件文に
2007年 10月 26日

Chemr TODO

  • chm じゃなくても HTML + index つくればみれるようなの
    • 無駄に時間かかるし、Windows 必要だし……
    • てきとうにバンドルにしたらよさそう
    • そもそも Apple Help を忘れてるだろ……
  • 設定分離 (いい方法考えるのがめんどくさい)

Apple Help メモ

http://developer.apple.com/documentation/Carbon/Conceptual/ProvidingUserAssitAppleHelp/

キーワード機能がない。全文検索だけ。

Amalgam

QuickSilver がスタンバイから復帰するとおかしくなったり、やたら重くなったり、途中から候補がおかしくてアイコンがおかしくて……になったりで度々再起動させられるのにうんざりしたので、それ RubyCocoa でっておもって書きはじめてとりあえず自分でつかえるぐらいにはなってきた。QS をあんまり深く使ってなかった。すぐ作れる RubyCocoa はほんとすばらしい。

http://screencast.com/t/xmHrG0w6

ホットキーおすと、コンボボックスがおもむろに現われて、うちこんで RET で起動する。SO☆RE☆DA☆KE

ホットキーの実装部分は前につくってあったのでそれそのままつかって、あとは最近覚えた IB 上で NSView つくってほげほげみたいな連携とかをしながらできるだけ時間をかけずにつくってみた。

やっぱ完成度50%ぐらいからすすみがわるくなるなぁ……つくりはじめが一番たのしい。

あと設定をてきとうに eval するようにすれば自由に候補を追加してラウンチできるようになりそう。デバッグコマンドとかもコマンド (引数をとる) として分離したらいいかなぁ。

名前は QuickSilver が水銀だから、それっぽいのに

QS の使いかたとか設定を覚えるより、RubyCocoa でかいてしまって、設定を Ruby で書いてしまうほうが他に応用できていいなぁとおもった。


そういえば orderOut したときに他のアプリにフォーカスがうつらないんだよなぁ……

Chemr 2007-10-26

http://lab.lowreal.net/test/chemr/Chemr.2007-10-26.dmg

http://coderepos.org/share/changeset?new=lang%2Fruby%2FChemr%40740&old=lang%2Fruby%2FChemr%40689

いろいろ変更

  • ツリー表示を有効に
    • キーワードがメインなのはもちろんそのまま
    • OutlineView の注意事項はちゃんと読むと書いてあるんだなぁ……冒頭の部分を飛ばしてよんでて、API しかみてないのがバレバレすぎる……
  • UserCSS
    • ~/.chemr/userstyle.css を読む
    • WebView の機能をそのままつかっているのでキャッシュがきいたりするかも
  • 一部の chm で落ちてたのを暫定的に修正
    • .js でおわるファイルを読まないようにした
  • とりあえずの全文検索をつけた (Ctrl+RET すると全文検索)
    • 日本語きかない。でもあんまり困らないからプライオリティひくい
  • ページ内検索
    • キーワードの検索エリアに検索文字列を入れたうえで Cmd-F

usercss はとりいそぎ Cocoa の chm をリコンパイルするのがめんどいのでつけた。

英英 on Mac

どうでもいいけど、WebKit つかっていたりするやつだと Ctrl-Cmd-D でカーソル直下の単語を辞書でひけるのでべんりべんり (おしっぱだとひきっぱなしにできる)。もちろん WebView そのまんまつかっている Chemr も例外でなくて、そのままつかえる。Cocoa はすばらしいなぁ……

2007年 10月 27日

今の Amalgam の曖昧検索と Chemr の補完

r = /(#{str.split(//).map {|c| Regexp.escape(c) }.join(").*?(")})/i
@now.concat @candidates.select {|i|
	r === i.name
}.sort_by {|i|
	# 文字が前のほうに集っているほど高ランクになるように
	m = r.match(i.name)
	(0...m.size).map {|i| m.begin(i) }.inject {|p,i| p + i }
}

もっとうまくかけるかな、というかいいアルゴリズムあるかな……(Chemr にもうつそう)
いまつかってるかぎりだとけっこういい感じ

adp
Adobe Photoshop
fi
Finder
dip
Displays.prefPane
dis
Displays.prefPane
thu
Thunderbird
safa
Safari
tem
Terminal
trm
Terminal
itu
iTunes

みたいにそれっぽくトップにくる。てきとうにうってもあたるのはやっぱいいなぁ。QS もそうだけど


あと Chemr で TAB おしたときに

keys[0].zip(*keys[1..-1]) do |a|
	m = a.first.downcase
	if a.all? {|v| v && (m == v.downcase)}
		common << m
	else
		break
	end
end

ってやってるけど、もっとうまく書けないかなぁ……要素中の先頭から共通の部分を最長でもってくる……

こういうの考えるの苦手すぎる……すなわち頭が悪いというこなんだけど……

Chemr 2007-10-27

http://coderepos.org/share/changeset?new=lang%2Fruby%2FChemr%40759&old=lang%2Fruby%2FChemr%40740

http://lab.lowreal.net/test/chemr/Chemr.2007-10-27.dmg

  • .chm バンドルをサポート
  • 検索結果がなくなった場合自動的に曖昧検索になるように
    • 曖昧検索中はテーブルビューが赤くなる
    • かなり重いのでデフォルトにはできない……
2007年 10月 28日

千石原

今日は両親と一緒に千石原へ。昨日の台風のおかげで雲ひとつない。写真を90枚ほどとった。1Gbytes ぐらい。

なんか、あれだけど、観光地の飯屋で、まずいところほど罪深いところはないと思う。観光地自体がつまんないのは別にいいと思うけど、飯屋がまずいのはほんとにあれだと思う。そういう店はさっさと滅びるべきだ。想像したらわかるだろうけど、例えばデートとかで「おいしいお店だといいね!」とかいってそういう店屋に入って、「おいしくなかったね」っていう、そういういたたまれなさとか、嫌じゃないか。もちろん二人でならそういったある種の困難、みたいなものがあっても乗り超えていけるだろうけど、べつにそれはどうだっていい。とにかく、そういうまずい飯を出す店っていうのは、根本的に想像力 (あるいは味覚) が欠如しているんだと思う。

なんか USB のメモリリーダが Windows@SC440 で認識しない。いいけど Mac は無線でつないでで遅いから鯖に転送するのがたいへんだ……というかそろそろ鯖の容量がきつくなってきたのでどうにかしたいけどうにもできない。

「花が終わるとあの清楚な姿は消え、葉が伸び広がり、キャベツのお化けのような姿に変わります」

水芭蕉のことを説明している看板に書いてあったんだけど、なんかちょっと暗い部分があるいいかただよなぁと思った。あと引用だけ書くとどっかの小説にでてきそうだなぁ

IMG_60520077
順光

IMG_60560075

逆光

千石原

というかなんかカップルが結構いて微妙に腹立たしい……と思いきやそうでもなく、なんか今日の自分はいつにも増して妄想力が働いていて、ああ彼らにはこんなストーリーがあったんだろうなぁとか、こんなイベントであんなフラグがたって今ここにいるんだなぁとか考えてにやにやしてたまじきもい。

DSLR

若い女性の一眼はニコン多いなぁ。キムタク効果なのか単に値段なのかはわからないけど……

RAW

Photoshop の現像時のごみとり機能が便利だ。パッチツールみたいなやつだけど、自動で似た色のところを選択するっぽい。いまつかってる一眼がゴミはいってるんだけどどこについているかわからない……開放してとっているときはボケて気にならないけど、絞るとおもっきり写るんだよなぁ

RubyCocoa メモ

  • NSArray の便利メソッドはわりと最近追加された
    • Array とか Enumerable のメソッド
    • 今リリースされているやつだと使えない
  • NSDictionary は Symbol 渡しても String 渡しても同じように扱ってくれる
    • dic[:hoge] dic["hoge"] がおなじ
  • 0 と false は別ものに変換される
    • 最近の修正? かな @window.setOpaque(0) がきかなくて気付いた
    • r1874 かなぁ。0.12.0 が r1925 だから最新リリースでは既にそうだったみたいだ
  • hogehoge= を呼ぶと setHogehoge に変換してくれる
    • これのおかげで @input.stringValue += "hogehoge" とか書ける
  • 最近いろんな Obj-C の inspect がわかりやすくなった。r2038?
    • いちいち p arr.to_a とかしなくてもいいし、p str.to_s とかもする必要ない
    • pp も対応してるらしい r2092?

NS* 系がほぼ Ruby のオブジェクトと同じように扱えるようになってて、あんまり違いを意識する必要がなくてすてき。

2007年 10月 29日

GranParadiso

Firefox の history.dat の形式に嫌気がさした (パーサ書いたけど、大量のヒストリあると重くて使えない……) ので Fx3 に乗りかえるお><
GranParadiso Alpha8 入れた! 常用してやる!!!! (FireBug と Greasemonkey がない時点でむり)

userChrome.js が有効なっているけど、hatena のきりかえはどっかバグってるっぽいなぁ

いきなり常用プロファイルで起動して大丈夫かなぁと思ったけど、割と大丈夫っぽい。2.0 に戻れないかもだけど

やばい GM なしで生きていくのはつらい。というか GM 入れてない人ってよくインターネットできるよな……

memo

CREATE TABLE moz_anno_attributes (
	id INTEGER PRIMARY KEY,
	name VARCHAR(32) UNIQUE NOT NULL
)
CREATE TABLE moz_annos (
	id INTEGER PRIMARY KEY,
	place_id INTEGER NOT NULL,
	anno_attribute_id INTEGER,
	mime_type VARCHAR(32) DEFAULT NULL,
	content LONGVARCHAR,
	flags INTEGER DEFAULT 0,
	expiration INTEGER DEFAULT 0,
	type INTEGER DEFAULT 0,
	dateAdded INTEGER DEFAULT 0,
	lastModified INTEGER DEFAULT 0
)
CREATE TABLE moz_bookmarks (
	id INTEGER PRIMARY KEY,
	type INTEGER,
	fk INTEGER DEFAULT NULL,
	parent INTEGER,
	position INTEGER,
	title LONGVARCHAR,
	keyword_id INTEGER,
	folder_type TEXT,
	dateAdded INTEGER,
	lastModified INTEGER
)
CREATE TABLE moz_bookmarks_roots (
	root_name VARCHAR(16) UNIQUE,
	folder_id INTEGER
)
CREATE TABLE moz_favicons (
	id INTEGER PRIMARY KEY,
	url LONGVARCHAR UNIQUE,
	data BLOB,
	mime_type VARCHAR(32),
	expiration LONG
)
CREATE TABLE moz_historyvisits (
	id INTEGER PRIMARY KEY,
	from_visit INTEGER,
	place_id INTEGER,
	visit_date INTEGER,
	visit_type INTEGER,
	session INTEGER
)
CREATE TABLE moz_items_annos (
	id INTEGER PRIMARY KEY,
	item_id INTEGER NOT NULL,
	anno_attribute_id INTEGER,
	mime_type VARCHAR(32) DEFAULT NULL,
	content LONGVARCHAR,
	flags INTEGER DEFAULT 0,
	expiration INTEGER DEFAULT 0,
	type INTEGER DEFAULT 0,
	dateAdded INTEGER DEFAULT 0,
	lastModified INTEGER DEFAULT 0)
CREATE TABLE moz_keywords (
	id INTEGER PRIMARY KEY AUTOINCREMENT,
	keyword TEXT UNIQUE
)
CREATE TABLE moz_places (
	id INTEGER PRIMARY KEY,
	url LONGVARCHAR,
	title LONGVARCHAR,
	rev_host LONGVARCHAR,
	visit_count INTEGER DEFAULT 0,
	hidden INTEGER DEFAULT 0 NOT NULL,
	typed INTEGER DEFAULT 0 NOT NULL,
	favicon_id INTEGER
)

places.sqlite + ActiveRecord

require "rubygems"
require "active_record"
require "active_support"

ActiveRecord::Base.establish_connection(
	:adapter => "sqlite3",
	:database => "places.sqlite"
)

class MozHistoryvisit < ActiveRecord::Base
	belongs_to :place, :class_name => "MozPlaces", :foreign_key => "place_id"
end

class MozPlaces < ActiveRecord::Base
end

p Time.now.yesterday
# なんか 6桁ちがうのでかけてみてる……
# ソースよまないとよくわからなそう
from = Time.now.yesterday.to_i * 1000000

MozHistoryvisit.find(:all, :conditions => ["visit_date > ?", from]).each do |h|
	place = h.place
	puts place.title
	puts place.url
	puts place.visit_count
	puts
end

GranParadiso のロケーションバー補完

なんかちょっと Fx2 よりディレイあるなぁ。

Amalgam

補完候補を生成するプロセスとランチャが実際動いてるプロセスを分離したほうがいいかもなぁ。Ruby のスレッドだと影響しあっちゃうし、マルチコアの恩恵がうけられないし、ごちゃごちゃやったりするので Cocoa と通信してるよこでやったりするとたまに落ちる。起動直後 fork して DRb るのがいいのだろうか

Amalgam 2007-10-29

http://lab.lowreal.net/test/amalgam/Amalgam.2007-10-29.dmg

つかれてきた。プラグインで候補を追加できるのと、サブランチャを作れるところぐらいまでやった。起動がクソ遅い (毎回アプリケーションフォルダスキャンしてるから)

プラギンは ~/.amalgam/plugins において、.d reload_plugins すれば(リ)ロードされるように

プラギン自体は http://coderepos.org/share/wiki/Amalgam#plugins みたいになっていて、候補を生成するとき毎回プラグインの candidates メソッドが呼ばれる (なので必要ならプラギン側でキャッシュする必要がある)

サブランチャは http://coderepos.org/share/browser/lang/ruby/Amalgam/plugins/folders.rb こんなんみるとなんとなくわかるかもしれない。amalgam.sublaunchers 配列に push すると候補を生成するやつ (とフィルタしてソートするメソッド) をそのオブジェクトに委譲する。

サブランチャから戻るには C-b で、サブランチャの中では空白 RET でも選択されたアイテムが実行される (通常は空白 RET はキャンセル扱い)

デバッグコンソールみたいなのをアプリケーション内にもったほうがいいなぁ。SEGV には無力だけど……

GranParadiso に Greasemonkey

強制的に有効にしたら普通につかえた。

https://addons.mozilla.org/ja/firefox/addon/421 が便利っぽい。アイコンがださいけどw

Amalgam Fx ヒストリ

fuzzy 検索にしたくて URL リストをとってきてこっちでやっていたんだけど、重すぎなのと不安定 (スレッドつかってるから) なので、SQL クエリを直接なげるようにした。LIKE をてきとうに投げて、visit_count でソートするようにしてみた。だいたいロケーションバーの補完とにたかんじに

http://coderepos.org/share/changeset/838

設定とかプラグイン

って、すごく気をつかう部分だよなぁ……実装しまくるっていう感じじゃなくて、よく考えて実装して、一度置いて、また考えて、みたいなのを繰り返さないと良い設計にならない……たぶんすごい人はいっきにできてしまうんだろうけど……

スレッドとか DRb とか RubyCocoa のくみあわせ

どうも相性わるくて、落ちるときは確実に落ちるけど、最小再現つくろうとすると落ちない。メインスレッド以外で Obj-c のオブジェクトにアクセスするとまずいっぽいけど確実にそうってわけでもないしなぁ……

ruby のバージョンあげないとだめなのかも

ruby 本体へのパッチってこういう系の問題対処だったんだ

パッチあて済みの libruby がレポジトリにはいっていたのでそれそのままコピーしたら落ちなくなった

cd /usr/lib
sudo mv libruby.1.dylib libruby.1.dylib.orig
sudo cp ~/project/rubycocoa/src/misc/libruby.1.dylib . 

http://rubycocoa.sourceforge.net/EmbedRubyCocoa

2007年 10月 30日

Chemr + Amalgam

Chemr でいっぱい開いてると、目的のやつにたどりつくまでめんどいので、Amalgam から検索できるようにしてみた。DRb++

http://screencast.com/t/9jJng5yu7U

http://lab.lowreal.net/test/chemr/Chemr.2007-10-30.dmg (設定可能版の Chemr)

  • http://svn.coderepos.org/share/lang/ruby/Amalgam/user-plugins/chemr.rb を ~/.amalgam/plugins に
  • うえのファイルの =begin ~/.chemr/initrc.rb から =end までを ~/.chemr/initrc.rb に追記
  • Chemr 再起動してファイルたくさんひらく
  • .d r "Chemr" (プラグインのトップレベル候補をリロード)
    • 機能のバージョンだとできないので touch ~/.amalgam/plugins/chemr.rb して .d reload_plugins
  • chm ファイル名でトップレベルに候補追加
  • 選択して RET するとサブランチャに (初回は Chemr から index をとってくるのでおもい)
  • さらに選択して RET すると該当のウィンドウがアクティブになって項目を表示

libruby ふくめてないからそのままだと落ちると思う。ぜんぶにふくめたほうがいいのだろうなぁ……

ローカル gem の chm バンドルをつくる ruby スクリプト

http://coderepos.org/share/browser/lang/ruby/misc/chm-generators/generate-local-gems-chm-bundle.rb

カレントディレクトリに GemRdoc.chm というバンドル (Chemr だけで読める) をつくる (ただしテンプレに Resh をつかっていること前提)。ドキュメントの実体は gempath にあるほうなので、gem install したり削除したりしたら実行しなおす。バンドルみたいにただのディレクトリだと symlink とかつかえてよい。

AR とか AS のももちろんインデクスされるので、そういう系の .chm はいらなくなった。

.chm にコンパイルするのも yaml から変換すれば簡単にできるだろうけれど、時間かかるのでめんどそう

mobirc いれた

これはすばらしい。

keitairc のとき読むのがめんどくさくてずっと basic password を毎回いれてたけど、これで開放される…… (N73 は接続きれたりすると再入力になってしまう)

あとキーワード機能がすばらしいなぁ。重要なのだけピックアップできるのがすてき。

モバイルの CSS ってどんぐらい効くんだろう。N73 だと twitter がかなり綺麗に表示されるけど、あれは外部 CSS になってんのかなぁ。モバイル事情を知らなすぎる。

N73 メモ

  • ブロック要素でも縦の margin 指定がきかない
  • padding はきく
  • body { margin:0; padding:0 } しても上下にマージンがでる
  • bold にならない
  • フォントサイズは割と変えられる (というか ttf よんでる)
  • input[type="text"] に対応している (CSS2)
  • 外部スクリプトは呼べない
  • document.writeln だけ確認
  • Opera mini
    • 外部スクリプトよべる
    • alert できる (中央にメッセージ表示)
    • Opera のサーバを経由する (全部のページがケータイ向けに変換かかる)

gerry++

なんか腹痛い……

2007年 10月 31日

Perl memo

mobirc で Perl の学習をする日

検索用 -> 変数に入れたメソッド名・サブルーチン名でサブルーチンを呼びだす Ruby send

$self->$method_name;

{
    no strict 'refs';
    &$method_name();
}

__PACKAGE__->can($method_name)->();

POE と Perl の基本メモ

KERNELとかはPOEがエクスポートしてる関数。@array[1,2,3] とかは配列のスライス。ハッシュ版は @hash{'key1', 'key2'}

http://twitter.com/typester/statuses/375208972

@_[KERNEL, SESSION] とかが全く読めなくてこまったんだぜ! (そして最終的に使わなかった)

n行で書くテンプレートエンジン

io のやつは 50 行ぐらいだった。いい線じゃないですか!! 正規表現ないのに!!! (あるけど標準じゃない)

とかはどうでもよくて、Ruby で 40 行で ERB に似てるテンプレートエンジン (たぶんすごいだめなバグがある気がする)

class MiniERB
	module Util
		ESCAPES = { "&" => "&amp;", "<" => "&lt;" , ">" => "&gt;"}

		def escape(str)
			str.to_s.gsub(/[#{ESCAPES.keys.join}]/o) {|i| ESCAPES[i] }
		end
		module_function :escape
	end

	attr_reader :src

	def initialize(template)
		@src = compile(template)
	end

	def compile(s)
		ret = "_tt_string = ''¥n"
		while m = s.match(/<%([^¥s]*)/)
			ret << "_tt_string << #{m.pre_match.dump}¥n"
			code = m.post_match.match(/(.*?)%>/)
			s = code.post_match
			code = code[1]
			case m[1]
			when "h"
				ret << "_tt_string << MiniERB::Util.escape(#{code})¥n"
			when "="
				ret << "_tt_string << (#{code}).to_s¥n"
			else
				ret << "#{code}¥n"
			end
		end
		ret << "_tt_string << #{s.dump}"
		ret
	end

	def result(binding=TOPLEVEL_BINDING)
		eval(@src, binding)
	end
end

sample

require "time"

entries = [
	{
		:title => "hoge<<<&>>>>>>>>>>",
		:body => "a<a href='aa'>a</a>a",
		:date => Time.now
	},
	{
		:title => "fuaaaaa<<<",
		:body => "hehe, Nice boat.",
		:date => Time.now
	},
]

puts MiniERB.new(DATA.read).result(binding)

__END__
<% entries.each do |entry| %>
<div class="entry">
	<h2><%h entry[:title] %></h2>
	<div class="body"><%= entry[:body] %></div>
	<div class="info">Time: <%= entry[:date].xmlschema %></div>
</div>
<% end %>

%h で htmlescape 済みの。 = で生のデータうめこみ。

できるだけ式展開するバージョン (早くなると思われる) 同じく 40 行

class MiniERBExpressionExpantion
	module Util
		ESCAPES = { "&" => "&amp;", "<" => "&lt;" , ">" => "&gt;"}

		def escape(str)
			str.to_s.gsub(/[#{ESCAPES.keys.join}]/o) {|i| ESCAPES[i] }
		end
		module_function :escape
	end

	attr_reader :src

	def initialize(template)
		@src = compile(template)
	end

	def compile(s)
		ret = "_tt_string = ¥""
		while m = s.match(/<%([^¥s]*)/)
			ret << "¥#{#{m.pre_match.dump}}"
			code = m.post_match.match(/(.*?)%>/)
			s = code.post_match
			code = code[1]
			case m[1]
			when "h"
				ret << #{MiniERB::Util.escape(#{code})}"
			when "="
				ret << #{(#{code}).to_s}"
			else
				ret << "¥"¥n#{code}¥n _tt_string << ¥""
			end
		end
		ret << "¥" << #{s.dump}"
		ret
	end

	def result(binding=TOPLEVEL_BINDING)
		eval(@src, binding)
	end
end


ベンチマーク

require "time"
data = DATA.read
entries = [
	{
		:title => "hoge<<<&>>>>>>>>>>",
		:body => "a<a href='aa'>a</a>a",
		:date => Time.now
	},
	{
		:title => "fuaaaaa<<<",
		:body => "hehe, Nice boat.",
		:date => Time.now
	},
]

require "benchmark"
Benchmark.bmbm do |x|
	x.report("concat") { 100000.times {
		MiniERB.new(data).result(binding)
	} }
	x.report("expexp") { 100000.times {
		MiniERBExpressionExpantion.new(data).result(binding)
	} }
end

__END__
<% entries.each do |entry| %>
<div class="entry">
	<h2><%h entry[:title] %></h2>
	<div class="body"><%= entry[:body] %></div>
	<div class="info">Time: <%= entry[:date].xmlschema %></div>
</div>
<% end %>

Mac 1.8.2 / 1.83GHz CoreDuo

ruby 1.8.2 (2004-12-25) [universal-darwin8.0]
Rehearsal ------------------------------------------
concat  35.230000   0.240000  35.470000 ( 36.472992)
expexp  33.690000   0.220000  33.910000 ( 35.208808)
-------------------------------- total: 69.380000sec

             user     system      total        real
concat  35.220000   0.210000  35.430000 ( 36.348813)
expexp  33.570000   0.180000  33.750000 ( 34.598484)

ubuntu LTS 1.8.4 / Intel(R) Celeron(R) CPU 2.66GHz

ruby 1.8.4 (2005-12-24) [i486-linux]
Rehearsal ------------------------------------------
concat  37.250000   1.040000  38.290000 ( 38.371623)
expexp  36.270000   1.000000  37.270000 ( 42.917439)
-------------------------------- total: 75.560000sec

             user     system      total        real
concat  37.110000   0.980000  38.090000 ( 38.109001)
expexp  35.650000   1.030000  36.680000 ( 36.799591)

ubuntu LTS 1.9.0

ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
Rehearsal ------------------------------------------
concat  37.910000   0.060000  37.970000 ( 38.100921)
expexp  35.910000   0.010000  35.920000 ( 35.944483)
-------------------------------- total: 73.890000sec

             user     system      total        real
concat  37.870000   0.010000  37.880000 ( 37.909874)
expexp  36.040000   0.020000  36.060000 ( 37.622068)

>

いちおうはやくなったようだ。誤差の範囲すぎる。

(あたまわるくて意味ないベンチした)

シュワルツ変換

http://en.wikipedia.org/wiki/Schwartzian_transform

覚えた! map sort map みたいなのをいうらしい。やってたけど名前を知らなかったw

Ruby だと sort_by になるからやらなくていい。

スペルが全く覚えられない感じだけど、幼女が「しゅわるちゅへんかんー」とか言ったら萌えるんじゃないか、と一瞬思った。「だけど」の前と繋がってないな。