timeoutが遅いのはtimeout用スレッド生成が遅いんだろうから、timeout thread 用スレッドを一個ずっと走らせておけば、という話につながったりするんだろうか。そんなに難しそうでも無さそうだしな。
研究は趣味か,と聞かれると,圧倒的に趣味なんだろうなぁ.
MapReduceの話を聞いてきたけど,モデルは非常に単純というか.うまくいくのは当たり前.
で,その当たり前を数千,数万のクラスタ上で実用に耐え得るものに仕上げたのがすばらしい.
が居て,はじめてここまできちんとしたものが出来たんだろうね.
でも,やっぱり適用できる問題は(全ての問題数と比べると)あまり多くは無いそうで.当たり前かな.
ちなみに,keyという存在がよくわからなかったのだよな.分散のために必要なのね.
久しぶりにSICP.
しかし,目的は内職.
def main *args
yield
end
def void *args
end
def int *args
end
####
#include <stdin.h>
int main(){
printf("Hello World!");
}
久々にgmailに入ったら招待数が100通と出た.そんなに知り合いいねー.
10000.times{
Thread.new{a=1}.join
}
とかで,実行速度が一桁違う.うーむ.
あー,スレッドの生成はむちゃくちゃ遅くなってるなー.当たり前だけど.
#
#
#
class AutoLoggedFile < File
def self.open *args
file = self.new(*args)
if block_given?
begin
r = yield file
ensure
file.close
end
r
else
file
end
end
def initialize repository, path, *args
@alf_backbone = check_backbone(repository, path)
super(@alf_backbone.open_path, *args)
end
def close
super
@alf_backbone.commit
end
ALFBackbone_Systems = []
def check_backbone repository, path
ALFBackbone_Systems.each{|klass|
if klass.supported?(repository, path)
return klass.new(repository, path)
end
}
raise "Unsupported repository: #{repository}"
end
####################################
class ALFBackbone
def self.supported? repository, path
raise "Implement it"
end
def initialize repository, path
@repository = repository
@path = path
end
def open_path
raise "Overload it"
end
def commit
raise "Overload it"
end
def self.inherited klass
ALFBackbone_Systems << klass
end
end
####################################
class ALFBSvnCommand < ALFBackbone
def self.supported? repository, path
svncd = File.join(repository, '.svn')
FileTest.directory?(svncd)
end
def initialize repository, path
super
@path = File.join(repository, path)
end
def open_path
@path
end
def add
if FileTest.directory?(File.join(File.basedir(@path), '.svn'))
path = @path
else
path = File.basedir(@path)
while !FileTest.directory?(File.join(File.basedir(path), '.svn'))
path = File.basedir(@path)
end
end
svn_command("add #{@path}")
end
def changed?
case svn_command("stat #{@path}")[0]
when ??
add
when ?M
true
else
false
end
end
def commit
if changed?
svn_command("ci #{@path} -m 'commited by AutoLoggedFile'")
end
end
def svn_command args
r = `svn #{args}`
if $? != 0
raise "Subversion command exit with error (#{$?})"
end
r
end
end
end
少し整理してみた.
10.times{
AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
f.puts Time.now.to_s
}
}
これで10秒(on cygwin)かかるというのは,使い物にならないか....
でも,まぁこんなもん,と思えばこんなもんかなぁ,という気はする.気だけ.
あんまり需要はないのかなぁ.
なんでこんなのを考えているかと言うと,前も書いたような気がするが,この日記,バージョン管理していないので,管理したいのだ.
うは、新しいT4は軽量バッテリー付ですか。すげえ欲しい。
軽量バッテリーだけ買っちゃおうかな。
Intel のプロセッサの違いがさっぱりわからないので調べていたら、比較表があった(http://www.intel.com/products/processor_number/proc_info_table.pdf)。大変わかりやすい。しかし、Dual Core、EMT64、HyperThreading、VT に対応しているのは Pentium XE 955 だけか...。どうやって手に入れよう。
まぁ、こんなん揃えたい人なんて居ないんだろうなあ。
あれ、Xeonが書いてないぞ?
Pentium XE 955 は Dell で普通に買えるか。
DDRでダイエット、という話を見て、ちょっと買おうかと思ってしまった。それよりも剣神ドラゴンクエストかなぁ、と思ってネットで探してみたら、ほとんど売り切れ。ガーン。
誰か余ってませんか。
びびるびるびるびびるびー
というネタは、どこかで使えるんだろうか。
げんしけん7巻.なんか凄い展開だな.こみぱ?
やはりなんか熱ぽい.
なんというか,物欲大爆発って感じ.
x86用仮想化技術はもてはやされているが,では他のプロセッサに対してはどうなんだろう.
Xenはx86用って書いてあるな.
たとえばMIPSで必要なのは,
(a) user ----------- (b) kernel ----------- (c) VMM (Virtual Machine Monitor)
があったとき,例外で (a) -> (c) へ飛ぶ,(b) でのCP0関連命令をフック,(b)でのI/Oアクセスをフック,というところか?
フックしなくて大丈夫か? きちんと CP0のコンテキストが保存できていれば.うーん,どうなんだろうな.
TLBの差し替えとかをフック出来ればメモリはなんとかなりそうかな.なんとかするには命令書き換えしか思いつかないけど(CPUに手を入れなければ).
しかし,あんまり,需要無さそうだしなぁ.
サン、仮想化技術をSparcサーバに搭載へ を見て,つらつら考えてみた.
sparcだと,何をどうするんだろう.CPUに特殊なfeatureは要らないんだろうか.
寝まくり。
昨日は SHININGだった。興味深かったような興味深くなかったような。
全然、何も研究について、それ以外についても聞けなかったなあ。吸収する能力の欠如。欝だ。今後これじゃまずいだろう。
徹夜明けで途中何度も寝てしまったのも、失礼な話だなぁ。
COINSで x86_64 の TMDが作りたくなった。
で、家に初めてFAXが来た。ブラザー|薄型デジタル複合機 MyMio(マイミーオ)|MFC-620CLN。
ADFが素敵。しかし、相手が居ないんでFAXはまだ試していない。
ところで、平成17年度上期未踏ソフトウェア創造事業 千葉PM 成果報告会が告知されました。
こんなに大事にしてもいいんだろうか...。SDCで告知するから、もしかしたらすぐ売り切れるかも、だって。どうみても未踏発表じゃなくて、ひがさん、まつもとさん、千葉先生の講演目当てです。ありがとうございました。
なにやら、数名分優先枠をもらっているようので、興味のある方は声をかけてください。2/6 に枠が解除、ということです。
Rubyな人はほとんど居ないんだろうなあ...。
風邪.喉が痛いのが治ったと思ったら,気持ち悪くなってきた.
大変面白いサイトで,時間がさくさくと過ぎていく....
あかん,猫裁判読みきってしまった orz
母親と,「いただきます」についての話をしていたら,じゃぁ「ごちそうさま」はどうなんだろうね,という話になった.
どうなんだろうね.
http://www.ipab.org/Presentation/sem05/05-03-tkyo.pdf
不勉強ながら,計算加速器という言葉を初めて知る.なるほどー.
p53 なんで,システムソフトウェアをNAREGIがやるの? GRID技術が役に立つ?(たたないとは思わないが...) 略称だけを見ると,大型計算機のために何か作っても間違いはないとは思うが.
それとも,京速計算機自体について誤解してる?
p58.
2. 世界的にベクトルは衰退(ハイエンドでは)。
ローエンドでベクトル使ってるって...SIMD?
p62 の「上位の資源」とはなんだろう? ハイエンドマシンを政府の責任に?
最後の,応用から,と言う言葉は至言なんだが,今まで一度も応用を元に何かを作ったことが無い orz どーやるもんなんだろうな.自分自身が応用する側であれば,いいんだろうけど.
色々大変なので,るびまをさぼろうと思ったら次回予告にエントリーしちゃってるじゃん.うーんどうしよう.
んー、an か?
文句なく an か。
今日はSHININGだから早く寝ないと7時に起きれないー,と思っていても眠れない4:30.
で,なんかスゲーことを思いついたような気がして,ちょっと実装してみようかな,という気になっている.主観ではスゲーんだけど,簡単にできそうなので,すでに誰かがやっていそうではある.
いや,単純な話なんだけどさ,Ruby上だけで考えれば,簡単にファイルシステムをでっちあげられるんだよね.open-uriがやってるような.で,それはもっと拡張できるなぁ,と思ったという話.
たとえば,Ruby レベルに限れば jail みたいなのはスグできたりする?
というわけで,
class AutoLoggedFile < File
def self.open *args
file = self.new(*args)
if block_given?
begin
r = yield file
ensure
file.close
end
r
else
file
end
end
def initialize wc, path, *args
@wc = wc
check_working_copy
@path = encode_to_wc_path(path)
super(@path, *args)
end
def close
super
al_commit
end
####################################
def encode_to_wc_path path
File.join(@wc, path.tr('/', '_'))
end
def check_working_copy
`svn stat -q #{@wc}`
if $? != 0
raise "#{@wc} is not repository"
end
end
def al_add
`svn add #{@path}`
end
def al_commit
al_add if `svn info #{@path}` =~ /Not a versioned resource/
`svn ci #{@path} -m 'commited by AutoLoggedFile'`
end
end
こんなのを作ってみた.open するファイルが全部勝手に svn の working directory でバージョン管理される,という.
AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
f.puts 'foo'
}
AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
f.puts 'foo'
f.puts 'bar'
}
AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
f.puts 'foo'
f.puts 'bar'
f.puts 'baz'
}
こんな感じで,3回書き込みを行うと,
$ svn annotate a.txt
4 ko1 foo
5 ko1 bar
6 ko1 baz
こんなふうに,ちゃんとログ付けされていることがわかる.
いや,きっともうあるんだろうけど.これを使えば簡単にウェブアプリケーションが作るファイルがバージョン管理下におけるな,と.
で,問題はすげー遅いってことなんだな.svn 起動しまくり.そこでRubyでSubversion直呼びデスヨ! と思ったんだけど,なんだかわからんぽんなんで保留.須藤さん,わかりやすいドキュメント書いて.
open-uri のように,openを差し替える.al// で始まってるファイル名だったら,自動バージョン管理,ということにしておく.
alias orig_open open
def open path, *args, &bl
if path =~ /al\/\/(.+)/
path = $1
AutoLoggedFile.open($al_workdir, path, *args, &bl)
else
open path, *args, &bl
end
end
$al_workdir = './workdir'
open('al//b.txt', 'w'){|f|
f.puts '111'
}
open('al//b.txt', 'a'){|f|
f.puts '222'
}
open('al//b.txt', 'a'){|f|
f.puts '333'
}
結果:
$ svn annotate b.txt
7 ko1 111
8 ko1 222
9 ko1 333
openのファイルの指定方法がちょっとアレかな.
はて,windows用のsubversionだけど,workingcopy が workdir だったとき,svn ci workdir/foo とやっても現在のカレントディレクトリは working copy じゃない,というエラーが出る.はて,どうしたもんか.
他のサブコマンドは動くのになあ.add とか.
そして,もうひとつ不思議なのが,cygwinで実行すると動く,という.
Linuxでも動くようだなあ.まぁ,それならいっか?
というわけで,改訂.
class AutoLoggedFile < File
def self.open *args
file = self.new(*args)
if block_given?
begin
r = yield file
ensure
file.close
end
r
else
file
end
end
DefaultWorkingCopyPattern = nil
DefaultWorkingCopy = nil
def self.default_working_copy=(path)
path = File.expand_path(path)
self.instance_eval{
remove_const :DefaultWorkingCopyPattern
remove_const :DefaultWorkingCopy
}
self.const_set(:DefaultWorkingCopyPattern, /#{path}\/(.+)/)
self.const_set(:DefaultWorkingCopy, path)
end
#
def initialize wc, path, *args
@wc = wc
check_working_copy
@path = encode_to_wc_path(path)
super(@path, *args)
end
def close
super
al_commit
end
####################################
def encode_to_wc_path path
File.join(@wc, path.tr('/', '_'))
end
def check_working_copy
`svn stat -q #{@wc}`
if $? != 0
raise "#{@wc} is not a workingcopy"
end
end
def al_add
`svn add #{@path}`
end
def al_commit
al_add if `svn info #{@path}` =~ /Not a versioned resource/
cmd = "svn ci #{@path} -m 'commited by AutoLoggedFile'"
p cmd
# `#{cmd}`
system("svn ci workdir\\b.txt -m 'commited by AutoLoggedFile'")
end
end
require 'uri'
alias orig_open open
def open path, *args, &bl
path = File.expand_path(path)
if path =~ AutoLoggedFile::DefaultWorkingCopyPattern
path = $1
AutoLoggedFile.open(AutoLoggedFile::DefaultWorkingCopy, path, *args, &bl)
else
orig_open path, *args, &bl
end
end
使い方:
AutoLoggedFile.default_working_copy = 'workdir'
open('workdir/b.txt', 'w'){|f|
f.puts Time.now
}
open('workdir/b.txt', 'a'){|f|
f.puts Time.now
}
open('workdir/b.txt', 'a'){|f|
f.puts Time.now
}
欠点は著しく削除,移動,コピーなどが制限されることなんだろうなぁ.FileUtilsを全部変えるのは面倒だしな.
プレステ2かも>ローエンドでベクトル使ってるって...SIMD?
skype のビデオチャットって、
という疑問があるんですが、どうなんでしょうか。
そもそも、まだビデオ自体試してないんだが。
ちょっと話題になっている「いただきます」の話だけど、前も話題にならなかったっけ?
で、そのときにも書いたかもしれないけど書かなかったかもしれないので書いてみる。
高校のころ、ある人と一緒にCD屋に行って買い物をしたとき、その人は店員さんに「ありがとう」とか言っていたような気がする。で、私は金払ってるんだから当然だし、言う必要ないんでは? と聞いた。そしたら、そのある人は困ったような顔をして、でも、言われたほうが嬉しいし、みたいなことを言っていた様な気がする。それ以来、なるべく声に出してお礼を言うようにしている。
考えてみると、俺は今その人のそのときの年齢なんだな。比べてみると、俺は一体何やってんだろう、って思う。
その人は大切な恩人なんだが、何も恩返しが出来ないままだ。また一度一緒に酒を飲みたい。切に、切に、そう思う。
感謝は祈りなんだよねぇ。
少年少女の物語が、ハッピーエンドで、終わった。
この人は何が書きたかったのかなぁ。
あぁ,もう駄目駄目.駄目すぎる.自分駄目すぎ.ごめんなさいごめんなさいごめんなさい orz
まず,戦略を間違えた.圧倒的に間違えた.TeXは駄目って言われても,見積もりのために絶対に最初はTeXで書くべきだった.自分にそんな能力が無いってさっさとわからなかったのが,駄目すぎる.
うーん,最近 comment spam が増えてきたな.
とてもうれしい知らせが.
おー.許してもらえた.どうもありがとうございます.今度から買います(何を).
電車で iPod nanoで何か聞こうと思ったら、曲が何も入ってない!
一体何があったんだ。
リセットしたら、なんか見えるようになった。謎杉。
家族のPCが起動後数分で動かなくなっているらしい.以前HDDを交換してからの症状で,メモリを交換しても同じだった.これはマザボかなぁ,ということで,私の古いマシンと交換.ミドルタワーだから,リビングに置きたくなかったんだが.
今度キューブ形のを買うか.
で,HDDを入れ替えただけだと,マザボが違うので起動時にブルースクリーンが出るwin2k.さて,どう対処するんだっけな.
生まれて初めてVBプログラムを書いたような気がする.
なんでこんなことになったかというと:
pf 変更点:PortForwarderDlg.cpp を以下のように変更.
LRESULT CPortForwarderDlg::OnThreadEnd(WPARAM info, LPARAM lParam)
{
if (GetStatus() == PF_STAT_CONNECTED) {
/* server must disconnect cleanly (not fatally).
* could this happen?
*/
OnPfShow();
if (MessageBox("Connection closed by server. Reconnect?", APP_NAME,
MB_YESNO | MB_ICONEXCLAMATION) == IDNO) {
if (sshThread) {
delete sshThread;
sshThread = NULL;
}
EndDialog(0);
}
else {
exit(100);
}
}
else if (GetStatus() == PF_STAT_DISCONNECTING) {
/* client requested to disconnect. */
SetStatus(PF_STAT_NOT_CONNECTED);
GetDlgItem(IDC_PF_STATUSSTATIC)->SetWindowText(PF_STRING_NOT_CONNECTED);
}
else {
/* never happens */
}
return 0;
}
vbs:
Dim WSHShell
Set WSHShell = WScript.CreateObject("WScript.Shell")
Do
err = WSHShell.Run("PortForwarder.exe atdot.net", 1, True)
If err <> 100 Then Exit Do
Loop
JS にしなかったのは,なんとなく.
まぁ,こんなもんでしょう.なんとなく,cygwin の ssh と shellscript だけで全然問題ないような気がするが,細かいことは気にしない方向で.
cygwin/shellscriptでDOS窓を起動しないでなんかさせるのは簡単なんだろうか.
eさんがmixiで過去を見て未来の趨勢(趨のほう)を予測、みたいな内容を書いているのを見て「な、なんだって(略」という言葉の語源を知らない世代がくるのだよなぁと思った。50年後に2chに(2chはいつまで続くんだろう)「な、なんだってー(略」と書いているんだろうか。
さすがに雪の中RHG読書会に来ている人は少ない.10人以下,というのは久々だ.
かっこいいならCool Rubyかぁ。となると、その次は Warm Rubyだなぁ、とか思った最近。
さて、珍しく自宅でプリンタが必要になったんだがインクが無いらしい。ちょうど複合機を買おうと思っていたので、今からインクを買うのはアレだ。 そして、学校はちょうどセンター試験で入れない。なんともはや。
さて、どうしよう。
デブサミ,OSSコミュニティもいくつか参加されてるんですね.Rubyの会もなんかやったほうがよかったのかしらん.というか,こういうのってどうやって話が進むんだろう.
『Warm Ruby』邦題>『うわぁ・・・Ruby の中・・・すごくあたたかいナリ・・・』
なんかよくわかんないけど嫌だなぁ。
今日はOKでしょ?17時まで。
おお,17時までOKだったのですか.
日本Rubyの会、デブサミに参加してますよ。リストに入ってました
あり? うわ、ほんとだ。[ruby:975] デブサミ2005。すっかりスルーしてたんですが、何するんだろ。
http://d.hatena.ne.jp/seiunsky/20060118/1137606585
MSDNやSunが書いているjavadocなどと比較するのはなぁ、と一瞬思ったけど、利用者は比較して当然なのかも(というか、比較しない理由は無い)。全部ボランティアベースだとか、そんなのは(利用者的には)まったく関係ないんだから。
そして、そういう比較をすると、「Rubyのドキュメントダメダメ」と思うのは当然なのかも。
perlはよく知らないんですが、そんなにドキュメント充実しているんですか。
さて、どうするべきなのかね。自分は基本部分のドキュメントが不足しているとは思ってないんだけど。なんか、イメージ戦略か何かが必要なのかも。逆に「ボランティアなのにこんなに充実していて凄い!」みたいなことを思わせる何か。
ちなみに、不足をマイナスにしたり、割り算の優先順位とかどうなんだろう、とどうでもいいことを思ってみる。
技術情報、特に雑誌で金を取るのは、難しいなあ(C magazine休刊を見て)。 これも、どうあるべきなんですかねぇ。
るびまも、どうしたもんなんだか。
リファレンスマニュアルをオサレな色に変えて字を小さくすればいいんじゃないかな? 字を小さくするのは冗談として、見映えはあんまり良くないですね。
充実度はともかく、見え方というか操作性に関しては、MSDNのサイトは最悪だと思ってるんですが、それは私だけなのかしら
どうも初めまして。リンクありがとうございますー。 ちょっと急ぎ足で書いた文章なので言葉足らずなところもあったのですが、カンタンに言ってしまえば「かんたん・わかりやすい」と言ったキャッチコピーと情報を集める時のギャップがあるなぁ、と。 あと、Perlの公式のドキュメントって知らないですけど(ぇ)、歴史がある分Webで調べるのは結構できますよね。まー、そんなとこの愚痴でした。 MSDNに関しては操作性はロクでもないですけど(Firefoxだと文字化けするし!)、VSのF1キー(ヘルプ)と連動してますからねぇ。あの変なブラウザに我慢すれば大体なんとかなるような気がします。 ……っと、ちょっと長くなってしまってすいません。それでは。 http://d.hatena.ne.jp/seiunsky/
わわ、改行が……。みにくくてすいません_| ̄|○
MSDNが特別最悪だとは思わないんですけど、俺の感覚が変なのかな。今のリファレンスマニュアルのデザインもかっこ悪いと思っていない俺は、やっぱり感覚が変なのかもしれない(というわけで、カッコイイRubyは無理ぽ)。
「Rubyは簡単」というのは、「情報もそろってて簡単、ばっちり」ということを連想させるから、現在のドキュメントを探し出すとっつきにくさのギャップが逆に目立つ、ということなんでしょうか。興味深いですね。となると、そもそもRubyは使いづらいと吹聴しておけばそもそも問題ないのか(違)。いや、そうしておいたほうが、隠し技になってくれてうれしいのかも。一部には。Rubyの普及を推進したい人たちの団体はできないものかな。日本Rubyの会はそういうものではないし。それとも、日本Rubyの会の中にも、普及を目的とした何かを作る必要があるのかも。
Perlの情報ってどうやって調べるんでしょうか。perldoc? ri と比較してどうなんだろ。日本語でまとまった情報はどうやって調べるんだろう。私がPerlが苦手な理由はドキュメントの調べ方がわからなかったことなんだけど。
Pythonは充実してると思う。でも、関数ばかりなのがどうにも苦手。
高橋会長と前に少しお話ししたのですが、 標準ライブラリのマニュアルが一箇所 (= ruby-lang) にまとまっていない (-> refe で出てこない) のが問題の一つではないかと思っています。
例えば、外部サイトにマニュアルがあって、ruby-lang のページにはそのサイトへのリンクだけがあるようなケースです。 例: http://www.ruby-lang.org/ja/man/?cmd=view;name=rss
とりあえず、全項目が refe で出るようにするところまでは持っていきたいと思っているのですが……
うーん、refeはどれくらい使われているんだろう。
このエントリを読んで考えて,いつぞやの「RAAじゃダメなんですか」という質問への答が出たので,まとめてみました。 でも,考えてみたら元の記事は言語の入門のときの壁のような・・・ こっちはモジュール(特にThird Party Module)のドキュメントについての話です。 まあ,合わせていつぞやの報復とばかりにPerlの良いところをアピールして反撃! を兼ねて,「Perl/CPANユーザから見たRAAがイマイチに思える点の指摘」ということで聞き流してください。
大雑把に言うと,二つの点でモジュールのドキュメントを探しにくい・読みにくいと感じました。 まずは上で指摘のある通り,モジュールのドキュメントが集まっていないこと。 PerlはCPANに集まっている→それを前提としたツールができて使いやすくなる→魅力的なツールがあるからCPANにアップロードしたくなるという好循環が出来ているのだと思います。Rubyはこれが逆に回っているのでは?
この辺の話を一つ目のエントリに書いてみました。ちょっとタイトルは煽ってますけど。 CPANにはツールが色々あるんですよ,という話です。 Perl/CPANの良いところ〜なぜCPANにはモジュールが集まるのか
二つ目はモジュールのドキュメントの文書構造です。 各モジュールのドキュメントの質・量は作者さん次第というところも多いので単純に比較するものでも無いと思うのですが,今回RAAからいくつかのモジュールのドキュメントを見て,どうもPerlのモジュールの方が読みやすいように思いました。
なんでだろうと考えてみたところ,Perlの場合たいていのモジュールのドキュメントはUNIX manを踏襲した文書構造で書かれていて(確かどこかでこれを推奨していたはずです),欲しい情報を最初に提示してくれているのに対し,Rubyのモジュールは順序がモジュールごとにばらばらで,欲しい情報がなかなか出てこないと思いました。
この辺を二つ目のエントリに書いてみました。 CPANモジュールのドキュメントの良いところ〜読みやすいドキュメント 概略を言うと,Perlのモジュールのドキュメントは「このモジュールではこんなことができるよ」というのを何よりも先に提示しているのです。文章ではなく,SYNOPSISというコードで。そしてSYNOPSISはその後に続くリファレンスをどこから読み始めれば良いかという情報も提供しています。こうして,モジュールのユーザの興味を最初から惹きつける(あるいは「あ,違う」とさくっとあきらめさせる)文書構造になっています。
このエントリの最後で「この順番が逆だったら?」と書いていますが,これは実はruby-dbiのドキュメントがほぼその順で非常に読みにくいと感じたからです。他にも似たようなパターンがあったように思います。
「このモジュールで何ができるの?」と思ってドキュメントを見たユーザが最初に目にするのがライセンスで,次に何人もの(ユーザにとっては初めて目にする・あるいは興味が無かったりする)名前が続き,その後も色々とあったあげく,最後の最後でExampleが出てくる,しかも実際のドキュメントは別のページだよ,と出てくる訳です。 そこまで辛抱強く読み進めるユーザがどれだけいるでしょうか?
PerlではCPAN SearchかKobesearchなりという,「共通のデザイン・同じ場所」で,(たいていのモジュールで)NAME VERSION SYNOPSIS DESCRIPTION (詳細) SEE ALSO AUTHORS LISENCEという「共通の文書構造」で読めるので,100個のモジュールの中から自分の欲しいモジュールを探すのも容易であるのに対し,Rubyではあちこちページをたどってどうにかドキュメントを見つけ・・・10個くらいで飽きてきます。
この2点がいつぞやの「RAAじゃダメ」の答えです。>ささだくん ちなみに「Perlの情報の調べ方」も書こうとしていたのですけど,いつの間にか「CPANモジュールネタの仕入れ方」になっていたので割愛させていただきます。 Ruby, Perlともども今後とも発展していくことを祈って。
・・・文体が変だね。>自分 さすがにここでこの手の話題なので。
某fate、OPダメダメ。妥協の産物。
closureって、環境をcloseするもの、でいいと思うんだけど、足りないのかしらん。定義、無いのかなぁ。
「Effective Ruby」という書籍はどうだろうなぁ、と思う今日この頃。誰か書かないかな。
「Effective」よりも、"たのしい","おいしい"(レシピブック)に続くシリーズ(?)として、"かっこいいRuby"がいいね、という話を以前babieさんとしてました。
表紙はかっこよくしてね>「Effective Ruby」。「カコイイRuby」って呼ぶから。
http://en.wikipedia.org/wiki/Closure_%28computer_science%29
ああ,もう半分過ぎてるよ....
むぅ,test/unit が動かなくなってる orz
プロシンの感想を書いていなかった.ので書いておこう.
■1/9 成人式
前日入り.会場設営など.夜の10時までかかった.夕飯前には終わらせたいものである.
■1/10 一日目
前日の疲れとか,バイトの仕事とかで,なかなか発表が聞けなかった.悲しい.
□オブジェクトの局所的位置関係を利用したトポロジー推定システムの開発
さっぱり聞けなかった.まぁ,聞かなかった,ともいえる.
□アラビヤ語形態素解析エンジンの開発と、学習者向け辞書システムへの応用
これもあんまり聞けなかったけど,プレゼンうまかったなぁ.
□俺デスク:ユーザ操作履歴に基づく情報想起支援ツール
よくわかんなかったけど,評価がとても難しそうだ.
□CD/DVDから起動するLinuxの起動高速化
阿部君頑張ってるねえ.
この話は,KNOPPIXとか,起動CDに限らない話だと思うんだけれど(CDなど遅いメディアへのアクセス高速化が可能になるんじゃないかと思う),その辺はどうなんだろう.あと,これを作るためのセットって公開してくれるんだろうか.
□HTTPプロトコルを用いる広域ストレージとそれを用いて起動するLinux
これは何回か聞いた話だったのでだいたいわかった.P2Pまでいったとき,どうなるんだか興味深い.
□災害時情報共有インタフェースおよびSDGミドルウエアの開発
災害情報,という話と,マウスを複数同時利用できる,という話が混ざって残念な感じに.どちらかに統一して話したほうがよかったんじゃないかと思うんだけれど.
災害情報の取り扱いについては,評価大変だろうけど,もうちょっとほしかった.
後ほど,竹内先生から,あれは他のプロジェクトと組み合わせると凄いんだ,と教えてもらった.
□ポスターセッション
ウダー大人気だったね.やっぱ音は強い.
他のポスターも人だかりで,なかなか話が聞けなかった.
□宴会
和田先生の話はさっぱりわからんかった.
Simpeiはもう解けたんだっけ.
■1/11 二日目
□君を感じるインターネット -超次元コラボレーションブラウザ「Antwave」という提案
あんまりあったかそうじゃないなあ.
□ビスケットランドの実装
さっぱりわからんかった.
Visual languageについての話(利点欠点,オフィスができない理由など)は興味深かったので,宴会で原田さんに少し伺った.
□Kuriltai: 局所性を考慮したID空間を持つDHT
よくわからんかった(知識不足).あまり聞いてなかったというのも.
□セキュアかつ高性能なウェブサーバの設計と実装
評価プログラムが恣意的だとか,なんとか.殺すために一度起きなきゃいけないが,そこではスラッシングは発生しないか?
□バイオ医療を進化させる新原理マイクロナノマシンとバイオロボティクス
大変面白かった.10年後くらいには,学研が「化学ブロック」を出さないだろうか.
最後の「研究者から学者へ」は私も質問しようと思ってたんだけど,さすが竹内先生.いいなぁ,この言葉.
□ロボカップサッカーシミュレーションエージェント開発体験キットOZED
Rubyで作ってあるらしい.るびま寄稿をお願いしてしまった.
□少人数・個人開発者向けオンラインゲームフレームワークの提供〜オンラインゲーム開発「3つの壁」に立ち向かう〜
発表者不在のため流れた.予稿を読んでもようわからんけど,タイトルはキャッチーだから,聞きたかったんだけどな.
□Javaへの限定された継続の実装と、その応用
継続と永続化の話がごちゃごちゃに.
継続のキャプチャはやっとわかったけど,しかし,どうやって継続の復帰を行うのかが未だにわからない.
スレッドの永続化じゃ,なんで駄目なんだっけ.
今読み直してみてもやっぱりわからない.うーむー.わからないのはスタックフレームの復元なんだけど.
□ActiveBasicを取り巻く言語市場の今後
大変斬新な発表だった.
原田さんが「計算機科学の敗北」と言っていたのが印象深い.
□報告等
俺これのためにプロシン行ったんだけどなあ.うけ取れなかったな・・・.
□自由討論
伊知地さんの芸術〜 というのに行った(教育のアレは覗いてみたら怖かったんだもん).
□宴会
和田先生の話,なんとなくわかった.
後藤さんがとても壊れていて面白かった.
すぐに時間が過ぎてしまうな.ああいう場は.
■1/12
□隠伏サーバを実現するTCP認証方式
よくわからなかった(知識不足)
ssh で暗号化でいいじゃん,と思ったけど,そのsshサービス自体を隠したい,という話だったんだろうか.どっかのフィールドになんか情報を押し込むとか何とか.ステガノグラフィみたいなの?
□サンプリング計測におけるトラフィック傾向把握手法の提案
やりたいことがよくわからなかった.
□Preccs:インターネットのための通信プロトコル記述言語
聞くのは2度目.やっぱりFPGAとの連動が面白そうなんだけどなあ.
□PrologによるMakeの実装
Makefileの実装,という言葉が面白かった.
□片付け
片付け.腰が痛かった.
□ビール蔵
多田先生,田中先生はビール蔵へ行くらしかったんだけど,登山電車で目が覚めたら終点で,誰も居なかった.
きょろきょろしてたら,前田さんと水島君が居たのでビール蔵へ連れてってもらった.色々,和田研の話を伺った.
電車に乗って帰ったら8時だった.ロマンスカーに乗ろうと思ってたけど,ぼーっとしてたら小田原過ぎて新宿だった.
プロシンバイトは,発表をなかなか聞けないからもう嫌だなあ.発表なんてどうでもいい,箱根で温泉入ってうまい飯食いたい,というのなら,いいバイトなのかも.
そういえば,若手の会の話は全然していないな...
というか,俺やっぱり今年幹事なんだろうか.幹事資格あるのかな....
こんな切羽詰ってるのはゼミの資料を思い出す・・・.
初学者に実装を教えてしまうと,抽象化してある利点を見逃してしまうのではないか,という危惧があります.たとえば,ポインタはアドレスだ,と教えてしまうと,数字しか思い浮かばなくなったり.
いずれは知るべきことかと思うんだけど,果たしてそれは早いほうがいいのか遅いほうがいいのか.教えられる人にもよるんだと思うけどね.
2ch に貼ってあった>http://grape.astron.s.u-tokyo.ac.jp/pub/people/makino/talks/mitaka20060113.pdf
正直読みづらいけど,内容に爆笑してしまった.
少なくとも,私がマクドナルドやジョナサンで原稿なりハックなりをしているのはそれが理由です>たださん(聞いてないって)
Let's Note T4って,バッテリーが素敵に持つ(ecoモードで8時間)ので,素敵に長居ができる(迷惑な客).
というか、家に機材そろえてるんだから、そこでやれよって感じだ。
orz
http://grape.astron.s.u-tokyo.ac.jp/~makino/articles/future_sc/face.html
HPCって奥が深い、というかキリが無いですね。http://www.ne.jp/asahi/comp/tarusan/ こちらの方の予想も面白い
ネットワークが繋がらない環境だと調べものがしづらくて大変だったりしませんか?(とゆー言い訳を思いついて仕方ない……)
結構なんとかなるもんですよ。というか、後でまとめて調べればそれなりにはかどります。
マクドは最近、Yahoo! BB Mobileが入ってるから誘惑がなぁ……契約しなければいいだけの話だけど。
そのうちIP Unreachableな環境を求めて山に籠るハッカーとか出てくるんだろうか
おわんないよウワーン.
いや,gzは終わらせたんだけどね.
wcコマンド難しい.というか,Rubyの解説難しすぎる.割りきりが必要だと思うんだが,どこで割り切ったもんだか.
black black をボトル(?)で買ってみたけど,800円.割安なんだろうか.内容量がどこにも書いていないのでわからない.
どうにも,人生を決めるようなメールを投げようとして,日本語がわからなくて困る.
というわけで,プロシンから昨日帰ってきた.
http://aspara.asahi.com/club/user/guest/topNaviList.do?type=reading のカレッジライフ ですねぇ.
俺の業績について,一本書くらしかったんだけど,新聞社側が「わけわかんねー」ということで没にされたという.
未踏な新年会.お疲れ様でした.
なぜか川合さん(shiroさんじゃない)が居る.
昨日の話,やりたいことは,
array.c S/1.html ascii.c S/2.html ... ext/Win32API/Win32API.c S/69.html ext/bigdecimal/bigdecimal.c S/70.html ext/bigdecimal/bigdecimal.h S/71.html ext/curses/curses.c S/72.html ext/dbm/dbm.c S/73.html ext/digest/defs.h S/74.html ext/digest/digest.c S/75.html ext/digest/digest.h S/76.html ext/digest/md5/md5.c S/77.html ext/digest/md5/md5.h S/78.html ext/digest/md5/md5init.c S/79.html ...
これをですね,Compiled HTML の ToC ファイルの形式に変換....説明がメンドイ.
まぁ,なんか木構造にしたい,と.
def make_ary tree, fmap, path
tree.sort.inject([]){|a, (n, t)|
a << {
:name => n,
:value => fmap.fetch(path+n),
}
t.empty? ? a : a << make_ary(t, fmap, path+n+'/')
}
end
def read_files
map = read_map('FILEMAP')
fmap = map.inject({}){|h, e| h[e[:name]] = e[:value]; h}
Dir.glob('files/*.html'){|file|
data = File.read(file)
if %r|<title>(.+)</title>|m =~ data
/(.+)\// =~ $1
fmap[$1] = file
end
}
tree = map.map{|e| e[:name]}.inject({}){|tree, path|
path.split('/').inject(tree){|t, n|
t[n] ||= {}
}
tree
}
ary = make_ary(tree, fmap, '')
end
ごちゃごちゃした処理が混じってるけど,やりたかったのはこんな感じ.
一度 hash にすれば,早かったな,と.
昨日のを同じように解くと,
def make_ary tree
tree.sort.inject([]){|a, (n, t)|
a << n
t.empty? ? a : a << make_ary(t)
}
end
def solve map
tree = map.inject({}){|tree, path|
path.split('/').inject(tree){|t, n|
t[n] ||= {}
}
tree
}
ary = make_ary(tree)
end
p solve(['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'])
#=> ["a", "b", "x", ["a", "b", "y", ["a"], "z", ["a"]]]
順序を保存しろ,という話になると,また違うんでしょうけど.
t.empty? ? a : a << make_ary(t) がかっこ悪いと思うんだが,なんか他に方法ないかな.
def make_ary tree
tree.sort.inject([]){|a, (n, t)|
a << n
a << make_ary(t) unless t.empty?
a
}
end
こっちのほうがマシ?
tree は inject 無いほうがわかりやすいかな,ということで,
def make_ary tree
tree.sort.inject([]){|a, (n, t)|
a << n
a << make_ary(t) unless t.empty?
a
}
end
def solve map
tree = {}
map.each{|path|
path.split('/').inject(tree){|t, n|
t[n] ||= {}
}
}
ary = make_ary(tree)
end
p solve(['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'])
# parse GNU global outputs and generate hhp, etc
def make_hhp id, title
<<EOS__
[OPTIONS]
Compiled file=#{id}.chm
Default topic=index.html
Title= #{title}
Language=0x411 日本語
Compatibility=1.1 or later
Contents file=toc
Display compile progress=Yes
Full-text search=Yes
Index file=idx
[FILES]
#{
Dir.glob('**/*.html').join("\n")
}
[INFOTYPES]
EOS__
end
def ary2toc ary
<<EOS__
<UL>
#{
ary.map{|e|
if e.kind_of? Array
ary2toc e
else
<<-EOS
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="#{e[:name]}">
<param name="Local" value="#{e[:value]}">
</OBJECT>
EOS
end
}.join("\n")
}
</UL>
EOS__
end
def read_map file
open(file).map{|line|
line.chomp!
if /(.+)\s(.+)/ =~ line
{:name => $1, :value => $2}
end
}.compact
end
def make_idx
idx = read_map('MAP')
<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="texi2html4hh">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
#{ary2toc idx}
</BODY>
</HTML>
EOS__
end
def make_ary tree, fmap, path
tree.sort.inject([]){|a, (n, t)|
a << {
:name => n,
:value => fmap.fetch(path+n),
}
t.empty? ? a : a << make_ary(t, fmap, path+n+'/')
}
end
def read_files
map = read_map('FILEMAP')
fmap = map.inject({}){|h, e| h[e[:name]] = e[:value]; h}
Dir.glob('files/*.html'){|file|
data = File.read(file)
if %r|<title>(.+)</title>|m =~ data
/(.+)\// =~ $1
fmap[$1] = file
end
}
tree = map.map{|e| e[:name]}.inject({}){|tree, path|
path.split('/').inject(tree){|t, n|
t[n] ||= {}
}
tree
}
ary = make_ary(tree, fmap, '')
end
def make_toc
toc = [
{:name => 'Index', :value => 'index.html'},
{:name => 'Mains', :value => 'mains.html'},
{:name => 'Defines', :value => 'defines.html'},
{:name => 'Files', :value => 'files.html'},
read_files
]
<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="texi2html4hh">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
#{ary2toc toc}
</BODY>
</HTML>
EOS__
end
hhp = make_hhp('ruby-1.9.0-src', 'ruby 1.9.0 (2006-01-06)')
toc = make_toc
idx = make_idx
open('global.hhp', 'w'){|f| f.write hhp}
open('toc', 'w'){|f| f.write toc}
open('idx', 'w'){|f| f.write idx}
んで,やっとましな ruby-1.9.0-src.chm が出来た.
... あぁ,俺は何やってんだ.
GNU global は,対応するフォーマットが少ないので gonzui では出来ないだろうか,と思うのだけれどどうなんだろう.gtags / htags 相当の機能はあるんだろうか?
DB をきちんと見て回れば出来るような気はするが,メンドイかなぁ.
ちなみに,gonzui は scheme をサポートしてくれないだろうか.ん,cvs を見たらありそうな予感.
やっぱり,*.scm が無いとつまんないな.
あぁ,現実逃避に chm を作りまくってしまった.
# parse GNU global outputs and generate hhp, etc
def make_hhp id, title
<<EOS__
[OPTIONS]
Compiled file=#{id}.chm
Default topic=index.html
Title= #{title}
Language=0x411 日本語
Compatibility=1.1 or later
Contents file=toc
Display compile progress=Yes
Full-text search=Yes
Index file=idx
[FILES]
#{
Dir.glob('**/*.html').join("\n")
}
[INFOTYPES]
EOS__
end
def ary2toc ary
<<EOS__
<UL>
#{
ary.map{|e|
if e.kind_of? Array
ary2toc e
else
<<-EOS
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="#{e[:name]}">
<param name="Local" value="#{e[:value]}">
</OBJECT>
EOS
end
}.join("\n")
}
</UL>
EOS__
end
def read_map file
open(file).map{|line|
line.chomp!
if /(.+)\s(.+)/ =~ line
{:name => $1, :value => $2}
end
}.compact
end
def make_idx
idx = read_map('MAP')
<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="texi2html4hh">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
#{ary2toc idx}
</BODY>
</HTML>
EOS__
end
def make_toc
toc = [
{:name => 'Index', :value => 'index.html'},
{:name => 'Mains', :value => 'mains.html'},
{:name => 'Defines', :value => 'defines.html'},
{:name => 'Files', :value => 'files.html'},
read_map('FILEMAP')
]
<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="texi2html4hh">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
#{ary2toc toc}
</BODY>
</HTML>
EOS__
end
hhp = make_hhp('ruby-1.8.4-src', 'Ruby 1.8.4')
toc = make_toc
idx = make_idx
open('global.hhp', 'w'){|f| f.write hhp}
open('toc', 'w'){|f| f.write toc}
open('idx', 'w'){|f| f.write idx}
現実逃避の産物.
ruby-1.8.4-src.chm こんなのが出来た.さて,これ便利なんだろうか.1.9 じゃないから便利じゃなさげ.
a, x/a, x/b, x/y/a, x/y/b, ... みたいなものを,[a, x, [a, b, y, [a, b]]] みたいに変換する簡単な方法は....
とりあえず.
p m = ['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'].map{|f|
f.split('/')
}
def parse ary
h = {}
return nil if ary[0].size == 0
ary.each{|e|
if h[e[0]]
h[e[0]] << e[1..-1]
else
h[e[0]] = [e[1..-1]]
end
}
h.sort.map{|k, v|
[k, parse(v)]
}
end
require 'pp'
pp m = parse(m)
def last ary
m = []
ary.each{|e|
m << e[0]
if e[1]
m << last(e[1])
end
}
m
end
pp m = last(m)
#=>
[["a"], ["x", "a"], ["x", "y", "a"], ["x", "b"], ["x", "z", "a"], ["b"]]
[["a", nil],
["b", nil],
["x", [["a", nil], ["b", nil], ["y", [["a", nil]]], ["z", [["a", nil]]]]]]
["a", "b", "x", ["a", "b", "y", ["a"], "z", ["a"]]]
まぁ,望む答えなんだけど,とてもかっこ悪い気がする.
仕様がよくわからないけど。
(use srfi-1)
(use gauche.collection)
(use util.match)
(define (p input)
((rec (r lis)
(append-map (match-lambda
(((x)) `(,x))
(((x . y) ...) `(,(car x) ,(r y))))
(group-collection lis :key car :test equal?)))
(map (cut string-split <> #\/) (sort input))))
gosh> (p '("a" "x/a" "x/y/a" "x/b" "x/z/a" "b"))
("a" "b" "x" ("a" "b" "y" ("a") "z" ("a")))
class N
def initialize(n= nil) @n, @c= n, {} end
def /(n) @c[n]||= N.new(n) end
def build
return [@n] if @c.empty?
res= @c.values.inject([]){|r,e| r+= e.build }
res= [@n, res] if @n
res
end
end
def trans(src)
t= N.new
src.each{|e| o= t; e.each{|n| o/= n } }
t.build
end
src= ['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'].map{|e| e.split('/') }
p trans(src)
おー。これからはPythonの時代デスネ。
http://slashdot.jp/comments.pl?sid=295416&cid=859977 誰も突っ込んでないけど,後者二つは同じもの.
最近のputtyは便利なもので,smb over ssh が簡単に出来るのね.
sigsafe_syscall(int sys, int argc, void *argv, sigmask) なんてシステムコールがほしい...。
sigsafe: Pattern reference をまた読み返してるんだけど、わかりやすいですね、問題点が。
Windows の handle は便利だよなぁ。
UNIX も、thread ごとに handle を持つようなセマンティックスになってくれれば、いいんだけど。
handle がシグナルでは、どのシステムコールも EINTR で失敗する、シグナルを受けるとhandleはシグナル状態になる、みたいな。シグナル状態の解除は明示的になんかする。
あ、シグナル状態になるのは handle じゃなくて、handle が指すオブジェクト、か。
そういえば、read が終わった後にどうせ CHECKINTS するんだから、結局 read の結果は捨てられるんじゃないだろうか、とか思った(もちろん、sigsafe が問題にしているのはもっと一般的な話だけど)。
なんか、read に関しては select で polling でいいような気がしている人。
write に関しては、まだ理解できていない。
gethostbyname() などでは、運が悪いと(シグナルが入っても)ずーっとブロックするよ、みたいな...。
うーん、これで古畑任三郎終わりか。
Thread#raise をいい加減にサポート。
さて、ブロックしてるやつを再開させるには、どうしたもんかな。POSIX なら pthread_kill() しかないんだけど。
trap をいい加減にサポート。
signal をいい加減にサポート。
学校に来てみる.
そういえば,東京に居ると免許って全然要らないんですよねえ.
RDE を使ってみる.うーむ,よくできてるなぁ.
RDE でデバッガを利用してみようと思ってみたんだけど,rde.so が無いと仰る.その前に,RDE のディレクトリに -I でパスを通してあげなきゃいけなくて,その後で rde/ruby19 にもパスを通してあげたんだけれど(-I じゃなくて,メニューからわかりやすくパスを通す方法があるような気がするんだけど,設定が見つからなかった).
どうも,独自ビルドのRubyでは駄目なのかもしれないね.
で,エディタの左にモジュールとかメソッド名一覧がずらーっと並んでいて,大変便利そうだったので,xyzzyでも同様のことができないかどうか考えてみたんだけれど,うまいこといかなかった.
C のメソッド一覧がtabでジャンプできたらいいな,と思ったんだけど.XTAGS でいいじゃん,といううわさもあるけど,動的に更新してくれないし.
code explorer というのか.いいなぁ.
腰がいてぇ.
#!/usr/bin/env ruby
require 'open-uri'
require 'optparse'
class WC
Version = '0.1'
def self.exec args, default_io
options = {}
OptionParser.new{|opts|
opts.banner = "Usage: #{$0} [options]... [Files]..."
opts.separator ''
opts.on('-c', '--bytes', 'print the byte counts'){
options[:chars] = true
}
opts.on('-m', '--chars', 'print the character counts'){
options[:chars] = true
}
opts.on('-l', '--lines', 'print the newline counts'){
options[:lines] = true
}
opts.on('-L', '--max-line-length', 'print the length of the longest line'){
options[:length] = true
}
opts.on('-w', '--words', 'print the word counts'){
options[:words] = true
}
opts.on_tail('-h', '--help', "Show this message"){
puts opts
exit
}
opts.on_tail('--version', "Show version"){
puts "wc command (sample ruby program) #{WC::Version}"
exit
}
}.parse!(ARGV)
options = {
:lines => true,
:words => true,
:chars => true,
} if options.empty?
wc = WC.new(options)
if args.empty?
puts wc.exec_io(default_io)
else
ARGV.each{|filename|
puts wc.exec_file(filename)
}
puts wc.total if wc.total_files > 1
end
end
######################################################
def initialize opts
@opts = opts
@total_lines = @total_words = @total_chars = 0
@total_files = 0
@total_length = 0
end
attr_reader :total_files
def exec_io(fobj)
output_format nil, *count(fobj)
end
def exec_file(file)
begin
open(file){|fobj|
fobj.binmode
@total_files += 1
output_format file, *count(fobj)
}
rescue Errno::ENOENT => e
"#{$0}: #{file}: No such file or directory"
end
end
def total
output_format("total", @total_lines, @total_words, @total_chars, @total_length)
end
private
def count fobj
lines = words = chars = length = 0
while line = fobj.gets
lines += 1 if /\n$/ =~ line
words += line.strip.split(/\s+/).size
chars += l = line.split(//).size
length = l if length < l
end
@total_lines += lines
@total_words += words
@total_chars += chars
@total_length = length if @total_length < length
return lines, words, chars, length
end
def output_format filename, lines, words, chars, length
result = ''
result << '%8s' % lines if @opts[:lines]
result << '%8s' % words if @opts[:words]
result << '%8s' % chars if @opts[:chars]
result << '%8s' % length if @opts[:length]
result << " #{filename}" if filename
end
end
if $0 == __FILE__
WC.exec(ARGV, ARGF)
end
wc コマンドを作ってみたが,WC クラスの意味が無い,ような気がするが,もしかしたら役に立つこともあるか?
-L オプションを追記してみた。しっかし、wc -L なんて初めて知った。というか、wc にオプションつけたこと無い。
福袋といえば、毎年恒例になっているユニクロの5000円の福袋(服はほぼ、これしか買わない)を元旦に買ったんだけど、ちょっとしょんぼりな感じ。なんか、毎年だんだんしょぼくなってきているような気がする。
コートの下に着るためのジャケットがほしい。
「面倒くさい」…学生、セキュリティホールを残す
あ、これ俺だ。
上記、wc の output_format がかっこ悪い気がしたので、なんとかならないかと考えてみる。
def output_format filename, lines, words, chars, length
[:lines, :words, :chars, :length].map{|sym|
'%8s' % eval(sym.to_s) if @opts[sym]
}.join << (filename ? " #{filename}" : '')
end
eval を使ってるところでなんか負けっぽい。しかも、最期の filename がなんか嫌。なんか無いかね。
class の re-open が嫌だ、という人のために、class 文を終わるとき、その class を freeze する何かをつけてみるのはどうか、と思ったけど、大量のライブラリが動かなくなりそうだな。
前に、erb で eval する対象は、コンパイル済みの命令列 (iseq) は簡単に出力できますよ、と言っていたんだが、なかなか難しいことに気づいた。で、昨年から色々考えてみてるんだけど、なかなかいい方法が思いつかない。
eval に渡す binding によって、iseq が変わる、というのが問題。
def m1
a = 1
binding
end
def m2 arg=0
a = b = 1
end
eval('p a', m1)
eval('p a', m2)
で、iseq は別々のものが生まれる。
このままでは、eval は毎回コンパイルが必要って気がする。うーーーーむ。
eRuby を高速に動かす方法がわからん。なんとかならんかな。
同じ環境(同じ binding)で、という条件つきなら出来るんだが。しかし、binding 、変わる可能性もあるしな。
def a
:a
end
def m
binding
end
eval('p a', b=m)
eval('a = 1', b)
eval('p a', b)
この例でもコンパイル結果は変わる。うーむ。
コンパイル結果を変えなくてよい、ということを検知する仕組みは...。
なんか違うマシンで2回連続 WinXP が落ちた...。なぜ。
午前中だけ、と思ったら夜までかかってしまった。
最初は陳腐だなぁ、と思ったけど、案外面白かった。いや、使い古されたネタかなぁ、と思っていたんだけど。
タイトルを、どう決着つけるのか楽しみ。
しかし、有力者が居ないと救われないってかんじがして、その辺は嫌な感じだった。
あんまり detail を楽しむ作品ではないのかな、とか思った。
あと、これだけ長い文章なんだから、まぁしょうがないかな、とも思ったが、誤字が結構。
open classをclassboxを使って実現、とか夢想してます
仮眠したら年が明けてた。
あけました。今年もよろしくお願いします。
仮眠したら、なにやら新年早々物騒な夢を見た。
うーむ。
Multi-VM を考えていたんだけど、なかなか良いものが思いつかない。グローバルなものを考えるとね...。やっぱり Ruby では無謀だったか?
core は Multi-VM enable にしておいて、拡張ライブラリでは InitMVM_hoge() みたいなものを用意する、というのはどうだろうな。なければ、2個目からは駄目、とか。
ぐろーばる VM ろっくがあるところで、ブロックするような read をするとき、
unlock_gvl();
{
read(...); // block しても何してもオケ
}
lock_gvl();
とすればいいなぁ、と思っていた。
で、これだとそのスレッドがブロックしているところに例外を投げたいとき、つまり Thread#raise を実装しようとすると、ブロッキングしてるスレッドに対して pthread_kill みたいなことをしてあげればいいなー、と思っていた。
unlock_gvl();
{
// (*A)
read(...);
CHECK_INTS();
if(errno = EAGAIN){
// なんか呼ばれてる!
}
}
lock_gvl();
これで、できるなーと思っていたんだが、(*A) の時点で signal を受けるとすると、read() は実行されて、ブロックしてしまう。
この問題は、unlock と read をアトミックに行う方法が無いということに起因するが、さて。Thread#raise は即時性を持つとは限らない、という注意書きだけでいいんかな?
うーむ、外部からのシグナルも同様な問題があるのか。
Windows のハンドルだと、この辺はうまく行きそうなんだがな。はて。なんかうまい手は無いかな。
... これって、もしかして出来ないのか? ありえない?
ちょっと考えてみた。
要するに、read が失敗すればいいので、read にあり得ないパラメータを渡すようにしてみれば解決する。シグナルハンドラの中で、あり得ないパラメータをスレッドに設定して、read するときは‘必ずそれを使うようにする、というのはどうだろう、と思ってみた。回りくどいけどね。たとえば、read なら -1 とか。
yarv_thread_t{
VALUE param;
VALUE illegal_param;
}
--------------------------
// read する人
th->param = fd;
th->illegal_param = -1;
read((int)th()->param, ...)
if(errno == EAGAIN ||
th->param == th->ellegal_param){
...;
}
--------------------------
// signal handler の中の人
th->param = th->illegal_param;
みたいにする。
ちょっと、でもなくめんどいけど、これくらいしか思いつかないなあ。
あぁ、これも穴があるなぁ。やっぱ小手先で考えても駄目だな。
signal handler から longjmp するか。
んー、これで本当に解決する? するような気がするな。
longjmp でいっかー、と思った途端、Windows には pthread_kill 相当が出来ないから駄目ジャン、ということになってしまった。駄目ジャン。
とりあえず pthread 用にざっと作るか。しかし、cygwin では pthread_kill はまともに動かないのは、どうしたもんかな。
rb_thread_wait_fd() なんかを全部からにしようと思ってたんだけど、そこを unlock で囲めば(fd の話は)解決なのか。
うーむ、そうなると、write が block してしまうという問題に対する対処法はないのか...。
新年早々でアレですが、アレにDHHが来てくれそうです :)
Auguri Buon Anno! つーことで今年もよろしくお願いします。朝生も終わったので寝る
read が起動した後に longjmp しちゃったら、read の返値が得られないのでうまくいかない。これを解決してしまう sigsafe というライブラリは面白いが、ポータブルではない。nonblocking にして、select で止まっているときに longjmp という手はある。read と違って select の返値は得られなくてもたいして困らないから。
なるほどたしかに終わった後の話は思いつきませんでした。select で、というのがよいんですかね。
とりあえず sigsafe のドキュメントを眺めてみるのがいいのでは。http://www.slamb.org/projects/sigsafe/api/
免許取っとき。社会人になるとマジ時間ない。私は転職の際1ヶ月空けて取りに行く予定です。
タイムアウトを起こしたい、と思ったその時点で時刻を取得しておいて、そこから起算してタイムアウト時刻を求めるとか。
はい,そうなると思います.