2010-08-01 :-)
_ 朝ッ
0400 起床
_ チャリったー
なるほど曇りじゃねーの
_ Distant World 犬耳家先行予約落選した
さて
_ [Rita]りたのじかん Rita's Hour 15 -wave of sound-
@晴れたら空に豆まいて
Rita はさっぱり馴染みがないのだけど前の前の上司が「 最近は霜月はるかじゃなくて Rita を聞くなどしている 」と言っていたのでせっかくだから申し込んでみたら当選した次第。Rita は関西人だった。
ライブでのアコギいいわあ。いやよく分からないけど。
2010-08-02 :-(
_ 朝ッ
0520 起床
_ id:youichi ( @yo_1 ) が「\茅原実里/」と言っている
私の周囲には訓練された茅原実里ファンが居るんだが私自身は属性持ってない。
_ トミカ40周年記念! 超微細加工アルミ製トミカ「Fairlady Z 432」 : ギズモード・ジャパン
けやきんとか買うといいと思うの
2010-08-03 :-(
_ 朝ッ
0520 起床
_ s/ラ・チャター/ラー・チャター/g
ガンダムシリーズの登場艦船及びその他の兵器一覧 - Wikipedia
クラップ級軽巡洋艦(宇宙巡洋艦)
クラップ、ラー・エルム、ラー・キェム(ラー・ギエム、ラー・ケイム)、ラー・ザイム(ラー・カイム)、ラー・チャター
間違えて覚えていた。
_ リッジレーサー7依存症
リッジレーサー7 を始めてから生活がリッジレーサー7漬けになった。あれは麻薬だ
_ [Template Method][Python][デザインパターン]Python でデザインパターン - Template Method
書き換え[ 20090508#p06 ]
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 8章 Template Method パターン - ヨタの日々(2009-05-08) # http://www.area51.gr.jp/~rin/diary/?date=20090508#p06 class CaffeineBeverage: def prepareRecipe(self): self.boilWater() self.brew() self.pourInCup() self.addCondiments() def brew(self): pass def addCondiments(self): pass def boilWater(self): print "お湯を沸かします" def pourInCup(self): print "カップに注ぎます" class Tea(CaffeineBeverage): def brew(self): print "紅茶を浸します" def addCondiments(self): print "レモンを追加します" class Coffee(CaffeineBeverage): def brew(self): print "フィルタでコーヒーをドリップします" def addCondiments(self): print "砂糖とミルクを追加します" def main(): tea = Tea() coffee = Coffee() print "\n紅茶を作っています..." tea.prepareRecipe() print "\nコーヒーを作っています..." coffee.prepareRecipe() main()
% python templatemethod.py 紅茶を作っています... お湯を沸かします 紅茶を浸します カップに注ぎます レモンを追加します コーヒーを作っています... お湯を沸かします フィルタでコーヒーをドリップします カップに注ぎます 砂糖とミルクを追加します
2010-08-04 :-)
_ 朝ッ
0520 起床
_ ,
@mizchi が居た聖剣伝説 LoM
_ 汝
いまなんじ?
_ [Python][デザインパターン][Iterator]Python でデザインパターン - Iterator
書き換え [ 20090512#p07 ]
Python で Iterator を実装するにはイテレータを使う方法とジェネレータを使う方法があるようだ。ジェネレータならば yield するだけなのでこれは Ruby に近い書き方になるのか。
イテレータ版
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 9章 Iterator パターン - ヨタの日々(2009-05-12) # http://www.area51.gr.jp/~rin/diary/?date=20090512#p07 # イテレータ版 class Menu: def __init__(self, item): self.item = item self.count = len(item) def __iter__(self): return self def next(self): if self.count == 0: raise StopIteration i = len(self.item) - self.count self.count -= 1 return self.item[i] def main(): menuItems = [ "K&Bのパンケーキ朝食", "通常のパンケーキ朝食", "ワッフル"] menu = Menu(menuItems) for n in menu: print n main()
ジェネレータ版
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 9章 Iterator パターン - ヨタの日々(2009-05-12) # http://www.area51.gr.jp/~rin/diary/?date=20090512#p07 # ジェネレータ版 def menu(item): for index in range(len(item)): yield item[index] def main(): menuItems = [ "K&Bのパンケーキ朝食", "通常のパンケーキ朝食", "ワッフル"] for n in menu(menuItems): print n main()
実行結果は両方ともこう
K&Bのパンケーキ朝食 通常のパンケーキ朝食 ワッフル
ref.
2010-08-05 :-)
_ 朝ッ
0520 起床
_ レキジョ
轢女
_ ,
dankogai dankogai という認識になっているのでもはや小飼弾と言われてもピンとこない。
_ ,
s/バッファロー/バッキャロー/g
_ C言語のポインタ
ポインタで挫折すると言っても a->b くらいなら普通に使うよね挫折するとかワケワカンナイヨと思ってた時期がありました。
463 デフォルトの名無しさん [sage] 2010/08/02(月) 23:02:44 ID: Be: (void)foo->super(foo)->hoge(foo->super(foo)); (void)(*(*(*foo).super)(foo)).hoge)((*(*foo).super)(foo)); 一時変数使えよって感じだな
(´Д`;)
_ ,
お。soda さんだ
_ [NetBSD][翻訳]NetBSD Blog - Interview with S.P. Zeidler
S.P. Zeidler へのインタビュー
August 06, 2009 posted by Emile Heitor
Here's the third edition of the "discussions with a NetBSD developer" series. This time, we had the chance to talk to S.P. Zeidler, admin and member of pkgsrc-releng.
第3回「NetBSD 開発者に聞く」。今回は NetBSD admin と pkgsrc-releng のメンバーである S.P. Zeidler に話を聞くことができた。
NetBSDfr: For the readers who don't know you, can you shortly introduce yourself ?
spz: Hi, I'm S.P.Zeidler, call name Petra, also answers to spz or stargazer or Ophiuchi. I'm a member of the NetBSD admins team and of pkgsrc-releng. My archs are amiga, sparc64, amd64 and i386. In other news, I'm Bavarian, mid-fortyish, female, married, 2 cats, no kids.
NetBSDfr: あなたのことを知らない読者のために自己紹介をお願いします。
spz: S.P.Zeidler と言います。Petra と呼んでください。spz か stargazer か Ophiuchi でもいいよ。NetBSD admin チームと pkgsrc-releng チームのメンバーです( 訳: ???? )。持ってるアーキテクチャは amiga, sparc64, amd64 それと i386 です。あと私はバイエルン人で、中年( 訳: ???? )の女性、既婚で 2 匹の猫がいます。子供はいません。
NetBSDfr: Why did you choose to run NetBSD ? How long have you been using it ?
spz: It was the first free Unixoid system that ran on my Amiga, serpens, which has been running NetBSD since February 1995, i.e. since NetBSD 1.0.
NetBSDfr: どうして NetBSD を選んだのですか? NetBSD を使い始めてどれくらいですか?
spz: NetBSD は、手元の Amiga でいい感じに( 訳: serpens ???? )動いた最初の Unix 系 OS なんです。1995 年の NetBSD 1.0 のころから使ってます。
NetBSDfr: How did you become a NetBSD developer ?
spz: When the admins team was looking for more help, I got asked and didn't run away fast enough :-P
NetBSDfr: どうやって NetBSD 開発者になったのですか?
spz: admin チームがもっと人手を求めていたとき捕まり、逃げ出さなかったためです :-P ( 訳: わからん ???? )
NetBSDfr: Do you have an idea of the time you spend working on the NetBSD project daily, weekly, monthly ?
spz: Half an hour daily at least, but depending on things to do; running up 20 hours over the course of a weekend happens quite easily. Both admins and pkgsrc-releng are demand driven, you get requests and you handle them, security updates to servers need to be done as vulnerabilities become known, etc etc. I don't do much programming, if I commit something that's usually a bug fix where I sufficiently hated the bug to unpack the zapper myself instead of just whining about it.
NetBSDfr: NetBSD プロジェクトに携わる時間について何か決めていますか? 毎日? 毎週? 毎月?
spz: いろいろな制約があるけど毎日少なくとも 30 分くらい作業します。週末なら 20 時間以上作業することも楽勝です。admins と pkgsrc-releng チームは両方とも要求が来たときに作業します。vulnerabilities のようにサーバーに必要なセキュリティアップデートなどの作業が要求されたら作業します。プログラミングはあまりできないので、激しく嫌悪するようなバグを解決してフィックスしたらいつも the zapper myself instead of just whining about it してやります。( 訳: ?????? )
NetBSDfr: What is the job of a NetBSD admin ? How many admins are there ? How do you work alltogether ? How do you share the tasks you have to do ?
spz: In the abstract, keeping the servers of The NetBSD Foundation secure, up, and doing useful work. At a closer view, it's plain oldsystem administration with administration of services like eg mail thrown in.
There are currently 5 admins on admins rotation, which means doing a week of looking after user requests in turn, plus 6 more who do specialized tasks like site visits or do emergency repairs if a server or service acts up (like eg putting a stop to a mail loop). We have a ticketing system (RT) that user requests go into; whoever takes a ticket is responsible for resolving it.
For non-user requests, eg mail setup and mail-filtering is done by soda@, and tls@ is looking after hardware; I handle OS and package installation and upgrades.
NetBSDfr: NetBSD admin での作業はどういうことをやっていますか? admins には何人いますか? みんな一緒に作業するのですか? どうやってタスクを分担して作業してるのですか?
spz: おおざっぱにいうと、The NetBSD Foundation のサーバー群をセキュアにし、ちゃんと動作するように保ちます。実際のところはメールなどの古き良き管理サービスを管理しているだけです。現在は、ユーザーからのリクエストについては 5 人で回して作業してます。6 人目は、サーバー自身やサービスの調子が悪いときに復旧させるなど特殊なことをやってます( メールのループを停止したりすることです )。チケット管理システム( RT )を使っていて、ユーザーからの要求については誰でもチケットに着手し問題を解決するようにしています。
メールのセットアップやメールのフィルターなどユーザーからのリクエストではないものについては soda@ がおこなってくれましたし、ハードウェアは tls@ が面倒を見てくれてます。私は OS をいじったりパッケージをインストールしたりアップグレードなどしています。
NetBSDfr: What is the hardware infrastructure of the NetBSD project, in terms of hardware and software ? Where are they located ?
spz: We currently have two main sites, at ISC in Redwood City where the public servers are, and at Columbia University in New York where the TNF owned build cluster is. There is one lonely box in Sweden, hosted by the Lule Academic Computer Society, which provides data backup services.
The servers are a comparably boring bunch of rackmount servers (no fun retro archs at all, unless you count i386 ;), the newer ones amd64 arch and the older ones i386, and they run NetBSD-4 or NetBSD-5 at present, seeing that I am currently installing new servers instead of upgrading the remaining NetBSD-4 machines.
blog.NetBSD.org is a TNF system as of earlier today, and there will be a new ftp and due to reshuffling, new www and mail servers eventually too.
Thanks to everybody who donated funds and made the new machines possible, and of course also thanks to the organisations that host them.
NetBSDfr: NetBSD プロジェクトのインフラにはどのようなハードウェアやソフトウェアを使ってるのですか? それらはどこに設置されてますか?
spz: 現在はおもに 2 箇所のサイトがあります。公開用サーバーは Redwood の ISC にあり、New York の Columbia 大学には TNF 自身のビルドクラスターがあります。バックアップ用サービスが 1 つだけ Sweden の the Lule Academic Computer Society にホスティングされてます。
これらのサーバーはラックマウントのように詰まらないものです( i386 をカウントしないならば全部枯れたアーキテクチャです )( 訳: 古くてまったく面白みが無いアーキテクチャということ ????????? )、新しいものは amd64 から、古いものは i386 があるんですが、それらは NetBSD 4 または NetBSD 5 で動作してます。いま NetBSD 4 のマシンをアップグレードしてる最中です。
blog.NetBSD.org は TNF システムでは割りと新しいものです。いずれ ftp を刷新し、www と mail もそのうち新しくします。
寄付してくれたみなさんには感謝しています。おかげで新しいマシンを構築できました。もちろんホストさせてもらっている団体にも感謝します。
NetBSDfr: As part of the pkgsrc-releng team, can you tell us more about the way pkgsrc releases are organised ? How is a release tested / validated ?
spz: Unlike releng for the OS, the pkgsrc-releng team does not actually create the releases, it just maintains them. Pkgsrc releases are done roughly quarterly, give and take a week, and get 'cut' after one to two weeks of freeze period during which build and security issues of packages get fixed while the pkgsrc infrastructure itself is static. Build issues get found by the bulk builders, packages not working right get found by community input (if not by their maintainers, who usually use their packages themselves).
The main advantage of a maintained stable branch is that security issues get point fixes, ie you get to replace just the affected package and the rest stays at same version, which makes eg configuration incompatibilities a lot less likely. For production servers, using the stable branch of pkgsrc is definitely a good idea.
NetBSDfr: pkgsrc-releng チームについて聞きたいのですが、よろしければもう少し pkgsrc のリリース行程について聞かせてもらえませんか? テスト済みのものや認証済みのものはどうやってリリースするのですか?
spz: OS のリリースとは異なり、pkgsrc-releng チームは release を作成しません。ただメンテナンスするだけです。pkgsrc リリースはだいたい四半期ごとに 1 週間かけて作られ、その後 pkgsrc の更新を止め、2 週間かけてビルドしたり( 訳: ???? )パッケージのセキュリティホールを埋めたりし、凍結させ、cut します。( 訳: 「CVS のブランチを作る」などという意味? )。ビルドの問題については bulk builders が見つけてくれますし、パッケージが正常に動作するかどうかはコミュニティの知らせを見れば分かります( パッケージメンテナーによるものではない場合は彼ら自身がパッケージを使います )。( 訳: ?????????????? )
NetBSDfr: You told us there were no fun retro arch in the machines administered by the project. I'm wondering then how are pkgsrc releases built (if they are) for those retro archs ? Are the pkgsrc releases cross-compiled ? Provided by third-parties ? Not built ? Does it work the same way for NetBSD releases by themselves ? Are all the "fun retro" archs versions cross-compiled ?
spz: NetBSD proper can be cross compiled, the framework exists, and it's being used to provide binaries for all archs (see ftp.netbsd.orgs /pub/NetBSD-daily, we don't just build formal releases :).
pkgsrc has a few packages that have a cross compilation framework, but most don't, and there are several packages with a lot of dependants for which creating such a framework would mean ripping out the entire build system the package brings itself and redoing it, and redoing it for every new version that comes out after it, unless one gets buy-in by the people who create and maintain the software being packaged itself.
One of the headache packages in that space is perl, and it's interesting to see that there is now interest in a fully cross-compilable perl in the perl community itself.
So how do binary packages materialize? Developers who have the hardware bulk-build packages and upload them. You can read about the build reports on the mailing list pkgsrc-bulk.
NetBSDfr: あなたさは先ほど NetBSD プロジェクトには枯れたアーキテクチャのマシンが転がっていると言いました。不思議に思うんですが、どうやって pkgsrc のリリースをそれらのアーキテクチャ向けに( またはそれらのアーキテクチャ上で )ビルドしてるんですか? pkgsrc のリリースはクロスコンパイルしてるんですか? それともサードパーティから提供されるんですか? ほんとはビルドしてないとか? NetBSD のリリースでも同じことをやってるんでしょうか? 素敵なアーキテクチャもすべてクロスコンパイルしてるんでしょうか?
spz: NetBSD はすでにフレームワークが整っているのでクロスコンパイルは妥当ですし、全アーキテクチャのバイナリを提供するときにも使っています。( ftp.netbsd.orgs /pub/NetBSD-daily を見てください。リリースに限らずビルドされたものが置いてありますから :)
pkgsrc のいくつかのパッケージにはクロスコンパイルのフレームワークがありますが、ほとんどのパッケージにはありませんし、大量のパッケージに依存しているいくつかのパッケージについてフレームワークを使うように作成すると、ビルドシステム全体をビルドしなおすようなことになりますし、その後 新しいバージョンが登場するたびに同じ作業をおこなう羽目になり、one gets buy-in するひとたちが居ないならば、ソフトウェア自身によってパッケージされるように作成、保守されるようにすればいい。( 訳: ??????????? )
この辺りの話題については Perl が頭痛の種の 1 つで、面白いことに Perl コミュニティ自身の手によって完全なクロスコンパイル環境が構築されています。( 訳: おかしい。前半と後半の意味がつながらない )
で、どうやってバイナリパッケージを準備するか、でしたっけ? 開発者自身がパッケージの bulk-build するためのハードウェアを持っていて、それらをアップロードしています。pkgsrc-bulk のメーリングリストでビルド報告を見ることができます。
NetBSDfr : In your professional environment, do you work with NetBSD ? How do you think we should promote NetBSD for wider use within companies ?
spz: At my present job I don't work with NetBSB (yet); I'm currently not responsible for internal IT and the customers have existing servers to take care of, where a ninja change of OS is not entirely practical, if occasionally very much desired. :-7 There is lately some pkgsrc, at least.
In my experience, NetBSD gets used in general IT in companies where the sysadmins knew NetBSD previously and appreciated it as a "install - configure - runs" system of minimum ick factor. The more people know and appreciate NetBSD, and the more practical its use on production servers, the more use of that kind it will see. Of course, many companies use NetBSD and have no idea that they do so, since it's part of some "solution device" they use; these tend to be boring from my point of view though, since they tend to be rather black-box like. The makers of these devices will likely differ.
NetBSDfr: あなたは仕事では NetBSD を使って仕事してるんでしょうか? もっとたくさんの企業に NetBSD を促進するためにはどうしたらよいでしょうか?
spz: 仕事では NetBSD は使っていません( いまはまだね )。社内システム部門( 訳: internal IT )の担当ではないし、顧客が持ってる既存のサーバーの面倒を見るだけだし、a ninja change of OS is not entirely practical ですよ。ときどきものすごくそういう衝動に駆られますけどね :-7 まあ最近はいくつかの pkgsrc を使ってます。
私の経験では、一般的に、NetBSD を知ってるシステム管理者は仕事場でも NetBSD を使ってますし、あまりウンザリしなくて済む「インストールして、設定すれば走る」というのは評判が良いです。ほとんどのひとたちは NetBSD が良いものだということを知ってますし、サーバーとして実用できますし、ほかのことにもほどよく使えるでしょう。もちろん多くの企業が NetBSD を使っていますし、どう使うかという案は持ってないようです、彼らの問題を解決するための装置の一部という扱いだし、これらについては私が見てる限りではウンザリすることになるし、むしろブラックボックスとして扱われるようになります。装置メーカーはこの限りではないようですが。
NetBSDfr: As a conclusion, can you tell us how you forecast NetBSD future ?
spz: That's a hard one, especially as it depends a lot on 'chaotic' nature events of, eg, one developer pulling something out of their hat that proves to be a must have feature for an entire new class of device, or others banding together to make a form of use that is now possible but tedious to set up a snap drop-in; and in the long run, the question where computing is going is also unclear.
I can tell you what I am hoping for, and that is for a NetBSD that is small enough to allow the insertion of daring new ideas in -current, and large enough to mature -current into a rock solid release track system periodically; a project that generates ideas that may spread into the common pool and isn't just a me-too with slightly different wallpaper. That is why I'm spending my time on doing infrastructure, at least.
Oh, and I want cool ARM based netbooks with ridiculously long battery lifetime running NetBSD available soonish. The guilty parties will hopefully get a move on :-P
NetBSDfr: 最後に NetBSD が今後どのようになっていくかあなたの考えを聞かせてください。
spz: 難しいね。何が起きるか分らないし。たとえば、ある開発者は新しいデバイスクラス全体を機能させるためにいざこざを起こすかもしれないし、ほかの誰かは snap drop-in をセットアップするのに飽きて make a form を一緒くたにしてしまうかもしれないし、結局コンピューティングの将来が不明なのと同じだよね。
希望を言えば、NetBSD は -current に奇抜な試み導入できるくらいはじゅうぶん小さくなってほしいし、成熟した -current がリリースごとに定期的にシステムを追えるほど堅固になるくらいじゅうぶん大きくなってほしいし、NetBSD プロジェクトが common pool の範囲内でアイデアを作ってほしいし、私だけに限らないけど少しずつ違った壁紙がほしい。少なくとも、それが、なぜ私がインフラに時間をかけてるかの答えです。
ああ、あと、NetBSD を乗せて長時間バッテリー駆動する ARM のネットブックが欲しいです。これは急務です :-P
Many thanks to Guillaume Lasmayous from NetBSDfr for his hard work in preparing, conducting and translating this interview.
Guillaume Lasmayous は前準備や運営やインタビュー記事を送ってくれて感謝する。
_ [Python][デザインパターン][Adapter]Python でデザインパターン - Adapter
書き換え[ 20090508#p04 ]
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 7章 Adapter パターン - ヨタの日々(2009-05-08) # http://www.area51.gr.jp/~rin/diary/?date=20090508#p04 class Duck: def quack(self): pass def fly(self): pass class MallardDuck(Duck): def quack(self): print "ガーガー" def fly(self): print "飛んでいます" class Turkey: def gobble(self): pass def fly(self): pass class WildTurkey(Turkey): def gobble(self): print "ゴロゴロ" def fly(self): print "短い距離を飛んでいます" class TurkeyAdapter(Duck): def __init__(self, turkey): self.turkey = turkey def quack(self): self.turkey.gobble() def fly(self): for i in range(5): self.turkey.fly() def main(): duck = MallardDuck() turkey = WildTurkey() turkeyAdapter = TurkeyAdapter(turkey) print "Turky の出力..." turkey.gobble() turkey.fly() print "\nDuck の出力..." testDuck(duck) print "\nTurkeyAdapter の出力..." testDuck(turkeyAdapter) def testDuck(duck): duck.quack() duck.fly() main()
出力
% python adapter.py Turky の出力... ゴロゴロ 短い距離を飛んでいます Duck の出力... ガーガー 飛んでいます TurkeyAdapter の出力... ゴロゴロ 短い距離を飛んでいます 短い距離を飛んでいます 短い距離を飛んでいます 短い距離を飛んでいます 短い距離を飛んでいます
2010-08-06 :-(
_ 朝ッ
0520 起床
_ 仕事
0830 出勤
_ CR2 と JPEG ファイルを異なるディレクトリに配置することにした
( ※ CR2: Canon EOS 系 RAW ファイル )
いままで CR2 と JPEG を同じディレクトリに置いてた。
そうすると PS3 Media Server で画像を見るとき CR2 と JPEG の両方とも区別なく表示してくれちゃうのでいろいろ不都合が無くは無いのだけど面倒くさいのでそのうちやろうと思っててずーっと放置してたんだが、いつの間にか iTunes が iPod touch へ CR2 も転送するようになったので( これまでは CR2 は除外されてた ) 結局 CR2 と JPEG ファイルを別のディレクトリに配置するようにした。16GB iPod touch に CR2 を転送されたらタマッタモノジャナイ。
ということで Python の練習。日付ごとにディレクトリを作ってそこにファイルをコピーしてく。というか EOS Utility などでカメラから計算機へ画像を転送したときのようなディレクトリ構成にしたいだけ。移動じゃなくてコピーなのはまあ削除したければ find などすればいい。
#!/usr/bin/python # -*- coding:utf8 -*- # CR2 をコピーする import sys import os import time import shutil from stat import * prog = sys.argv[0] if len(sys.argv) < 2: print "%s SRCDIR DSTDIR" %(prog) sys.exit() srcrootdir = sys.argv[1] dstrootdir = sys.argv[2] if os.path.exists(srcrootdir) == False: print "%s not found" % (srcrootdir) sys.exit() for root, dirs, files in os.walk(srcrootdir): for file in files: filename = os.path.join(root, file) if filename.lower().find(".cr2") == -1: continue # print filename stat = os.stat(filename) timestamp = time.strftime("%Y/%m/%d", time.localtime(stat[ST_MTIME])) # print timestamp dstdir = os.path.join(dstrootdir, timestamp) # print dstdir if os.path.isdir(dstdir) == False: os.makedirs(dstdir) print "copy %s to %s" % (file, dstdir) shutil.copy2(filename, dstdir)
2010-08-07 :-)
_ 朝っ
0900 起床
_ [Python][デザインパターン][Decorator]Python でデザインパターン - Decorator
書き換え[ 20090505#p06 ]
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 3章 Decorator パターン - ヨタの日々(2009-05-05) # http://www.area51.gr.jp/~rin/diary/?date=20090505#p06 class Beverage: def __init__(self): self.description = "不明な飲み物" def getDescription(self): return self.description; def cost(self): pass class CondimentDecorator(Beverage): def getDescription(self): pass class Espresso(Beverage): def __init__(self): self.description = "エスプレッソ" def cost(self): return 1.99 class HouseBlend(Beverage): def __init__(self): self.description = "ハウスブレンド" def cost(self): return 0.89 class DarkRoast(Beverage): def __init__(self): self.description = "ダークロースト" def cost(self): return 0.99 class Decaf(Beverage): def __init__(self): self.description = "カフェイン抜き" def cost(self): return 1.05 class Mocha(CondimentDecorator): def __init__(self, b): self.beverage = b def getDescription(self): return self.beverage.getDescription() + "、モカ" def cost(self): return 0.20 + self.beverage.cost() class Whip(CondimentDecorator): def __init__(self, b): self.beverage = b def getDescription(self): return self.beverage.getDescription() + "、ホイップ" def cost(self): return 0.10 + self.beverage.cost() class Soy(CondimentDecorator): def __init__(self, b): self.beverage = b def getDescription(self): return self.beverage.getDescription() + "、豆乳" def cost(self): return 0.15 + self.beverage.cost() def main(): beverage = Espresso() print "%s %s" % (beverage.getDescription(), beverage.cost()) beverage2 = DarkRoast() beverage2 = Mocha( beverage2 ) beverage2 = Mocha( beverage2 ) beverage2 = Whip( beverage2 ) print "%s %s" % (beverage2.getDescription(), beverage2.cost()) beverage3 = HouseBlend() beverage3 = Soy( beverage3 ) beverage3 = Mocha( beverage3 ) beverage3 = Whip( beverage3 ) print "%s %s" % (beverage3.getDescription(), beverage3.cost()) main()
% python decorator.py エスプレッソ 1.99 ダークロースト、モカ、モカ、ホイップ 1.49 ハウスブレンド、豆乳、モカ、ホイップ 1.34
_ [ドラゴンクエストの世界]第24回ファミリークラシックコンサート ~ドラゴンクエストの世界~ 交響組曲「ドラゴンクエスト IX」 星空の守り人
@東京芸術劇場・大ホール
曲
第一部
- 序曲IX
- 天の祈り
- 宿命~悲壮なるプロローグ
- 王宮のオーボエ
- 来たれわが街へ~夢みるわが街~酒場のポルカ~来たれわが街へ
- 野を越え山を越え~仲間とともに~箱舟に乗って~野を越え山を越え
- 陽だまりの村~村の夕べ
- 負けるものか~渦巻く欲望
第二部
- 暗闇の魔窟~洞窟のワルツ~そびえ立つ死の気配
- 集え、者たち~祈りの詩~せつなき思い
- サンディのテーマ~サンディの泪~サンディのテーマ
- 運命に導かれ~主なき神殿
- 決戦の時
- 星空へ~星空の守り人
アンコール
- 時の子守唄( DQ6 )
- 序曲IX
すぎやまこういちさんのお話
「ドラゴンクエストシリーズの王宮の曲は何か 1 つ楽器をもとにした曲があります。王宮のトランペット(5) 王宮のホルン(6) など。そのなかで『これだけはやりたくないなあ』という楽器は『王宮のブブゼラ』です :-) 」
「というわけで次の 2 曲。『王宮のオーボエ』から..... あ゛ 話す順番間違えた。『王宮のオーボエ』じゃなくて『天の祈り』です 」
とかいろいろ
_ [今日は一日ゲーム音楽三昧]NHK FM 今日は一日ゲーム音楽三昧
昼から録音しながら聞いていた。んだがツールの使い方がフガホゲであり途中 録音失敗している。
ドラクエコンサートのため外出したのだけど、その間にドラクエ、ときメモ、FFタイムがあったらしい。愛しの植松伸夫は私が帰宅する直前まで出演していたとか。くう
菊田裕樹さんが無かったり浜渦正志さんが無かったり崎元仁さんたちベイシスケイプの曲( オウガバトルとか! 蒼穹紅蓮隊リクエストしたのに )が無かったりと全体的に物足りないんだが、まあ仕方ない。ゲームは多すぎる。ジャンル別に分割などして今後も何度か放送してほしいなー。
最後の曲はこういうことらしい。
多分、ラジオで最後にギャラガが流れた理由がわからない人ってたくさんいると思う。実はね、さっきの曲は、世の中で一番最初に発売されたゲームミュージックのサントラの、一番最後の曲なんだよ。 #gamemusiczanmai (dfk_ohnuma)
あと大久保博さんのコメント
細野さんがVGM出してくれなかったらゲーム音楽の世界はこんなに盛り上がってなかったわけで。原点のレコードのラストトラックで締めるという狙いは、いい時代のNHKっぽくて好き。ボクも予約して買った思い出がよみがえった。(ookubon)
曲リスト→今日は一日 ○○三昧(ざんまい)
2010-08-08 :-)
_ 朝ッ
0900 起床
_ [Python][デザインパターン][Factory]Python でデザインパターン - Factory
書き換え[ 20090506#p04 ]
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 4章 Factory パターン - ヨタの日々(2009-05-06) # http://www.area51.gr.jp/~rin/diary/?date=20090506#p04 class PizzaStore: def orderPizza(self, _type): self.pizza = self.createPizza(_type) self.pizza.prepare() self.pizza.bake() self.pizza.cut() self.pizza.box() return self.pizza def createPizza(self, _type): pass class NYPizzaStore(PizzaStore): def createPizza(self, item): if item == "チーズ": return NYStyleCheesePizza() ## elif item == "野菜": ## return NYStyleVeggiePizza() ## elif item == "クラム": ## return NYStyleClamPizza() ## elif item == "ペパロニ": ## return NYStylePepperoniPizza() else: return None class ChicagoPizzaStore(PizzaStore): def createPizza(self, item): if item == "チーズ": return ChicagoStyleCheesePizza() ## elif item == "野菜": ## return ChicagoStyleVeggiePizza() ## elif item == "クラム": ## return ChicagoStyleClamPizza() ## elif item == "ペパロニ": ## return ChicagoStylePepperoniPizza() else: return None class CaliforniaPizzaStore(PizzaStore): def createPizza(self, item): if item == "チーズ": return CaliforniaStyleCheesePizza() ## elif item == "野菜": ## return CaliforniaStyleVeggiePizza() ## elif item == "クラム": ## return CaliforniaStyleClamPizza() ## elif item == "ペパロニ": ## return CaliforniaStylePepperoniPizza() else: return None class Pizza: def __init__(self): self.name = None self.dough = None self.sauce = None self.toppings = None def prepare(self): print "%s を下処理" % (self.name) print "生地をこねる..." print "ソースを追加..." print "トッピングを追加:" for t in self.toppings: print " %s" % (t) def bake(self): print "350度で25分間焼く" def cut(self): print "ピザを扇形に切り分ける" def box(self): print "PizzaStore の正式な箱にピザを入れる" def getName(self): return self.name class NYStyleCheesePizza(Pizza): def __init__(self): self.name = "ニューヨークスタイルのソース&チーズピザ" self.dough = "薄いクラスト生地" self.sauce = "マリナラソース" self.toppings = [] self.toppings.append("粉レッジャーノチーズ") class ChicagoStyleCheesePizza(Pizza): def __init__(self): self.name = "シカゴスタイルのディープディッシュチーズピザ" self.dough = "極厚クラスト生地" self.sauce = "プラムトマトソース" self.toppings = [] self.toppings.append("刻んだモッツァレラチーズ") def cut(self): print "ピザを四角形に切り分ける" def main(): nyStore = NYPizzaStore() chicagoStore = ChicagoPizzaStore() pizza = nyStore.orderPizza("チーズ") print "イーサンの注文は %s" % (pizza.getName()) pizza = chicagoStore.orderPizza("チーズ") print "ジョエルの注文は %s" % (pizza.getName()) main()
% python factory.py ニューヨークスタイルのソース&チーズピザ を下処理 生地をこねる... ソースを追加... トッピングを追加: 粉レッジャーノチーズ 350度で25分間焼く ピザを扇形に切り分ける PizzaStore の正式な箱にピザを入れる イーサンの注文は ニューヨークスタイルのソース&チーズピザ シカゴスタイルのディープディッシュチーズピザ を下処理 生地をこねる... ソースを追加... トッピングを追加: 刻んだモッツァレラチーズ 350度で25分間焼く ピザを四角形に切り分ける PizzaStore の正式な箱にピザを入れる ジョエルの注文は シカゴスタイルのディープディッシュチーズピザ
_ [Python][デザインパターン][State]Python でデザインパターン - State
書き換え[ 20090531#p06 ]
#!/usr/bin/python # -*- coding: utf-8 -*- # Head First デザインパターンを写経する - 10章 State パターン - ヨタの日々(2009-05-31) # http://www.area51.gr.jp/~rin/diary/?date=20090531#p06 class State: def insertQuarter(self): pass def ejectQuarter(self): pass def turnCrank(self): pass def dispense(self): pass class HasQuarterState(State): def __init__(self, gumballMachine): self.gumballMachine = gumballMachine def insertQuarter(self): print "もう一度25セントを投入することはできません" def ejectQuarter(self): print "25セントを返却します" self.gumballMachine.setState(self.gumballMachine.getNoQuarterState()) def turnCrank(self): print "クランクを回しました..." self.gumballMachine.setState(self.gumballMachine.getSoldState()) def dispense(self): print "販売するガムボールはありません" def __str__(self): return "waiting for turn of crank" class NoQuarterState(State): def __init__(self, gumballMachine): self.gumballMachine = gumballMachine def insertQuarter(self): print "25セントを投入しました" self.gumballMachine.setState( self.gumballMachine.getHasQuarterState()) def ejectQuarter(self): print "25セントを投入していません" def turnCrank(self): print "クランクを回しましたが、25セントを投入していません" def dispense(self): print "まず支払いをする必要があります" def __str__(self): return "25セントが投入されるのを待っています" class SoldOutState(State): def __init__(self, gumballMachine): self.gumballMachine = gumballMachine def insertQuarter(self): print "25セントを投入することはできません。このマシンは売り切れです" def ejectQuarter(self): print "返金できません。まだ25セントを投入していません" def turnCrank(self): print "クランクを回しましたが、ガムボールがありません" def dispense(self): print "販売するガムボールはありません" def __str__(self): return "売り切れです" class SoldState(State): def __init__(self, gumballMachine): self.gumballMachine = gumballMachine def insertQuarter(self): print "お待ちください。すでにガムボールを出しています" def ejectQuarter(self): print "申し訳ありません。すでにクランクを回しています" def turnCrank(self): print "2回回してもガムボールをもう1つ入手することはできません!" def dispense(self): self.gumballMachine.releaseBall if self.gumballMachine.getCount() > 0: self.gumballMachine.setState(self.gumballMachine.getNoQuarterState()) else: print "おっと、ガムボールがなくなりました!" self.gumballMachine.setState(self.gumballMachine.getSoldOutState()) def __str__(self): "dispensing a gumball" class GumballMachine: def __init__(self, numberGumballs): self.soldOutState = SoldOutState( self ) self.noQuarterState = NoQuarterState( self ) self.hasQuarterState = HasQuarterState( self ) self.soldState = SoldState( self ) self.state = self.soldOutState self.count = numberGumballs if numberGumballs > 0: self.state = self.noQuarterState def insertQuarter(self): self.state.insertQuarter() def ejectQuarter(self): self.state.ejectQuarter() def turnCrank(self): self.state.turnCrank() self.state.dispense() def setState(self, state): self.state = state def releaseBall(self): print "ガムボールがスロットから転がり出てきます" if self.count != 0: self.count = self.count - 1 def getCount(self): return self.count def refill(self, count): self.count = count self.state = self.noQuarterState def getState(self): return self.state def getSoldOutState(self): return self.soldOutState def getNoQuarterState(self): return self.noQuarterState def getHasQuarterState(self): return self.hasQuarterState def getSoldState(self): return self.soldState def __str__(self): result = "" result += "\nMighty Gumball, Inc." result += "\nJava対応据付型ガムボール モデル #2004" result += "\n在庫: #{self.count} 個のガムボール" result += "\nマシンは%s" % (self.state) return result def main(): gumballMachine = GumballMachine( 5 ) print gumballMachine gumballMachine.insertQuarter() gumballMachine.turnCrank() print gumballMachine gumballMachine.insertQuarter() gumballMachine.turnCrank() gumballMachine.insertQuarter() gumballMachine.turnCrank() print gumballMachine main()
% python state.py Mighty Gumball, Inc. Java対応据付型ガムボール モデル #2004 在庫: #{self.count} 個のガムボール マシンは25セントが投入されるのを待っています 25セントを投入しました クランクを回しました... Mighty Gumball, Inc. Java対応据付型ガムボール モデル #2004 在庫: #{self.count} 個のガムボール マシンは25セントが投入されるのを待っています 25セントを投入しました クランクを回しました... 25セントを投入しました クランクを回しました... Mighty Gumball, Inc. Java対応据付型ガムボール モデル #2004 在庫: #{self.count} 個のガムボール マシンは25セントが投入されるのを待っています
_ 盛り上がるネタ
- ベストなテキストエディタはなんですか?
- おすすめのプログラミング言語はなんですか?
- Linux って Windows よりショボイんでしょ?
- ○○されるほうが悪い( ○○には犯罪の名前が入る )
- 処女厨
_ ,
ベイシスケイプ分がまったく不足しているのでトレジャーハンターGを聞くなどしている。
_ sizeof
CentOS 64bit な環境でリベンジ [ 20100502#p02 ]
#include <stdio.h> int main( int ac, char** av ) { printf( "%d\n", sizeof( int ) ); printf( "%d\n", sizeof( long ) ); printf( "%d\n", sizeof( void* ) ); return 0; }
$ gcc size.c && ./a.out 4 8 8
フォカヌポウ
_ LPIC って自慢になるの?
周囲には趣味で LPIC 出題範囲内くらいのことをおこなっているひとはゴロゴロいるし自分でもやってるので( 自宅にサーバー設置して Linux でも *BSD でもいいからテキトーな計算機にテキトーにオペレーティングシステムをインストールして DNS 設定して Postfix などを運用しメーリングリストなどを使えるようにしておけば LPIC レベル 2 まではイケル ) LPIC 取得した程度で自慢になるのかどうか分からん。
2010-08-10 :-)
_ ,
agumon さんがレースネタを構想している
_ [NetBSD][PDP-11][翻訳]hubertf's NetBSD blog - Of course it runs ... 2.11BSD (or: PDP-11 in a FPGA)
It's about time NetBSD gets the PDP11 port done: the PDP-11/70 CPU core is now available as implementation on a FPGA-board, and there's need for a newer operating system than 2.11BSD! Citing from the homepage:
NetBSD への PDP11 移植がようやく終わった。PDP-11/70 CPU core が FPGA ボードで実装されたのだ。2.11BSD より新しいオペレーティングシステムならば動くんだぜ!homepage より引用:
``The project contains a complete PDP-11 system: a 11/70 CPU with memory management unit, but without floating point unit, a basic set of UNIBUS peripherals (DL11, LP11, PC11, RK11/RK05), and last but not least a cache and memory controllers for SRAM and PSRAM. The design is FPGA proven, runs currently on Digilent S3BOARD and NEXYS2 boards and boots 5th Edition UNIX and 2.11BSD UNIX. ''
このプロジェクトの目的には PDP-11 を完全に実装することがある: 11/70 CPU でメモリマネージメントユニット( ただし浮動小数点演算ユニットは除く )、基本的な UNIBUS ペリフェラル(DL11, LP11, PC11, RK11/RK05) のセット、そして最後に、これが重要なのだが SRAM と PSRAM のキャッシュコントローラーとメモリーコントローラーだ。この設計で Digilent S3BOARD と NEXYS2 ボード FPGA で実装できたし、5th Edition UNIX と 2.11BSD UNIX で起動できた。
_ ,
うーさーのひとってたしか 10 年くらい前に獣姦ビデオ鑑賞オフなどというものをおこなってブルーになってたひとじゃなかったっけ
_ HTML の a href= で指定したファイル名を小文字に変えたいだけなんだよ
gsub イッパツというわけにはいかないのか。
#!/usr/pkg/bin/ruby while gets if $_ =~ /(.*)(<a href=")(.*)(">)(.*)/ puts "#{$1}#{$2}#{$3.downcase}#{$4}#{$5}" else puts $_ end end
_ [リッジレーサー7]リッジレーサー7
オンラインバトルなど。B2ェ....
- 走行距離 97318 km
- RSGP 進行度 100.0 %
- 名声 24885 FP
- オンラインバトル勝利数 929/3387
_ [QuickML][コードリーディング][Ruby]QuickML を読む - 概要
QuickML とは、高林哲さんが書いたメーリングリストシステムである。うちでも使っている。ありがたいことである。
横着プログラミング 第5回: QuickML: 超お手軽なメーリングリスト
QuickMLは
- メーリングリストを作るのが面倒
- メーリングリストを管理するのが面倒
- コマンドメールを覚えるのが面倒
- Web上のフォームにあれこれ記入するのが面倒
といった面倒さを解決し、いつでも、どこでも、誰でもお手軽にメーリングリストを活用できるシステムである。
ソースコードはこちら→ quickmlサーバ: 超お手軽なメーリングリストシステム
なお手前味噌ながら作業ログはこちら 同一ホスト上で qmail と QuickML を動かす手順 同一ホスト上で Postfix と QuickML を動かす手順
_ [QuickML][コードリーディング][Ruby]QuickML を読む - quickml-ctl
QuickML の起動処理について読んでいく。
ソースコードをダウンロードし、展開すると configure や Makefile.in などがあることが分かる。QuickML のインストールは ./configure && make && make install すればよい。
起動させるときは quickml-ctl を実行する。quickml-ctl を読んでみる。
#! /bin/sh start() { echo -n "Starting QuickML services: " /usr/local/sbin/quickml echo } stop() { echo -n "Stopping QuickML services: " kill `cat /var/run/quickml.pid` echo } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 1 start ;; *) echo "Usage: quickml-ctl {start|stop|restart}" exit 1 esac exit 0
起動だけでなく終了、最起動するときも quickml-ctl を使う。quickml-ctl start、quickml-ctl stop などして実行する。
quickml-ctl に渡された start, stop, restart に応じて各々処理する。
quickml-ctl start すると /usr/local/sbin/quickml を実行し、quickml を開始する。/usr/local/sbin/quickml の場所は configure したときに決まるのでこの PATH ではない場合もある。
_ [QuickML][コードリーディング][Ruby]QuickML を読む - quickml
/usr/local/sbin/quickml を読んでみる。
まずはスクリプト冒頭。
$KCODE = "e" require 'quickml'
require 'quickml' で lib/quickml.rb を読み込んでいる。lib/quickml.rb はこうなっている。lib/quickml/* のファイルを読み込んでいる。
require 'quickml/utils' require 'quickml/config' require 'quickml/core' require 'quickml/gettext' require 'quickml/logger' require 'quickml/mail' require 'quickml/server' require 'quickml/sweeper' require 'quickml/version'
/usr/local/sbin/quickml に戻る。main() を読む。
def main (argv) config_file = if argv.length == 1 then argv.first else File.join("/usr/local/etc", "quickmlrc") end config = QuickML::Config::load(config_file) check_directory(config.data_dir)
argv には Ruby 定数 ARGV がそのまま入る。quickml-ctl を使った場合 ARGV は空である。よって config_file は /usr/local/etc/quickmlrc になる。/usr/local/sbin/quickml hogehoge.rc などとすれば別の設定ファイルを読み込ませることができる。
その /usr/local/etc/quickmlrc を QuickML::Config::load(config_file) により読み込み、config を作成している。config については後述する。
config.data_dir を check_directory() でチェックしている。check_directory() はこう。
def check_directory (dir) error("#{dir}: No such directory") unless File.directory?(dir) error("#{dir}: is not writable") unless File.writable?(dir) end
dir がディレクトリでないか、または書き込み可能でない場合は error() を呼んでいる。error() はこう。
def error (msg) STDERR.puts "#{$0}: #{msg}" exit(1) end
標準エラー出力にプログラム名とメッセージを印字し、終了する。$0 は現在のプログラム名を表す Ruby 変数である。
check_directory() の次は be_daemon() と be_secure() を呼ぶ。
be_daemon be_secure(config)
be_daemon() を見る。
def be_daemon exit!(0) if fork Process::setsid exit!(0) if fork Dir::chdir("/") File::umask(022) STDIN.reopen("/dev/null", "r+") STDOUT.reopen("/dev/null", "r+") STDERR.reopen("/dev/null", "r+") end
プログラム自身をデーモン化させる処理である。デーモン化させる手順は一般的にはこう。
1. fork()して、親プロセスを終了させる。こうすると、シェルに制御が戻る。
2. setsid()により、プロセスグループとセッショングループのリーダーになる。
3. 再びfork()し、親プロセス(セッショングループリーダー)を終了させる。
4. chdir("/")し、どのディレクトリも使用中でないことを明確にする。これを忘れると、ファイルシステムのアンマウントが出来なくなることがある。
5. umask(0)して、以降作成されるあらゆるファイルを支配下に置く。
6. ファイルディスクリプタの0、1、2をclose()する。親プロセスから引き継いだ、リダイレクト先不明の標準入出力は使用しない。
7. stdin、stdout、stderrは、自分で新しいディスクリプタとしてopen()する。
詳しいことは詳解 UNIX プログラミングを読むなどするとよい。
なお、Ruby 1.9 には Process.daemon が実装させているのでたんにこれを呼べばよい。
次に be_secure() を見てみる。
def be_secure (config) return unless Process.uid == 0 uid = Etc::getpwnam(config.user).uid gid = Etc::getgrnam(config.group).gid touch(config.pid_file) touch(config.log_file) File.chown(uid, gid, config.data_dir) File.chown(uid, gid, config.pid_file) File.chown(uid, gid, config.log_file) Process.uid = uid Process.gid = gid Process.euid = uid end
関連するファイルの UID と GID と 実効UID を config で設定した user と group に設定している。config については後述。
main() の最後。
server = QuickML::Server.new(config) sweeper = QuickML::Sweeper.new(config)
ここで server と sweeper を起動している。server は QuickML のメーリングリストとしての動作を請け負う。sweeper はメーリングリストの有無やユーザーの有無などを処理する。
trap(:TERM) { server.shutdown; sweeper.shutdown } trap(:INT) { server.shutdown; sweeper.shutdown } trap(:HUP) { config.logger.reopen }
プログラムに TERM シグナルまたは INT シグナルが送られたときは server と sweeper を終了させ、HUP が送られたときは logger を reopen する。この辺りは後述。
t = Thread.new { sweeper.start } t.abort_on_exception = true server.start
sweeper スレッドを生成し、server も開始させる。abort_on_exception は以下のように働く。
真の時は、いずれかのスレッドが例外によって終了した時に、インタプリタ全体を中断させます。デフォルトは偽、すなわち、通常あるスレッドで起こった例外は、Thread#join などで検出されない限りそのスレッドだけをなにも警告を出さずに終了させます。
2010-08-11 :-)
_ 朝ッ
1030 起床
_ [コードリーディング][Ruby][QuickML]QuickML を読む - config
QuickML の設定ファイルを管理するクラス。
/usr/local/sbin/quickml で QuickML::Config::load(config_file) としていたので、initialize() が最初に呼ばれるのではなく load が呼ばれる。
def self.load (filename) self.new(eval(File.safe_open(filename).read)) end
load() の中で new() している。どうして load() 経由で呼んでいるのかは分からない。誰か教えて。def self.ナントカ とするとクラスメソッドとして定義することになる。どうしてクラスメソッドにしておくのかというと、インスタンスを生成する手間を省きたいからじゃないでしょうか。たぶん
new() に渡している引数を見ていく。以下のような順番で処理される。
- File.safe_open(filename)
- それを read()
- それを eval()
- それを new() に渡す
File.safe_open() は lib/quickml/utils.rb の中で定義している。
class File def self.safe_open (filename, mode = "r") begin f = File.open(filename, mode) if block_given? yield(f) f.close else return f end rescue => e STDERR.printf "%s: %s\n", $0, e.message exit(1) end end end
block_given? とはなんぞや
block_given?
メソッドにブロックが与えられている時には真、そうでない時に偽を返します。
つまり、以下のように呼ぶと block_given? は真
File.safe_open(hogehoge) {|f| 何かの処理 }
以下のように呼ぶと block_given? は偽となる。
f = File.safe_open(hogehoge)
self.load では File.safe_open(filename) と、ブロックを渡していないので File.safe_open() では File オブジェクトが返る。
次に、その File オブジェクトの read() を呼ぶ。quickmlrc の全て読み込んでいる。
File.safe_open(filename).read
quickmlrc の内容はこう。Ruby のハッシュである。ここではまだハッシュオブジェクトではなく、たんなる文字列になっている。
# -*- mode: ruby -*- Config = { :user => "quickml", :group => "quickml", :port => 10025, :bind_address => "0.0.0.0", :smtp_host => '127.0.0.1', :smtp_port => 25, :domain => 'qml.area51.gr.jp', :postmaster => "rin@maaya.jp", :info_url => "http://QuickML.com/", :data_dir => '/usr/local/var/quickml', :pid_file => '/var/run/quickml.pid', :log_file => '/var/log/quickml.log', :verbose_mode => true, :max_members => 100, :max_mail_length => 100 * 1024, :ml_life_time => 86400 * 31, :ml_alert_time => 86400 * 30, :auto_unsubscribe_count => 5, :sweep_interval => 3600, :max_threads => 10, :timeout => 120, :use_qmail_verp => false, :confirm_ml_creation => false, # for confirming ML creation. (experimental) # :message_catalog => nil # for English messages :message_catalog => '/usr/local/share/messages.ja', }
次に、ここで読み込んだ Config を eval() する。
eval(File.safe_open(filename).read))
eval() してようやく Config はハッシュオブジェクトとして生成されたことになる。
その Config を self.new() に渡す。
new() を呼ぶと initialize() が呼ばれるので initialize() を見てみる。長いので省略
def initialize (config = {}) @data_dir = config[:data_dir] @smtp_host = config[:smtp_host] @domain = config[:domain] raise ArgumentError if @data_dir.nil? raise ArgumentError if @smtp_host.nil? raise ArgumentError if @domain.nil? @pid_file = (config[:pid_file] or "/var/run/quickml.pid") @max_members = (config[:max_members] or 100) @max_mail_length = (config[:max_mail_length] or 100 * 1024) # 100KB :
見たとおりに config にあるキーから値を取得などしている。
(config[:pid_file] or "/var/run/quickml.pid") という処理は config[:pid_file] が nil ならば "/var/run/quickml.pid" を設定するということを意味している。つまり quickmlrc に pid_file が定義されていなければ "/var/run/quickml.pid" を使う。いわゆるデフォルト値になる。
initialize() の最後に注目。
instance_variables.each {|name| self.class.class_eval { attr_reader name.delete('@') } }
instance_variables とはなんぞや
instance_variables
オブジェクトのインスタンス変数名を文字列の配列として返します。
obj = Object.new obj.instance_eval { @foo, @bar = nil } p obj.instance_variables # => ["@foo", "@bar"]
これで
["@data_dir", "@smtp_host", "@domain" ...]
といった配列が返る。それを each する。
self.class.class_eval { attr_reader name.delete('@') } を 1 つずつ見ていく。
self.class はつまり自分自身のクラス。
class_eval とはなんぞや。これは結局 module_eval である。
module_eval とはなんぞや。
ブロックが与えられた場合にはそのブロックをモジュールのコンテキストで評価してその結果を返します。ブロックの引数 mod には self が渡されます。
モジュールのコンテキストで評価するとは、実行中そのモジュールが self になるということです。つまり、そのモジュールの定義文の中にあるかのように実行されます。
ええと、つまり @data_dir などに attr_reader 属性を付加していることになるらしい。へー
_ また処女か
「処女」かどうかと「乙女チック」「乙女心」「清純」などというものは別の問題なので、そこをゴチャゴチャすると話にならない。
前者はたんに肉体の問題であり、後者は精神、立ち居振る舞いの問題である。
処女厨が叩かれるのは「処女イコール清純」という前提になってるからであろうよ。
だと思うんだよね。
_ [QuickML][Ruby][コードリーディング]QuickML を読む - logger
ログを印字する処理。同期に対して注意している。
require 'quickml/utils' require 'thread' module QuickML class Logger def initialize (log_filename, verbose_mode = nil) @mutex = Mutex.new @log_file = File.safe_open(log_filename, "a") @log_file.sync = true @verbose_mode = verbose_mode end
log_file.sync は結局 IO の sync を設定している。
sync
現在の出力同期モードを真偽値で返します。同期モードが真の時は出力関数の呼出毎にバッファがフラッシュされます。
そのまま。
private def puts_log (msg) @mutex.synchronize { time = Time.now.strftime("%Y-%m-%dT%H:%M:%S") @log_file.puts "#{time}: #{msg}" } end public def log (msg) puts_log(msg) end def vlog (msg) puts_log(msg) if @verbose_mode end
外部には log() と vlog() を公開しておき、結局各々 puts_log() を呼んでいる。puts_log() では RFC 3339 ぽい日付時間フォーマットに整形している(ref. RFC3339 インターネット上の日付と時間:タイムスタンプ )。( タイムオフセットが無いよね? )
def reopen @mutex.synchronize { log_filename = @log_file.path @log_file.close @log_file = File.safe_open(log_filename, "a") } end
同期を気にしつつファイルを一度閉じて開いている。reopen() は HUP を貰ったときに実行される。
trap(:HUP) { config.logger.reopen }
_ ,
結局個体差なので「処女だから云々」というのはつまり主語が大きいんである。
_ 買い物
@紀伊国屋
ラノベ分が枯渇した
4044748187
4094511539
4086305577
4840131627
4840134049
4840124019
4840126003
4044740046
4044740054
4044740062
4044740070
2010-08-12 :-)
_ 朝ッ
0400 起床
_ ちゃりったー
朝日っておる
_ [QuickML][コードリーディング][Ruby]QuickML を読む - server 起動
あとまわしにしていた server の処理を読む。起動のところだけ。
ファイルは lib/quickml/server.rb
Server クラスの処理。
def initialize (config) @config = config @status = :stop @logger = @config.logger @server = TCPServer.new(@config.bind_address, @config.port) end
initialize() で内部の状態を設定などしている。server は Ruby の TCPServer をラップしている。
initialize() したら start() が呼ばれる。start() はこう。
def start raise "server already started" if @status != :stop write_pid_file @logger.log sprintf("Server started at %s:%d [%d]", "localhost", @config.port, Process.pid) accept @logger.log "Server exited [#{Process.pid}]" remove_pid_file end
状態をチェックし、起動済みならば例外を発生させる。
write_pid_file() では QuickML のプロセスID が書かれたファイルを作成している。Unix では伝統的な pid ファイルである。このファイルは quickml-ctl の stop() で以下のように使われる。
stop() { echo -n "Stopping QuickML services: " kill `cat /var/run/quickml.pid` echo }
次に accept() する。名前の通り接続待ちになる。accept() はこう。
def accept running_sessions = [] @status = :running while @status == :running begin t = Thread.new(@server.accept) {|s| process_session(s) } t.abort_on_exception = true running_sessions.push(t) rescue Errno::ECONNABORTED # caused by @server.shutdown rescue Errno::EINVAL end running_sessions.delete_if {|t| t.status == false } if running_sessions.length >= @config.max_threads ThreadsWait.new(running_sessions).next_wait end end running_sessions.each {|t| t.join } end
実際の受け入れ処理は TCPServer の @server.accept がおこなっている。ブロックに渡される s は TCPSocket である。つまりソケット。
そして running_sessions には確立したセッションのスレッドが格納されていく。
セッションを処理している process_session() を見てみる。
def process_session (socket) begin session = Session.new(@config, socket) session.start rescue Exception => e @logger.log "Unknown Session Error: #{e.class}: #{e.message}" @logger.log e.backtrace end end
Session を生成し、開始している。
Session はこう。
class Session include GetText::GetText
def initialize (config, socket) @socket = socket @config = config @command_table = [:helo, :ehlo, :noop, :quit, :rset, :rcpt, :mail, :data] @hello_host = "hello.host.invalid" @protocol = nil @peer_hostname = @socket.hostname @peer_address = @socket.address @remote_host = (@peer_hostname or @peer_address) @logger = @config.logger @catalog = @config.catalog @data_finished = false @my_hostname = if @config.port == 25 then Socket.gethostname else "localhost" end @message_charset = nil end
名前のとおり、接続ごとの処理を請け負う。
command_table に格納しているのは SMTP のコマンドである。
initialize() の次は start() である。
class Session : public def start start_time = Time.now _start elapsed = Time.now - start_time @logger.vlog "Session finished: #{elapsed} sec." end
_start() を見る。
class Session : def _start begin connect timeout(@config.timeout) { process } rescue TimeoutError @logger.vlog "Timeout: #{@remote_host}" ensure close end end
connect() して process() している。connect() を見る。
def connect def @socket.puts(*objs) objs.each {|x| begin self.print x.xchomp, "\r\n" rescue Errno::EPIPE end } end @socket.puts "220 #{@my_hostname} ESMTP QuickML" @logger.vlog "Connect: #{@remote_host}" end
ここで、def @socket.puts(*objs) することによりこのスコープでのみ @socket の puts() をオーバーライドしている。*objs は渡された引数を表す。self.print で @socket.print を呼び出している。x には渡された引数、つまり文字列 String になる。xchomp() は lib/quickml/util.rb で定義している。
class String : def xchomp self.chomp("\n").chomp("\r") end end
そしてさらに "\r\n" を追加している。つまり渡された文字列から \n \r を削除し、そのあとに \r\n を追加している。
のだと思う。
@socket がリモートから受け取った文字列に対して処理するならば分かるんだが、@socket.puts() はすぐ下の @socket.puts "220.... で使っているだけなのだろうけど、\r \n を削除するのはなぜなんだ。
2010-08-13 :-)
_ [首都圏外郭放水路見学]首都圏外郭放水路見学
行ってきた。
オレが本当に欲しかったのは明るい広角レンズだということが分かった。
F4 では暗すぎたんだ...
管理室というのはどこもそう変わらないんだなあとか
「首都圏外郭放水路 超厚水路で 歌手、声優として活躍中の水樹奈々さんの "WILD EYES" MUSIC CLIP撮影が行われました」
_ [QuickML][コードリーディング][Ruby]QuickML を読む - メーリングリストの作成と参加
メーリングリストの作成と参加の一連の処理を見てみる。
メーリングリストの作成方法はこう。
横着プログラミング 第5回: QuickML: 超お手軽なメーリングリスト
○○○@quickml.com のような任意のアドレスにいきなりメールを送るだけで、新しいメーリングリストを作成できる。たとえば宴会のメーリングリストを作るには enkai@quickml.com にメールを送ればいい。このとき、 From: と Cc: のアドレスがメーリングリストに登録される。
Subject: 宴会メーリングリスト To: enkai@quickml.com ← 作りたいMLのアドレス From: satoru@namazu.org ← 自分のアドレス Cc: masui@pitecan.com ← 参加者リスト 突然ですが、宴会好きのメーリング ← 本文 リストを作ってみました。
では先ほどの続きで、 process() を見る。
class Session : def process until @socket.closed? begin mail = Mail.new receive_mail(mail) if mail.valid? processor = Processor.new(@config, mail) processor.process end rescue TooLargeMail cleanup_connection report_too_large_mail(mail) if mail.valid? @logger.log "Too Large Mail: #{mail.from}" rescue TooLongLine cleanup_connection @logger.log "Too Long Line: #{mail.from}" end end end
Mail を生成し、mail を受け取り、processor に渡している。
Mail を見る。
Mail クラスは lib/quickml/mail.rb に定義されている。
class Mail def initialize @mail_from = nil @recipients = [] @header = [] @body = "" @charset = nil @content_type = nil @bare = nil end
メールそのものだ。
receive_mail() を見る。
lib/quickml/server.rb に戻る。
class Session : def receive_mail (mail) while line = @socket.safe_gets line.xchomp! command, arg = line.split(/\s+/, 2) command = command.downcase.intern # "HELO" => :helo if @command_table.include?(command) @logger.vlog "Command: #{line}" send(command, mail, arg) else @logger.vlog "Unknown SMTP Command: #{command} #{arg}" @socket.puts "502 Error: command not implemented" end break if command == :quit or command == :data end end
ソケットから 1 行ずつ読み取り、メールを処理する。
ここの処理は SMTP のコマンドを想像すると分かりやすい。
send(command, mail, arg)
send() はこれ。
オブジェクトのメソッド name を、引数に args を渡して呼び出し、メソッドの実行結果を返します。
つまり rcpt, data などのコマンド名をそのままメソッド名として解釈させ、受け取った SMTP コマンドごとの該当するメソッドを呼んでいる。
ML に参加する手順では、from() で参加したいひとのメールアドレス、rcpt() でメーリングリストのアドレスを処理することになる。
from() を見てみる。
def from address = if not self["From"].empty? collect_address(self["From"]).first else @mail_from end address = "unknown" if address.nil? or address.empty? normalize_address(address) end
collect_address() はこう。addresses にメールアドレスを追加していく。
def collect_address (field) address_regex = /(("?)[-0-9a-zA-Z_.+?\/]+\2@[-0-9a-zA-Z]+\.[-0-9a-zA-Z.]+)/ #/ addresses = [] parts = remove_comment_in_field(field).split(',') parts.each {|part| if (/<(.*?)>/ =~ part) or (address_regex =~ part) addresses.push(normalize_address($1)) end } addresses.uniq end
次に rcpt() を見てみる。
class Session : def rcpt (mail, arg) if mail.mail_from.nil? @socket.puts "503 Error: need MAIL command" elsif /^To:\s*<(.*)>/i =~ arg or /^To:\s*(.*)/i =~ arg address = $1 if Mail.address_of_domain?(address, @config.domain) mail.add_recipient(address) @socket.puts "250 ok" else @socket.puts "554 <#{address}>: Recipient address rejected" @logger.vlog "Unacceptable RCPT TO:<#{address}>" end else @socket.puts "501 Syntax: RCPT TO: <address>" end end
ドメインの有無チェックなどがあるが、ようするに add_recipient() してメーリングリストのメールアドレスを追加していく。
class Mail : def add_recipient (address) @recipients.push(normalize_address(address)) end
recipients にひたすら追加している。
受け取ったメールアドレスを格納していったので、次にそれを処理するための Processor を見る。Processor.process() で処理している。
ファイルは lib/quickml/core.rb
class Processor : public def process mail_log if @mail.looping? @logger.log "Looping Mail: from #{@mail.from}" return end @mail.recipients.each {|recipient| process_recipient(recipient) } end
溜め込んだメーリングリストのメールアドレス recipients を処理していく。
process_recipient() を見る。
class Processor : def process_recipient (recipient) mladdress = recipient if to_return_address?(mladdress) handler = ErrorMailHandler.new(@config, @message_charset) handler.handle(@mail) elsif @config.confirm_ml_creation and to_confirmation_address?(mladdress) validate_confirmation(mladdress) else begin @config.ml_mutex(mladdress).synchronize { ml = QuickML.new(@config, mladdress, @mail.from, @message_charset) @message_charset = (@message_charset or ml.charset) (unsubscribe(ml); return) if unsubscribe_requested? submit(ml) } rescue InvalidMLName report_invalid_mladdress(mladdress) end end end
QuickML.new() からがその処理。QuickML クラスはメーリングリストを管理する。
submit() はこう。
class Processor : def submit (ml) if ml.exclude?(@mail.from) @logger.log "Invalid From Address: #{@mail.from}" elsif ml.forward? @logger.log "Forward Address: #{ml.address}" ml.submit(@mail) elsif confirmation_required?(ml) ml.prepare_confirmation(@mail) elsif acceptable_submission?(ml) submit_article(ml) else report_rejection(ml) end end
quickmlrc で confirm_ml_creation を true にしていなければ( デフォルト False )、submit_article() が呼ばれる。
submit_article() を見てみる。
class Processor : def submit_article (ml) @unadded_addresses = [] if ml_address_in_to?(ml) add_member(ml, @mail.from) @mail.collect_cc.each {|address| add_member(ml, address) } end unless @unadded_addresses.empty? report_too_many_members(ml, @unadded_addresses) end ml.submit(@mail) end
ここで、指定したメーリングリストが新規作成される場合は ml.submit(@mail) のみが呼ばれる。メーリングリストがすでに存在しておりそのメーリングリストにメンバーを追加する場合は from で格納したメールアドレスを add_member() で登録する。
add_member() はこう。
class Processor : def add_member (ml, address) begin ml.add_member(address) rescue TooManyMembers @unadded_addresses.push(address) end end
ml.add_member() はこう。
class QuickML : def add_member (address) if exclude?(address) @logger.vlog "Excluded: #{address}" return end return if @active_members.include?(address) raise TooManyMembers if too_many_members? @former_members.delete(address) @active_members.push(address) save_member_file @logger.log "[#{@name}]: Add: #{address}" @added_members.push(address) @member_added_p = true end
メーリングリストにメールアドレスを追加などし、メーリングリストの管理用のファイルを書き込んでいる。
ml.submit() は結局これが呼ばれる。
class QuickML : def _submit (mail) inc_count save_charset remove_alertedp_file subject = Mail.rewrite_subject(mail["Subject"], @short_name, @count) body = rewrite_body(mail) header = [] mail.each_field {|key, value| k = key.downcase next if k == "subject" or k == "reply-to" header.push([key, value]) } header.push(["Subject", subject], ["Reply-To", @address], ["X-Mail-Count",@count]) header.concat(quickml_fields) Mail.send_mail(@config.smtp_host, @config.smtp_port, @logger, :mail_from => @return_address, :recipients => @active_members, :header => header, :body => body) end
メールを組み立て Mail.send_mail() を呼ぶ。
これ。特異クラスとなっている。
class << self def send_mail (smtp_host, smtp_port, logger, optional = {}) mail_from = optional[:mail_from] recipients = optional[:recipients] header = optional[:header] body = optional[:body] if optional[:recipient] raise unless optional[:recipient].kind_of?(String) recipients = [optional[:recipient]] end raise if mail_from.nil? or recipients.nil? or body.nil? or header.nil? contents = "" header.each {|field| key = field.first; value = field.last contents << "#{key}: #{value}\n" if key.kind_of?(String) } contents << "\n" contents << body begin sender = MailSender.new(smtp_host, smtp_port, true) sender.send(contents, mail_from, recipients) rescue => e logger.log "Error: Unable to send mail: #{e.class}: #{e.message}" end end
sender.send() でメール送信する。
これ。
class MailSender : def send (message, mail_from, recipients) recipients = [recipients] if recipients.kind_of?(String) s = TCPSocket.open(@smtp_host, @smtp_port) send_command(s, nil, 220) send_command(s, "EHLO #{Socket.gethostname}", 250) if @use_xverp and @xverp_available and (not mail_from.empty?) send_command(s, "MAIL FROM: <#{mail_from}> XVERP===", 250) else send_command(s, "MAIL FROM: <#{mail_from}>", 250) end recipients.each {|recipient| send_command(s, "RCPT TO: <#{recipient}>", 250) } send_command(s, "DATA", 354) message.each_line {|line| line.sub!(/\r?\n/, '') line.sub!(/^\./, "..") line << "\r\n" s.print(line) } send_command(s, ".", 250) send_command(s, "QUIT", 221) s.close end
SMTP をしゃべっている。
どうして Net::SMTP などを使わずに自力でしゃべっているのか。
ChangeLog を見てみる。
2003-01-17 Satoru Takabayashi <satoru@namazu.org> * lib/quickml/utils.rb (Net::NetPrivate::SMTPCommand): Removed. * lib/quickml/mail.rb (QuickML::Mail::send_mail): Use MailSender instead of Net::SMTP. * lib/quickml/server.rb (QuickML::Session::report_too_large_mail): Change the recipient address: @mail.envelope_from => @mail.from * lib/quickml/mail.rb (QuickML::MailSender): New class.
うーん
MailSender で use_xverp しているので....
module QuickML
class MailSender def initialize (smtp_host, smtp_port, use_xverp = false) @smtp_port = smtp_port @smtp_host = smtp_host @use_xverp = use_xverp @xverp_available = false end
XVERP 関連の処理を描き直したかったのかしら。
2010-08-14
_ 朝ッ
0900 起床
_ [コミックマーケット][コミケ]コミックマーケット78 2日目
いつものところなど。菊田裕樹さんから「がんばってくださいw」などと逆に声をかけられたり、そして細江慎治さんはぐったりしていた。
- メタファジックチャイルド
- TroubadourRedord&INSPIRE Nanosweep はもう 10 なのか...
- へっどほんトーキョー
- sound sepher / Liverne アレンジャー豪華すぎワロタ
Megalomachia のために東 4 5 6 に行ったんだが東方サークルをまったく警戒していなかった。東4 5 6 には近づくべきではなかったのだ....。
2010-08-15 :-)
_ 朝ッ
0500 起床
_ コミックマーケット78 3日目
Namiki サークルが人手不足ということでなんだかんだでサークルとして入場したのであった。せっかくだからオレは最後までつきあった。やはりコミケは楽しいのう。
- tabgraphics 桐乃ちゃんマジ桐乃
- Atelier Tiv artworks 落ちてる
- q-orbit
- steelwool こげついてる
2010-08-16 :-(
_ 朝ッ
0520 起床
_ 仕事
0830 出勤
_ ,
それが役立つというのであれば役立つのであろう。お前んなかではな。
_ ,
基調講演【瀬名秀明】ゲームの知能と小説の感覚 ヒトの宇宙の究極(?)問題を考える - CEDEC 2010 - CESA Developers Conference
パラサイトイブだけは読んだことがある。
@studio5 向け
_ RR7
TA で走ったあとに kn さんのリプレイ動画を見るとあまりにも華麗な走りに感動すら覚える。むしろ感動する。洞窟コース順走の直線の直前でトリプル溜まらない。
2010-08-17 :-(
_ ,
冷房を 30℃に設定して発動させながら寝てみた。
_ ,
家の中よりも外のほうが涼しい
_ 朝ッ
0520 起床
_ 仕事
0830 出勤
_ ルーチンワーク
携帯百景 を眺めているひとには「三輪はいつも同じような飯を作っているではないか」と思うひとが居るかもしれない( いないだろうなあ )、それは正しくて、三輪は飯を作る作業をルーチンワークにしているのでいつも同じ飯を作るハメになっている。id:kennak のように豊富なレシピを持ち合わせていればいいんだが、まあ持ってなくてもクックパッドで検索すればザクザク表示されるんだけど、その手間もなんだか面倒くさくなってしまったので、とりあえず作り方を覚えてしまった飯を作るだけの簡単なお仕事と化することによりルーチンワークにしておいた。ルーチンワーク化させて残りの時間をどうしてるのかというとまあリッジレーサー7 やってるわけですが。
_ インターネットはエロのおかげで発展した
学生のころ インターネットヒストリー を読むなどし、インターネットは技術者にとって夢の場所なのだ、インターネットは性善説でできているなど純真なポリシーを患い、そのまま社会人になったものだから、当時先輩から「インターネットはエロのおかげで発展した」という言葉を聞いて「違う! インターネットはそんな俗なものではない! インターネットはもっと高貴なものなのである! 」と食ってかかったんだが、いま思うと「まあそうかもしれない」と思える。年とったなあ
_ [NetBSD][翻訳][コアチーム]hubertf's NetBSD blog - New NetBSD Core Team announced
新しいコアチームの案内
NetBSD's core team is responsible for technical steering of the project. In the past the group was five people, and it was increased to seven people now. Read more in Alistair Crooks' announcement:
NetBSD コアチームは NetBSD プロジェクトの技術面の管理を担当する。以前は 5 名だったが、現在は 7 名に増えている。詳細を Alistair Crooks' announcement より:
We take great pleasure in announcing that the NetBSD core team, responsible for technical management within the NetBSD project, has increased its numbers to seven. This is to help in the running of a project with an ever-growing source base and developer community, and mirrors a similar change made to the board of directors, which has worked extremely well.
NetBSD プロジェクトの技術管理を担当する NetBSD コアチームが 7 名に増えた。これを告知できることをうれしく思う。NetBSD コアチームは成長し続けるソースコードと開発者コミュニティを持続させることを手助けし、ボードメンバーのようにうまく機能する。
To help with the running of the project, we have asked Antti Kantee (pooka%NetBSD.org@localhost) and Chuck Silvers (chs%NetBSD.org@localhost), and they have very kindly agreed to join the core team. Antti is well known to many both inside and outside the project, and has contributed many new and exciting ideas, the most memorable and useful of these being the rump kernel architecture. Chuck is also well-known in NetBSD circles - his work on UBC, and his recent update of the Linux emulation code are just two examples of his contributions.
NetBSD プロジェクトの持続を助けるために、Antti Kantee (pooka%NetBSD.org@localhost) と Chuck Silvers (chs%NetBSD.org@localhost) に訊ね、彼らは NetBSD コアチームに加わることを快く引き受けてくれた。Antti は NetBSD プロジェクトの内外で有名で、とてもたくさんの素晴らしくエキサイティングなアイデアを提案してくれた。もっとも印象的だったのは rump カーネルアーキテクチャだ。Chuck も NetBSD 界隈では有名で、UBC の作業と最近の Linux エミュレーションのコードの作業の 2 つは彼の貢献を表している例だ。
We therefore thank them both for their outstanding work to date, and to their joining the core team to lead and guide progress in the future.
だから我々は彼らのすぐれた活動と、今後も進路を導くためにコアチームに加わってくれたことに感謝する。
For the current core team:
現在のコアチームメンバー:
- Alistair Crooks -- agc%NetBSD.org@localhost
- Matt Green -- mrg%NetBSD.org@localhost
- Antti Kantee -- pooka%NetBSD.org@localhost
- Chuck Silvers -- chs%NetBSD.org@localhost
- Yamamoto Takashi -- yamt%NetBSD.org@localhost
- Matt Thomas -- matt%NetBSD.org@localhost
- Christos Zoulas -- christos%NetBSD.org@localhost
2010-08-19 :-(
_ 朝ッ
0520 起床
_ ,
バンドメンバー紹介時に自分を紹介し忘れるのは國府田マリ子もよくやってたなあ
_ ,
近所に家庭菜園しているオッサンを見るんだが、そのひとの家の前には「パソコン教室」という看板があり、そこを通るたびに私は「パソコン教室と言いつつこのひとはきっと超ウィザード級ハッカー(※)であり いつもどこからか私のことを『|e・)』などとウォッチしているに違いない #followme ! 」などと妄想している。今日も暑いですぬ。
2010-08-21 :-)
_ [佐渡裕][シエナウインドオーケストラ]佐渡裕指揮 シエナウインドオーケストラコンサート
@河口湖ステラシアター
ohguchi にチケットを確保してもらい、行ってきたった。車乗るぜー超乗るぜー
途中渋滞しており往路 2 時間くらいのつもりが 4 時間かかった。うどん食えなかった (>'A`)>
プレコンサートの開演時間 14:30 には間に合ったのでちんたら見る。森山良子が「この広い野原いっぱい」を歌っていた。このひとが歌ってたのかー。プレコンサートでは複数の中学校のブラスバンド部の少年少女たちが合同で演奏していた。この音楽祭の間は合宿状態になり演奏しておったそうだ。
他校のひとたちと一緒に泊まりがけで富士山麓で野外のコンサートを聞いたりするなどといったことは けいおんの連中も夏フェスに行っていたけど こういうのを見るとけいおん部の気持ちが分かるなあ。もう文化祭のノリだよね。これは楽しい。
写真など
足柄PA でインディカーなんぞ飾ってあった図
河口湖ステラシアターなのよ。
そして帰路は渋滞が無くかなりサクサク帰れた。
2010-08-22 :-)
_ 読書
2010年8月9日 - 2010年8月15日の読書メーター
読んだ本の数:1冊
読んだページ数:263ページ
機動戦士ガンダムUC(5) ラプラスの亡霊 (角川スニーカー文庫 0-105)
死亡フラグ回収しすぎ
読了日:08月13日 著者:福井 晴敏
読書メーター
_ w
暑いのでなんとなく uptime してみたら 3 users と言われて驚いたんだが
rin@hitomi[~]% uptime 12:55PM up 59 days, 18:08, 3 users, load averages: 0.04, 0.10, 0.08
screen で 3 つセッション作れば 端末が 3 つになるのだからまあそりゃそうか。そうか
rin@hitomi[~]% w 1:01PM up 59 days, 18:14, 3 users, load averages: 0.45, 0.22, 0.13 USER TTY FROM LOGIN@ IDLE WHAT rin pts/1 192.168.0.14:S.0 27Jun10 7 -/usr/pkg/bin/zsh rin pts/2 192.168.0.14:S.1 27Jun10 7 -/usr/pkg/bin/zsh rin pts/3 192.168.0.14:S.2 12:53PM 0 w
_ RR7 ARC葉月GP延期のお知らせ
PSN障害発生中らしくPSNにサインインできない状態であります。なので本日予定していたレースは延期します。新しい日程についてはまた連絡します。
PlayStation.com(Japan) - PlayStation®Network - 障害・メンテナンス情報
●“PlayStation Network”障害のお知らせ
ただいま、“PlayStation Network”(“PlayStation Store”を含む)へ繋がりにくい障害が発生しております。
調査及び復旧作業を行っておりますので、いましばらくお待ちいただけますようお願いいたします。
お客様には大変ご迷惑をおかけしておりますことをお詫び申しあげます。
【発生日時】2010年8月22日(日) 20:30 ~
【障害内容】“PlayStation Network”へのアクセスができない場合があります。
2010-08-23 :-)
2010-08-24 :-)
_ 朝ッ
0520 起床
_ 仕事
0830 出勤
_ この aptitude にはスーパー牛さんパワーなどはありません。
牛さんって?
使用方法: aptitude [-S ファイル名] [-u|-i] aptitude [オプション] <アクション> ... アクション (指定がない場合、Aptitude はインタラクティブモードで起動します): : --with(out)-recommends 推奨パッケージを強い依存関係として扱うか否かを指定しま す。 -S <ファイル名> : <ファイル名> から aptitude の拡張状態情報を読み込みます。 -u : 起動時に新しいパッケージ一覧をダウンロードします。 -i : 起動時にインストールを行います。 この aptitude にはスーパー牛さんパワーなどはありません。
_ ほげ
- ubuntu に rails をインストールしよう
- rubygems がない
- aptitude install rubygems
- gem install rails
- 302 エラーって言われた
- ググる
- つ 最新版
- ソースからインストール
- rdoc が無いって
- sudo apt-get install irb libopenssl-ruby libreadline-ruby libruby rdoc ri ruby ruby1.8-dev ( ref. ubuntuでrails環境構築~ubuntu9.10改訂版~ )
- gem install rails
- sudo aptitude install libsqlite3-dev
- sudo gem install sqlite3-ruby
- 3.6.x を使えと言われた
?('A`)
$ aptitude show libsqlite3-dev パッケージ: libsqlite3-dev 状態: インストール済み 自動的にインストールされた: はい(yes) バージョン: 3.4.2-2
(>'A`)>
_ RR7
TAでHIJACKで遊んでいたらPapoさんに招待されたのでrossoさんの部屋に入ったらカテ3だった。あいかわらず速いなあ
2010-08-25 :-(
_ 朝ッ
0520 起床
_ 仕事
0830 出勤
_ ,
あれ?三菱電機インフォメーションシステムズって
_ [訃報][RIP][今敏]今 敏 永眠のお知らせ - KON'S TONE
今敏の監督作品はこれだけ見た。
- PERFECT BLUE
- 千年女優試写会[ 20020909#p01 ]
- 東京ゴッドファーザーズ[ 20031109#p03 ]
今敏 最後の言葉 さようなら - KON'S TONE
_ PERFECT BLUE
1998 年のころ「岩男潤子と荘口彰久のスーパーアニメガヒットTOP10」というラジオ番組があって、当時は岩男潤子が誰なのかすら知らなかったんだが昔からアニメ好きだった私はこっそりと番組を聞いていた。するとなにやら「ダブルバインド THE LOOKING GLASS OF PERFECT BLUE」などといったラジオドラマが放送されており( 内容は猟奇殺人事件を扱ったものなので描写がグロイ )、さらに劇場版も公開開始され、舞台挨拶もあるという。そのことを聞いたときはまったく興味なかったので頭のスミに記憶にとどめておく程度だった。
ある日 「コンピュータ総合学園HAL」( 現在の HAL )でゲーム開発学科だかの体験入学だったか何かがあり、そのイベントに参加し( セガサターンのバーニングレンジャーをプレイしてきた )、その帰りに「そういえばパーフェクトブルーの劇場公開されてるんだったか」と思い出し、ふらふらと渋谷パルコ3 に向かった。映画チケットを購入し、そこそこの長蛇の列が出来上がっていて「まあ劇場公開 間もないころだから混んでるんだろう」と気にしてなかったんだが、中に入ったらなんと舞台挨拶が始まった。それで混んでたのか。舞台挨拶には今敏、荘口彰久、岩男潤子が出演(?)していた。何を語ったのかさっぱり覚えてないんだが、パーフェクトブルーを見たあとにブルーになったこと( 精神的な意味で )は覚えている。
_ ,
どうでもいいが 1998 年の上半期はまだ日記を書いてなかった。学生仲間とメールを頻繁にやり取りしてたはずなんだが、もはやそんなメールは消失した。
2010-08-26 :-)
2010-08-27 :-)
2010-08-28 :-)
_ もしドラ
忙しい人のための もし高校野球の女子マネージャーがドラッカーの「マネジメント」を読んだら - ハックルベリーに会いに行く
_ ,
書いてないことを読み取らないでください
_ 24hテレビ
俺が、俺達がAKB48だ
_ chrome
なんとなく Google chrome を日常生活で使おうと思ったんだが Firefox に馴染んだ指には chrome の生活を覚えるには少々面倒くさい。これが老害か
_ [リッジレーサー7]リッジレーサー7 ARC 2010 葉月GP
結果
- ANSΩB2マンタレイ 146
- Locus 145
- emotion21 140
- OWA 108
- CONTI4X 84
- knhtymh 78
- ANSΩ三嶋出雲 66
- 桜上水すずめ 62
- ちゃぶマッ 47
- のきあ 31
- agumon11 30
- ANSΩマリアナブルー 29
- ANSΩmiwarin 25
- 八雲藍 19
B2さんは最後のレースはまた回線不調により不参加。しかしそれでも 1 位になるあたりはもはやその走りは鬼神のごとく。
今回 emotion21 さん、のきあさんが初参加。emotion21 さん速いなあ。
knhtymh さん、agumon さんは途中から参加。
人数に余裕があったから KAI さん呼べたかな...
そしてマリアナさんは毎度のように回線不調。むう....
2010-08-29 :-)
_ 読書
2010年8月16日 - 2010年8月22日の読書メーター
読んだ本の数:6冊
読んだページ数:1733ページ
放課後の魔術師 (4)ワンサイド・サマーゲーム (角川スニーカー文庫)
短編集。ボードゲーム三昧だった。魔法少女ベルがかわいい。そして安芸はあいかわらず酷い朴念仁ぶりw
読了日:08月22日 著者:土屋 つかさ
緋弾のアリア〈2〉燃える銀氷(ダイヤモンドダスト) (MF文庫J)
白雪の巻。ハーレムが増えていくなあ。カンピオーネ!みたいだ。次あたりレキが加わるか?
読了日:08月19日 著者:赤松 中学
緋弾のアリア (MF文庫J)
武器などは具体的な名前が登場するのでミリオタには嬉しいかしら。描写がざっくりしてるのでサクサク読める。
読了日:08月18日 著者:赤松 中学
剣の女王と烙印の仔 5 (MF文庫J)
ミネルヴァとシルヴィアのチート的な力が明らかになり物語は収束へ向かうかと思ったらさらにアンゴーラ帝国が登場しカオス。神の力についてはスタンドくらいにありふれてるものだと思うことにした
読了日:08月17日 著者:杉井 光
剣の女王と烙印の仔〈4〉 (MF文庫J)
銀卵騎士団はなんだかんだで繋がってる。ニコロもきっと戻ってくるんだろう/カーラ先生の声は脳内で津田匠子の声で再生しておく
読了日:08月16日 著者:杉井 光
カンピオーネ! 7 斉天大聖 (集英社スーパーダッシュ文庫)
乳尻ふともも/次々と「最強」が登場するけど今後どうすんだ
読了日:08月16日 著者:丈月 城
読書メーター
_ 日笠陽子
「処女で何が悪い!」などと叫んでいたり 24h テレビのナレーションやってたり。役者はさすがだ
_ [題名のない音楽会]題名のない音楽会 マリオ・ドラクエ・FF~大人気ゲーム音楽SP を見た
たぶんそのうちここにバックナンバーができる http://www.tv-asahi.co.jp/daimei/contents/onair/100829.html
「ファイナルファンタジー」はあいかわらず 7, 8, 9 版だし( オーケストラアレンジしやすいのか? )、植松伸夫とか桜井政博がトークし、錦織健と高橋織子が歌うなどし、すごく... PRESS START でした....
すぎやまこういちによるドラクエ曲は 3 無双だった。おっさんホイホイ
2010-08-30 :-)
_ 朝ッ
0520 起床
_ 仕事
0830 出勤
_ ,
「USBのメモリ」が「ブルースリーのメモリ」に聞こえた。聴くのではない、感じるのだ。
_ 生放送
さくまあきらアワー ~帰ってきたジャンプ放送局~ - ニコニコ生放送 を見始めたあとに日記巡回したら DETUNE LIVE on USTREAM: DETUNEがお送りする、トーク&ライブ番組。出演はTrio The DS-10(佐野信義/光田康典/岡宮道生) をハッケソしたので見るなどしていた。
_ ARC 2010 総合得点
B2 無双 ARC2010 - リッジレーサー7
_ photos
contact の写真を眺めてると、私の写真はまったく味わいが無いことを実感する http://www.flickr.com/photos/miwarin/friends/
_ [題名のない音楽会]『題名のない音楽会』ゲーム音楽特集のアレ
helen さんが「感想投げるといいよ」と言っていた( 『題名のない音楽会』ゲーム音楽特集を見たレポート/ぜひ第二弾も・・・! )ので投げてみた。まあこの辺をもう少しキモくなるようにアピールしただけ。
植松伸夫もすぎやまこういちも佐渡裕もオーケストラをもっと親しみやすくしたいと考えてて、彼らが同じ舞台に立ったことは有意義だと思うなのよ (miwarin)
2010-08-31 :-)
_ [CEDEC]CEDEC 2010 - CESA Developers Conference 1日目
オープニングと基調講演は CEDEC の存在意義を確認するものだった。
オープニングスピーチ
- 和田洋一(CESA会長)
- 日本ヤバいとよく聞かれるけど日,米,欧,アジアと比較するとそれほどでもない
- でも違いはある
- ディスカッションする場があるか無いか
- 日本には無い
- 情報や知恵は自分から与えたぶんだけ返ってくる
- 「このひとに話しておけばもっと教えてくれそう」
- クリエイターは 0 から 1 を創りだす、と思われている
- そうじゃない
- まったく 0 というものはもはや無い
- 知恵の積み重ねだ
- なにを what どうやって how 作るのか
- what は自分の中にだけあるもの
- how をみんなで共有すればいい
CEDECとは? −そのもたらす価値の追求−
- 松原健二(CEDECフェロー)
「CEDEC を身近に感じてほしい」
- 元エンジニア
- 1980 - 1990
- IT 業界にいた
- ( マイクロプロセッサを作ってたということだから {N, F, T, H}か )
- 当時 日本はメインプレイヤーに成り損ねた
- もともとメインプレイヤーじゃなかったけど
- 欠けていたもの 3 つ
- 危機感の欠如
- 「日本はこれまでうまくやってきたから大丈夫!」大丈夫じゃない
- 戦略の欠如
- 全体が「トップを追え」という姿勢だった
- トップ = IBM
- みんな IBM を追いかけていた
- そんなではトップになれるわけがない
- 課題共有の欠如
- 持ってる課題はみんなだいたい同じ
- でも顕在化できてなかった
- 海外は課題共有が盛ん
- そーいうのは全部 hp から学んだ
- 危機感の欠如
- 開発者がやること
- 進化の確認
- 危機感の共有
- 進むべき方向性の確認
- 自分を高めるのは自分だけ
- CEDEC とはなんぞや
- ゲームに関わるひとたちのためのイベント
- プログラマがプログラミングスキルを上げるだけではない
- ゲームは開発者のマスターベーションではない
- ビジネスとして考えよう
- 売れなきゃ話にならない
ゲームサウンドにおける理想的なサラウンド体験提供への挑戦~技術交流の取り組み事例~
- 藤澤森茂(ヤマハ)
- 大橋紀幸(ヤマハ)
- 矢島友宏(スクウェア・エニックス)
- 土田善紀(スクウェア・エニックス)
スクウェアのひとからの「RPG の音楽は上下の音を削りまくって圧縮してるんだが FF13 を作るときにそれが不満だった、どうにか出来ないかヤマハさん」という愚痴により始まった技術交流。ソフトウェア担当とハードウェア担当のひとが実現したいことを実現するために妥協点を探す、という取り組みの紹介だった。家庭用の環境向けにチューニングしてイイ感じに出力できるアンプを作ってみました。ということで FF13 をプレイしながらその効果を紹介していた。んだが、違いがあまりよく分からなかった。
抽象化すると:
入力→処理(アンプ)→出力
こんだけっていう
Dub the future of game sound! ~ゲームサウンドの歴史と将来ビジョン~
- 田中宏和(クリーチャーズ)( 田中宏和 - Wikipedia )
- 近藤広明(Dolby Japan)
田中宏和さんに近藤広明さんがインタビューしていく、という形式で進んでいった。途中は会話が途切れそうになったりしてハラハラしたんだがそれでもやはり伝説的なひとの話題なのでけっこう盛り上がった。
田中「横井軍平からの遺言『初対面のひとと ラブテスター すること』ということなのでラブテスターやりましょう近藤さん」
- 田中宏和の歴史
- 最初は任天堂でプログラマやってた
- 音源を設計したり
- そのうち作曲するようになった
- 2000 年にクリーチャーズ作った
- よく「ゲーム音楽のひと」とか「音楽のひと」と言われるけど「サービス業」なんです
- エンターテイメント、娯楽、サービス業。そーいったことをやってるんです
- Dub
- レゲエの Dub
- 完成させずに音を 1 つ 2 つ抽出して音楽を作る(?)
- ゲーム音楽専門なわけじゃない
- ゲームがあっての音楽
- ゲームすべてを 1 人で作ってたころからの人間なので、まずゲームありきで考えている
- ネタ帳
- つねに(エンターテイメントの)ネタを考えている
- 1 曲作るために 20 曲をボツにするくらい
- パッと 1 曲だけ作れる、というわけじゃない
- 背景にたくさんの曲があり、それらを積み重ねて 1 曲を作る
- こういう姿勢を続けていきたい
- 自分が変化していないと見えないものがある
- 走ってるときの風景と止まっているときの風景が異なるように
- 自分がエンターテイメント、娯楽、サービス業をやるために自分は右往左往しておく
質疑応答
- 任天堂時代の印象的なひとは誰?
- 「宮本さん」( 宮本茂 - Wikipedia )
- とにかく徹底している
- 四六時中ゲームのことを考えている。あのひとはおかしい :-)
- 横井軍平との仕事
- 「仕事は遊び」について
- ムダと思えることでも省かなかった
- 仕事のうち 2, 3 割りはムダなことをやっていた
- でもそれがよかった
- ( デマルコの「ゆとりの法則」か )
- それが維持できてるときはうまくいっている
- BGMとSEの作り方
- BGM
- 最初にテーマを 3 つ決める。それから着手する
- 例: めざせポケモンマスター の場合
- 好きなコード進行
- 「アニソンは自分にとって初めての仕事。初めて好きになったコード進行をここで使ってみた」
- 転調
- あともう 1 つ。言葉で表現できない
- 好きなコード進行
- SE
- ユーモアを持たせる
- 場面と音楽があってる、ぐっときた音楽は?
- 初期のナムコ作品。ディグダグ等
- ゲームと音楽とのバランスが絶妙だった
- 20 歳のころ仕事始めたときの環境は印象に残るものだ
- 宮本さんも一目置いていた、と思う
- MOTHER2 の音楽ではメモリなど開発者とモメたか?
- モメてない
- 自分が偉そうにしてたので文句言われなかった :-)
- 自分は自分のイヤな部分から出来ている
- 任天堂は任天堂のイヤな部分から出来ている
- ガンコとか、強さとか。そーいうのが特徴を作る
- どうなるか分からない状況に飛び込め
- 未知のことが起きるときはチャンス
- これまでの経験がまったく役立たない状況を楽しめ
- それは岐路だ。重要な岐路に差し掛かっている
セガ社も認めた静的解析 − ゲーム開発からバグを取り除く方法
- 節政暁生(セガ)
- 内田洋一(セガ)
- 安竹由起夫(コベリティ)
PR トラックなので Coverity のひとが最初に製品紹介。そのあとにセガのひとが事例紹介。静的解析は私も以前客先でやってたんだが、お客によるとやはり最初はみんなあまり乗り気じゃなく、しかしそれでも解析しておくとそれなりに効果あったらしい。
- Coverity紹介
- よくある警告
- バッファオーバーラン
- 変数の未初期化
- 未到達コード。論理演算を誤っている
- 単純ミスはコード流用時に多い
- セガ事例
- 2006 - 2007 開発が大規模化。静的解析やろうぜ
- 携帯、自動車、組み込み業界では割りと使われている
- PSU( ファンタシースターユニバース )で実践してみた
- すでに運営してるのである程度動的解析は出来ている
- 再現性が低いバグがある
- 静的解析してみたら発見できた
- 自動化のメリット
- 人に言われるとムカつくけど機械に言われるとムカつかない :-)
- 毎日実行
- チェックチームは機能チェックに時間を割けるようになった
- 社外開発にも適用
- 最初は「面倒くさい」「ほんとに効果あんの?」と懐疑的だったが実際にやってみせると納得してもらえる
- ライブラリ、ミドルウェアにはよくバグがある
- 運用実績
- PC, Xbox360, PS3, PSP....
- アミューズメントにも使い始めた
社外事例としてファンタシースターポータブルでのアルファシステムとの開発事例。こんな感じだった。アルファシステムからセガへソースコードをコミットして、セガ社内で解析して解析結果を保存しておく。アルファシステムからセガ社内の解析結果をブラウズする。
It's a showtime!! -DISSIDIA FINAL FANTASYのAI設計-
- 下田翔大(スクウェア・エニックス)
AI と言っても学習させていくようなもんじゃなくて、条件 => アクションの組み合わせなのね( awk のように )
- AIの要件
- 短時間のバトルで特徴、味を出す
- 対 AI 戦はショーである
- FF キャラらしさを醸しだす
- 性格とスキル
- 性格
- 時間、場面ごとにアピールすることを明確にする
- 朝、昼、晩など。デートを想定してみよう
- スキル
- スキル発動の要因は単純にしておく
- いろいろな要素をからめると分かりづらくなる
- 性格とスキルをタイムラインに当てはめる
- 弱いAIはこういうアルゴリズムを適用させない
- 性格
移動(性格) ↓ 攻防(スキル) ↓ 反撃(性格) ↓ 移動(性格) ↓ 攻防(スキル)
- データとプログラム
- キャラにはデータ 4 つのみ持たせる
- 射程距離
- 避け方
- 攻撃の間合い
- あとなにか
- プログラム
- 移動の仕方は共通
- 相手のベクトルの手前に向かう
- 曲線を描く
- タイミングによってはエアダッシュ
- これによりプレイヤーと AI が様子をうかがいあうということが出来るようになった
- 人間くささを演出する
- キャラにはデータ 4 つのみ持たせる
- アルゴリズム実例
- 全体構成
- 自分と相手の HP などの組み合わせごとの行動を決める
- 基本アルゴリズムを組み合わせて行動セットを作る
- 攻撃の基本は移動して攻防するだけ
- 他はエラー、例外処理
- 反応型にはバグがあった
- 学習させることにした
- プレイヤーの攻撃を回避 or ガードの成功率によって行動させる
- バトル開始後から学習させる
- (ファイルに保存させずメモリに持つのみということか。そりゃそうか)
- 全体構成
質疑応答
- 参考にしたものは何?
- スマッシュブラザーズ
- プレイヤーキャラをまったく動かさずに AI の動きを観察するなど
- 他に参考にできるゲームがあまり無いのでみんなどんどん発表しようず
- ワークフロー
- プログラマの隣で作業
- AI の仕様( Excel で組み合わせの表を作る )をひたすら作る
- 実装
- ゲーム中での強さの設定
- ゲーム中に設定画面はあるけど、設定させるために仕様を作ったわけじゃない
- せっかくの仕様があるからプレイヤーに見せよう、ということになった
Before...
_ みわ [おお。ありがとうございます。e+の先行予約は今日からだったんですね。さっそく申し込みました。11/6のみですが ( ̄..]
_ ちくわん [LEGEND OF MANAはオヌヌメですのよ。 自由度高いから好きなように遊べます(^^]
_ みわ [自分でマップを作っていくんですねい わりとフリーシナリオの味があるのかしら]
_ ちちちくくくわわわ [なんといっても武器改造&モンスター育成ですな。 やり方によっては化け物じみた武器&モンスターになります。(^^]
_ みわ [さっぱり分からないけど「ラグナロク」「ドラゴンバスター」といった武器は生成できるとみた。]