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月 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 (タブばっか使ってるので) を意識した感じ

]

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

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

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


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

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月 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 のパッチクライアントを思い出した。


>