卜部昌平のあまりreblogしないtumblrTumblr (3.0; @shyouhei)https://shyouhei.tumblr.com/んで、結局JS Girlsってキラキラしたいだけなの?<p>俺はLindaたちがなにをあそこまで思いつめてRailsGirlsを始めたか完璧には理解していない(し、そもそも「完璧な理解」って存在するのか?)が、ひとつ理解しているのは、RailsGirlsはべつにRailsやりたい女子じゃないという点だ。Railsはたまたまそのへんに転がってたからチョイスしただけ。本当のゴールは女性へのツールとコミュニティの提供を通じて、在野の女性のアイディアを実現する事にある。不勉強で日本の事情はよく知らんけど、本家はそういうことになってる。だから本当にRailsGrilsのRailsってのはウィキリークスのWikiくらいどーでもいいんですよ。今後たとえばRailsいけてなくねってことになったらRails捨ててexpress.jsなりに移っても、RailsGirlsのミッションはいささかも揺るがない。</p> <p>RailsGirlsってのはアファーマティブアクションですよ。たとえば性別逆転して「男性優先、女性は男性同伴のみの場合のみ可であるRailsBoys」とか考えてごらんなさい。だいぶ醜悪な事態じゃないですか。ということはつまり、そこにジェンダーによる構造的なギャップがある。だからこそ解消しようとするのは重要で、そのための具体的なアクションというのはあるよねってこと。ともかくもRailsGirlsが成立してる背景には女性が性別により不利益を被る構造というものがある。なきゃただの男性差別ですよ。俺はRailsGirlsに(単独では)参加資格ないけど、それはわざわざRailsGirlsに参加するまでもなくすでに俺が十分に社会から恩恵を受けているからで、だから俺なんかよりもっとRailsGirlsに参加すべき人が参加すべきという理論で、これはまったく正しい。</p> <p>大変残念ながらそのへんがJS Girlsでは後退してるように見えるんだよな。</p> <p>わりと色々調べてみたけど結局JS Girlsがなにをどうしたいのかが分からんわけです。<a href="http://jsgirls.org/events/kanazawa-201106.html">どうやら男性は困ると言われていることは分かる</a>んだけどね。じゃあ女性があつまって何したいの? キラキラしたいだけなの? というのが見えてこない。たんに盛り上がればいいの? それおらが村にも嫁さ来てくんねえかなとどうちがうんだ?</p> <p>勘違いしてほしくないのはべつにだからJS Girlsやめろとかじゃないですよ。大いにやればいいとおもう。ただちょっと今のままだと「たんに男性を排除してる」ようにしか見えないぞと。きっとダイバーシティって排除とは真逆の方向だと思うんで。もっとちゃんと広報すべきなんじゃないですか。外野からは観測できないところではそういう議論あるかもしれないけどさ。今後どういうふうにしていきたいのかっての、ちゃんと公表しといてくれたほうがいらぬ誤解を生まなくて済むよ。</p> <p>で、もしそんな深く考えてませんでしたっていうなら、Girlsとか安易に言っちゃうのはちょっと迂闊すぎると思います。</p>https://shyouhei.tumblr.com/post/81992242210https://shyouhei.tumblr.com/post/81992242210Mon, 07 Apr 2014 23:18:16 +0900http://www.homes.co.jp/cont/rent/rent_00002/ そろそろ本棚追加しないとなー、でもその...<img src="https://64.media.tumblr.com/c7dbffa3853cf4fd918f53969f6f695b/tumblr_n0fe9dbtjW1qzt98vo1_400.png"/><br/><br/><p><a href="http://www.homes.co.jp/cont/rent/rent_00002/">http://www.homes.co.jp/cont/rent/rent_00002/</a></p> <p>そろそろ本棚追加しないとなー、でもそのためにはまず家がなー、とか思って賃貸物件見てたらこのページに突き当たって怒髪天を突く勢いでもはや本棚どころじゃねえ。年収400万が最低ラインってどうなんだよ。それ以下は相手にもされないってのか。</p> <p><a href="http://doda.jp/guide/heikin/2012/age/">http://doda.jp/guide/heikin/2012/age/</a> このへんでも見やがれ。これは「額面」年収だ。だから額面400万ってのは手取りでもっと少ねえんだよ。32でも中央値額面400万とかで半数が400万行ってねえぞコラ。20代の過半数は客ですらねえってのかコラ。どうなんだよ。</p> <p>ほんとはらたつわー。これが供給側の認識なのかと思うと。日本あきらかに階級社会になってるね。お金持ちから俺らは見えてないよ。見えてない。</p>https://shyouhei.tumblr.com/post/75483866765https://shyouhei.tumblr.com/post/75483866765Tue, 04 Feb 2014 00:12:49 +0900テストのめどい話<h3>最初にめどい言い訳をせねばならぬ</h3> <ul> <li>俺は江島氏ともきょん氏とも面識はないですが、お二人ともが俺のことを知ってることを俺も知ってる程度には狭い業界であり。どちらかに肩入れしたいわけではないです。喧嘩したいわけでもないです。</li> <li>普段あまりここでは言及しないですが俺は今の仕事としてはテストを書いたりテストを実施したりする係をしてノリクチをしのいでおり、いわばテストは本業ですので、テストに言及することは今現在の同僚に対して意図しない受け取られ方をする可能性があるので困るので、それもあって普段はここではあまりテストの話はしないわけだが、だからと言って沈黙を破ってテストの話をするのが同僚に対して含みがあるというわけでもないです。</li> <li>とはいえ俺は大学等で真面目にソフトウエア工学の講義を受講したことがなく、経験と勘と昔取った杵柄だけで食ってるので、そういう意味では若干の後ろめたい気持ちもある。</li> </ul> <h3>で、テストって何なん</h3> <p>俺が現職に転職してきて一番びっくりしたのはなんといっても、俺は会社に一円たりとも入れてないのに会社からは俺の口座に何十万も給料が振り込まれてくるっていう驚愕の事実なわけですよ。なんじゃこりゃと。それまで前職では受託開発でしたからね。受託開発ってのは、人月単価だから、俺が働くことによってある程度毎月会社が儲かって、それが俺の給料の原資になるわけです(そこには入金まで数ヶ月のディレイがあるがまあそれはテクニカルな話で本質的ではない)。だから、俺の給料がなぜ払われてたかっていうと、それは俺と直接連動してお金が動いてたからや。明確ですね。でもテストはそうじゃない。俺がどんなに頑張って休日返上で働いても会社としては一銭も儲からない。じゃあなぜ俺の口座には給料が途切れることなく振り込まれているのか?</p> <p>俺は嫌でも、テストの意味と価値に関して深く静かに思いを馳せずにはいられない立場になってしまったわけです。</p> <h3>テストで腹は膨れない</h3> <p>まあつまり、テストやったから儲かるとかないわけですよ。だから、きょん氏が「テストやらない理由がどこにあるか分からない」とか書いてて、正直はあ?って思う。そんなもん食えないからに決まってるでしょ。俺は社内で常にテスト書こうよって言いつづけてて、テスト書く理由を説いてるのに、テスト書かない理由がないってのは、だいぶ別世界に思えました。またこの部分は俺ときょん氏ですら見解の相違があるのに、起業家である江島氏とおれら従業員の断絶は多分相当あるだろうと思います。</p> <p>で、じゃあ、テスト全然やんないですかっていうと、それはそれで違いますよね。テストエンジニアこのあたりを攻めるべき。なぜテスト書くのかと。</p> <h3>我々が必要としているのは止まらないソフトウエアじゃない。止まらない業務だ。</h3> <p>テストって、ものすごく巨視的な見方をすると投資なわけですよ。</p> <ul> <li>テストをすることであらかじめバグを見つけておく。運用中にバグを発見した場合の機会損失と運用コストをあらかじめ避けることができる。</li> </ul> <p>だいたいここに収斂してくるイメージがある。だから、ぶっちゃけバグがあろうがなかろうが儲かってないプロダクトをテストしてもあんま意味ないっす。前提としてprofitableなプロダクトがあり、それの運用コストを圧縮したいねってときにテストは有効。</p> <p>あとweb屋の場合はバグが出ちゃっても機会損失がまださほどでない瞬間にとっとと直すって戦略はありうるわけですよ。その点はリコールで会社が傾くような自動車の制御ソフトとかとは大いに違う。だからテストする費用対効果ってのはweb屋に限って言えば、だいぶシビアというのはその通りでしょう。</p> <p>まあ上にも書いたとおり俺はソフトウエア工学の専門教育を受けてないのでこの項目はめっちゃ外してる可能性も結構あるのだが。</p> <h3>回帰テストを書け</h3> <p>運用コストの圧縮という面でいちばん重要なのは回帰テストです。一回テスト書けば毎回有効ってことにすればコスト圧縮は積分で効いてくる。だから本来は回帰テストを書きましょうねってのが一番重要で、たぶんそこはボトムラインとしてみんなやったほうがいい。あとになるほどスルメみたいに効いてくるからね。</p> <p>だがこれが意外にねえ。ホワイトボックステストをやってると内部構造べったりに書いちゃってねえ。とくにC1カバレッジとか見だしちゃうととたんにねえ。「この分岐をこっちに通るようなテスト書かなきゃ」とかなっちゃうんだ。でもそれは本末転倒なのですよ。何と戦ってるのかわかんなくなっちゃう。これは俺もよくやってしまう失敗で、ひじょうに自戒的なのだけれど。</p> <p>そういうテスト、ばかだなって言うのは簡単だけど、そもそも完璧な人はテスト書かなくてもそもそもバグ出さないって話もある。だからテスト書くってのはばかをおのずと内包してるので、それに向かってばかって言っても虚しさしか残らんという点は指摘しておくべきかなと思います。</p> <h3>テスターは最初のユーザー</h3> <p>テストしてると「あれこのプロダクト、クソじゃね?」っていう瞬間はやっぱありますよ。はばかられるので具体例はあげないけどさ。そういうのって本当に重要で、ようするに品質って何かって話。テストやってるとよく品質保証とか言うけどさ、それで実際やってるのって仕様と実装の乖離を見てるだけってのがほとんどじゃん。悲しいことに。でもさあ、もとの仕様がクソってるのってやっぱあるですよ。そういうときクソ仕様と乖離のないクソ実装が仕上がってQA終わり!っての、違うと俺は思う。</p> <p>これようするにフィードバックの話ですけど、テストする段階まで来ちゃってるときに、これやっぱクソだわーっての声に出して言えるかどうかって大きいと思うんですよ。テスターはそのプロダクトを使う最初の人でもあるわけで。UXのおかしさとかに気付ける最初の人でもあるわけじゃないですか。そういうのきちんと拾っていければ、ただの防衛的なコスト圧縮だけじゃないテストによる価値の創出っての、ありうるんじゃないかと思います。ただのバグならエラー検知で発見できるかもしれないけど、リターンレートの低さの理由とか、そういうのですよ。離脱しちゃったユーザーに聞きようがないじゃん。</p> <p>テストは意味がないってより、俺らが使いこなせてないだけってのが実状やと思います。</p>https://shyouhei.tumblr.com/post/73195212853https://shyouhei.tumblr.com/post/73195212853Mon, 13 Jan 2014 19:27:51 +0900解題といえばおれのタイムラインにムーノーローカルの作り方流れてきたことない<p>解題といえばおれのタイムラインにムーノーローカルの作り方流れてきたことない</p>https://shyouhei.tumblr.com/post/72845094230https://shyouhei.tumblr.com/post/72845094230Fri, 10 Jan 2014 14:43:02 +0900ruby/ruby#495日本語解題<h3>三行で</h3> <ul> <li>卜部って口だけ野郎でどうせたいしたもん書けないんでしょ? <a href="https://twitter.com/ja_jp/status/73165523495555073">[1]</a> <a href="https://twitter.com/mihumi/status/418693697585168384">[2]</a></li> <li>→ 見せてやんよゴラァ</li> <li>→ <a href="https://github.com/ruby/ruby/pull/495">ごらんの有様</a></li> </ul> <p>教訓: 陰口は本人に聞こえない所で。さすがに名指しはまずい。</p> <h3>どういうパッチか</h3> <p>Rubyのオブジェクトサイズを変更(大きく)する。そのことにより第一義的にはCPUキャッシュミスヒットが削減される。副次的作用として大きくなった余剰の領域にデータを詰め込めるので中間構造体を減らしてメモリアロケーションが最適化される。それらの総合的な結果として全体に高速化する。</p> <h3>前史</h3> <p>とはいえこのアイディア、べつに最近涌いて出たものでもない。というか、俺がまだ大学院でNetBurstと戯れてたころの発想だから、かれこれ7~8年物だな。しかもこの間べつに秘密にしてたわけでもなくて、Rubyのオブジェクトって素数幅でいくなくね?ってのは、わりと口頭では折に触れて言ってたので、聞いたことがある人もいるはずかと。あ、じゃあそんなに長期にわたってなんで放置してたの、というと、1.8やってたからです。ええ。</p> <p>でもね、実はこれ7~8年前だとまだ明確な理由があってNGだった。というのも当時はまだオブジェクトってスカスカで、いろんなところに隙間があいてたの。とくにFloatはひどくて</p> <pre><code>struct RFloat { struct RBasic basic; double float_value; }; </code></pre> <p>こうですからね。後ろ側が全然使われてない。これを、今回提案のように8word幅にすると、double(64bit)一個保持するのに64バイト確保することになってしまって、本来のデータの8倍ですよ。これはさすがに無駄いと言わざるを得ない。</p> <p>この問題はささださんが<a href="http://www.atdot.net/~ko1/diary/201212.html#d10">flonumを導入した</a>ことにより解決のめどがついた。また当時問題視されていたBignum等も、後ろの余ってる所にデータが詰め込めるなら詰め込むっていうのが、主に田中さんにより実装されていて、今ではRubyのオブジェクトは、例外もある(Fileなど)が、意外に後ろの方までつまっている。このため、オブジェクトを大きくすることはそれらのつめる系のやつにとってもプラスになるはずという目論見があった。</p> <h3>実装</h3> <p><a href="https://github.com/shyouhei/ruby/commit/c558ad41ea1ff9ba8a4a9211a4504583e06da1bb">コアのコンセプト</a>はそれこそ128秒で書けた。ちゅうてもまあ、7~8年と128秒ってのが実状だけどな。でもこれでハッピーかと思うと、そでもない。なんでかちゅうとですね、俺のしらん間にRGenGCとか入ってて、なんも考えずにオブジェクトいじるとぶっ壊れるんすよ。しかもRGenGCって世代別だから、壊れ方として、ライトバリア足りてない→markおもらし→生きてるオブジェクトが回収されちゃう系の壊れ方で。これはいかんかった箇所と死ぬ箇所が全然別になって超辛い。しかも俺のしらん間に入ったがゆえにRGenGCとか俺がよくわからん。しかもドキュメントない。というのをまずソース読むという作業が必要でやばかった。</p> <p>プルリク読むと迷いもなくいっぱつがきで書いてるように見えますけど送信までにめっちゃrebaseしまくってます</p> <h3>Hash</h3> <p>オブジェクトでかくなる副作用でポインタ何個ぶんも隙間できるからハッシュの中身展開してそこに突っ込もうぜっていう話。前述のつめる系のやつと同系なのだが、これまではオブジェクトのサイズが小さかったためあまり意味がないということで実施されてこなかった。これが実はベンチマークの面ではいちばん効いてる。ようするにRubyってハッシュのアロケーションでわりと時間食ってたと。これは実際やってみて分かったことなので自分でも驚いた。</p> <h3>その他の細かいネタ</h3> <ul> <li><p>Githubはrubyの2級市民であるにもかかわらず最初にgithubに投げたのは完全に意図的。RubyにおいてはML読んでる奴はたくさんいるが、コードまで読む奴はほとんどいない。が、にもかかわらず、ごく少数のコードまで読んでくれる人は絶対いる(今回で言えばEric Wongが読んでくれた)。MLでどうでもいいPR合戦をするのはそういう本当に大切にしたいメンバーとのやりとりにとって邪魔ゆえ、あえてPRはMLの外でやるという戦略だったわけ。これはうまくいったと思う。今のところMLは密度の濃い議論ができている。</p></li> <li><p>Valgrindでヒーププロファイルとれるじゃんと思ったところまでは正しかったが取るだけ取ったものを出力する方法がないのは閉口した。スクリーンショットしかないというのはいかがなものか。</p></li> <li><p>Haswellの真の実力を解き放つ設定が分からず苦労した。定格1.8GHzでturbo boost時3.0GHz(1.6倍!)のはずなのだがi7zで見ても常に定格っぽく…… 結局それは<a href="https://github.com/torvalds/linux/blob/master/drivers/platform/x86/sony-laptop.c#L2068">ACPI経由でコマンド叩き込まんと開放されない</a>ということのようだった。</p></li> </ul>https://shyouhei.tumblr.com/post/72765924962https://shyouhei.tumblr.com/post/72765924962Thu, 09 Jan 2014 23:13:51 +0900VAIO Pro 11買った。 周囲の少なくない割合のVAIO...<img src="https://64.media.tumblr.com/5de3c759e03d9af8998736de6a392ea4/tumblr_mx4trrlDhc1qzt98vo1_500.jpg"/><br/><br/><p>VAIO Pro 11買った。</p> <p>周囲の少なくない割合のVAIO Xオーナーが雪崩をうって買いに走ってるのをみてそうなんだろうなーとは思ってたものの、まあ、Sonyですからね。半年くらいは様子見るのは当然ですよね。</p> <h3>使用感など</h3> <p>とりあえずわくわくしながら電源入れて、次に口をついて出た台詞が「<strong>死ねよ</strong>」だったことは特筆しておいても良いのではないかと思いました。いや、だって、本当に電源切る方法がまったく分からないんだもん。電源ボタン押すと電源入るでしょ? なのにそこからもう一回電源ボタン押しても切れないんだよ。あほかと。省電力だからって言ってウォシュレットが一回始めたら水止まんないとしたらどう思います? そういう基本的な、本当に基本的なことですよこれは。結局ぐぐって解決したけど、電源の切り方っていう紙っぺら一枚添付してくれてもいいんじゃないの? そういうのこそ「デザイン」なんじゃないのかね? まあSonyが悪いことなのかは分かりませんけど、ファーストインプレッションは最悪から数えた方が近いとおもいます。</p> <p>あとね、MBAと比べてこんな微妙に幅が違うわけですけど、<br/> <img src="https://64.media.tumblr.com/d573e7220860d50caf141df401d09aee/tumblr_inline_mx4wvdqNLe1qzt7z1.jpg" alt=""/><br/> わざわざこれだけ横幅削ってまでキーボードピッチを狭くした理由が一切理解できない。なんなの? マゾですか? 誰も喜んでないでしょこれ。もっと何センチも削れるならキーピッチ狭いのもやむなしだけど、これだけじゃあ意味ないよ。幅をMBAと同じまで広げて普通のフルピッチのキーボードを載せなさいよ。わざわざ使い辛くしてどうするの。</p> <h3>よかったさがし</h3> <ul> <li>液晶は綺麗ですね。これは毎回思う。他社は本当にもっときれいな発色のパネルを使うべきです。このパネルは最大輝度だと個人的にはちょっとまぶしすぎるのだけど、そこから輝度を落としていったときの黒とか白とかのへんがとても違和感なく暗くなっていくのは、とても気味が良いです。</li> <li>予想に反してUbuntu 13.10一切何の抵抗もないままに最初のトライで入ってしまった。拍子抜けです。まあその後Ubuntu固有のクソiBus問題とか色々あるのでこれはこれでクソなのだが、それこそマシンと関係ない話で。</li> <li>Haswellよいですね。速くなった感じは一切しないが消費電力はpowertop(1)で見てても明らかに低くて。逆に言うと低消費電力のわりには速さに不満を感じませんね。</li> <li>個人的にはUSB3.0のUSBメモリで速いやつと遅いやつって、言うほど速さ変わんないなーって思ってたけど、マシン変えたらこのマシンでは結構速いって売ってたUSBメモリは速かったというのは印象深かったっす。</li> <li>あとまあ、やっぱ軽いのは正義ですね。</li> </ul> <h3>これから買う人へ</h3> <p>このびっくりするほどぺらいキーボード(まあXもそうでしたよ)からも分かるとおり、Sonyという会社に頑丈さを求めてはいけません。ThinkPadやLetsNoteと同じ使い方をするとものすごい勢いで物理的にぶっ壊れることが容易に想像できますので、他の何をおいても一切漏れなく絶対買うべきなのは「延長保証」です。それも破損をカバーしてるやつです。金額的に、一年で捨てても構わないって人は少ないはずです。そこをけちらないように。</p> <p>あとこのマシンは壊れるとなるとハードウエアですから、いったん修理に出すとしばらく返ってこないことが容易に想像できる。常にサブマシンを用意しましょう。安いやつでいいです。そしていつ修理に出しても言いように毎日のバックアップを欠かさないようにしましょう。だいたい一年あたり2週間くらいは修理に出ているかも知れませんよ。しかもそれが何年も続くかも知れませんよ。いや、そうならないことを祈るばかりではあるのですが…</p>https://shyouhei.tumblr.com/post/68737335507https://shyouhei.tumblr.com/post/68737335507Mon, 02 Dec 2013 11:21:41 +0900前回の続き。 前回の時点では「git...<img src="https://64.media.tumblr.com/44389c888b1aa094c9e295a77b0e054d/tumblr_mwegruHfib1qzt98vo1_500.png"/><br/><br/><p><a href="http://shyouhei.tumblr.com/post/51945063131">前回</a>の続き。</p> <p>前回の時点では「<code>git blame</code>が密になっているところはきっと活発に編集されていたに違いない」という仮説があったわけですが、これは本当のところは、よくわからない。なぜかというと、blameというのは地層のように降り積もったコミットの表面に露頭してるところしか見せてくれないわけです。本当に活発に更新されていたかを知るには、ようするに地質平面図じゃなくて地質断面図が必要なわけ。分かりますよね。</p> <p>で、それはどうやって作ればいいかというと、gitには便利な<code>git log -p</code>という、こういうとき便利だけど普段は使い道のなさそーなコマンドがあって、これは生のdiffをすべてだらだらと表示してくれるわけですよ。で、diffからblameを再構成するにはdiffの<code>+</code>行をひたすら集めてくればいいわけだけど、その時<code>-</code>行も一緒に覚えておいて、あるコミットでどのコミットが上書きされたかを覚えておくことができる。そのようにすると、<a href="https://gist.github.com/shyouhei/7507424">blameっぽいけど地層の底の方を見通すことができるコマンド</a>というものが作成できる。</p> <p>たとえばこういう出力が得られます:</p> <script src="https://gist.github.com/shyouhei/7507489.js"></script> <p>いかにも更新頻度の高そうな行がどのへんかがちゃんと可視化されているのが分かりますね。</p> <p>で、これだけでも結構興味深くて、たとえばeval.cで結局どこが一番ホットな箇所だったかといえばすばり<a href="https://github.com/ruby/ruby/blob/ruby_1_8_7/eval.c#L5035-L5059">ここ</a>ということがわかって、これはとても納得感が高い。つまり、作ってる我々からしてみても「ここは大変だった」と思える箇所なわけで、けっこうな妥当性があるんじゃないかと思いますね。なのでこれはこれで便利に使えるツールに仕上がるのではないかという気がする。</p> <p>ただまあ、やっぱ図にしてみたいですよね。前回同様に。で、やってみるとこうなる。明るいほど高頻度の編集です<img src="https://64.media.tumblr.com/4756df11ba29feb91b1c62a67e9008c0/tumblr_inline_mweghiegEc1qzt7z1.png" alt=""/></p> <p>これ、ぱっと見で画像が暗いと感じると思うのですが、ヒストグラムがひじょうに興味深くて、全体の50パーセンタイルが一回しか更新されてないのですよ。二回以下だと76パーセンタイル。まあこれだけで絵づらは決まったようなもんです。</p> <p>なので実はrubyの実装においては実は、だいたい半分はいっぱつ書きで動いてるといえる。もちろん、コメントとかも含んでるから、実際はもう少し精査しないといけないだろうけれど、それでもかなり予想より多いですね。びっくりです。</p> <p>逆に言うと、八回以上も編集してる箇所が1パーセンタイル弱くらいあるわけですけども、これはあやしいー。明らかに他と傾向が違うので、こういった部分では何かまずいことが起きていたのではないか? ということが推察されるわけです。たとえば上でも例にあげたeval.cの一番熱かった部分などは、これは二転三転した部分でとても困難だった。他にもそういう所があったのではないか? と思われるわけです。これを利用することで、更新頻度からのバグ探しといったことも可能ではないかと思わせますね。</p>https://shyouhei.tumblr.com/post/67314913322https://shyouhei.tumblr.com/post/67314913322Mon, 18 Nov 2013 09:38:00 +0900'10年代のRubyコア用語集<p>ゼロ年代のやつはマヨネーズ色の本に書いてあるよ。</p> <h3>あ</h3> <ul> <li><p><strong>IRC</strong> (あいあーるしー) 「教養チャンネル」とも「衒学チャンネル」とも呼ばれる。ほとんどのタイミングで日本史か中欧史か仏教史か英語史の話をしている。たまにRubyの話題になると逆に違和感が…</p></li> <li><p><strong>ISeq</strong> (あいせく) <code>RubyVM::InstructionSequence</code> のこと。長いので誰も正式名称で呼ぼうとしない。</p> <p>rubyスクリプトのいくつかある表現型の中でもっとも低レベルな表現。現在、rubyスクリプトからISeqを生成する機能は公開されているが、そのようにして生成したISeqを実行する機能はセキュリティ上の懸念から(作られてはいるが)封印されている。→ AST</p></li> <li><p><strong>ID</strong> (あいでぃー) 型。rubyレベルでいうSymbolにほぼ相当するもの(ちょっとだけ違う)。objcプログラマーはこれを見てVALUEと混乱しないように。</p></li> <li><p><strong>assn</strong> (あさしん) IRCで彼らがアサシンと呼んでいるものは暗殺者のことではなくアソシエーションの略なので、びっくりしないこと。たまにジャーゴンであることを忘れてIRCの外でも使ってしまい、通じなくて恥をかく。</p></li> <li><p><strong>Qundef</strong> (あんでふ) Qは黙字。実装上はQtrue, Qfalse, Qnilと並ぶruby第4の即値定数だが、実装詳細として頑なに表舞台に出てくることを拒んでいるため、rubyスクリプトから見かけることは非常にまれであり、見かけたときにはほぼ間違いなくバグなので、バグ報告しよう。</p></li> <li><p><strong>Emacs</strong> (いーまくす) 過去のある時点においてrubyはEmacs Lispでどこまで変態な文法が処理できるかの挑戦として作られたという事実がある<a href="http://www.slideshare.net/yukihiro_matz/how-emacs-changed-my-life">[1]</a>。現在でもEmacs上では正しくシンタックスハイライトされるが他のエディターではされない、というケースはまま見受けられる(特にネストしたヒアドキュメントが鬼門)。rubyのへんな文法はたいていEmacsのせいと思ってよい。</p></li> <li><p><strong>1.8</strong> (いってんはち) 輝かしい先駆者にして現在まで落とす影も大きい。なお現在のrubyに対する1.8に相当するポジションとして、1.8にはPerlという存在があった。</p></li> <li><p><strong>iter</strong> (いてれーたー) rubyが出たばかりのころこんな機能がある言語はかなりマイナーなものに限られていたが、今となってはC++ですらラムダリテラル構文がある。rubyのようなイテレーターというアイディアは十分に業界に浸透したといえるだろう。必ずしもrubyだけの功績ではないとは思うが、まったくrubyと無関係ってこともないはずだ。</p></li> <li><p><strong>Windows</strong> (ういんどうず) てか実のところWindows専用アプリでもないにも関わらずこれほど力を入れてWindows対応がなされているものって、なかなか見ないよ。本当に。頭が下がります。ただ、ユーザー定義したライブラリとかで対応が残念な事があって、そのため結局総体としては残念なことになってしまうって場合はまま見受けられるので、その点残念。</p></li> <li><p><strong>英語</strong> (えいご) われらの共通語。</p></li> <li><p><strong>Encoding</strong> (えんこーでぃんぐ) 抽象概念「文字」の抽象的な「列」である「文字列」を具象としてビットパターンに落とし込むための符号化方式、にrubyが名前をつけたもの。rubyではそのような符号化を一意に定めず、文字列ごとにそれぞれ別の符号化であることを許容している。こういうのをCSIというそうだ。</p> <p>なおASCIIという符号化方式との間にある種の互換性がないような符号化はrubyでは二級市民として差別されている。</p></li> <li><p><strong>configure.in</strong> (おーとこんふ) 「「「移植性を確認するプログラム&copy;」を生成するプログラム(sh)」を生成するプログラム(M4)」という、少々常軌を逸した営み。あるいは穢れを一身に引き受けてプロジェクトの他の部分を清く保ってくれているとも言える。</p></li> <li><p><strong>Makefile.am</strong> (おーとめーく) rubyにはない。理由はautomakeが生成したMakefileがgmake依存だから。逆にいうと、rubyのMakefile.inは驚くべきことに、gmakeにもbmakeにもnmakeにも有効なとてもポータプルなものである。</p></li> <li><p><strong>PoLS</strong> (おどろきさいしょうげんそく) Principle of Least Surprise, 驚き最小の原則。一時期よく設計方針として言及されていたが、あまりに誰も彼もが安易に使ってしまったので現在は嫌われている。少なくとも「誰にとっての驚きか?」という部分の曖昧さが指摘されている。</p></li> <li><p><strong>objspace</strong> (おぶじぇくとすぺーす) → heap</p></li> </ul> <h3>か</h3> <ul> <li><p><strong>拡張ライブラリー</strong> (かくちょう -) なんだかんだでrubyの設計者はCプログラマーだったということである。現在のrubyはCで拡張ライブラリーを書くことが容易になることを主眼として設計されている。主眼、である。Cさえ諦めればおよそありとあらゆる部分がより速く、あるいはよりシンプルに、再設計できる。しかしそうはなっていない。少々の速度よりも「Cで拡張ライブラリーを書くこと」のほうを優先しているからだ。</p></li> <li><p><strong>型</strong> (かた) rubyでは変数には型がないが値に型がある。一方、Cでは変数に型があるが値には型がない。Javaでは変数にも型があるし値にも型がある(しかも一致するとは限らない)。このように言語によって型の性質が異なるため、一般的に言って型とは何か、というのは突き詰めると難しい問題を孕んでいる。rubyにおいては、値が型を持つ、というところまではだいたい合意が取れている。が、具体的にそれは何か? というのは議論が分かれる。メジャーな意見としては「それはクラスだ」というものと、「それはダックタイプだ」というものがある。</p></li> <li><p><strong>完全言語の探求</strong> (かんぜんげんご - たんきゅう) 必読書。→ バベル17</p></li> <li><p><strong>企業</strong> (きぎょう) コミッター数ではNaCl (matz shugo gotoyuzo nari takaokouji)が、コミット数ではHeroku (matz nobu ko1 ayumin)が、他より頭一つ抜き出ている。</p></li> <li><p><strong>Git</strong> (ぎっと) 正直、</p> <ul> <li>信者うざい</li> <li>Subversionで困ってない</li> <li>Windows対応がひどい</li> </ul> <p>といったところ。</p></li> <li><p><strong>基本ブロック</strong> (きほん -) 途中で分岐がないような一連のプログラム素片。途中で、というのは、最初と最後にあってもよいという意味であり、通常は基本ブロックといえば最初に他の基本ブロックからの条件分岐で入ってきて、一本道でいくつか処理をして、最後に条件分岐かreturnで他の基本ブロックへと抜けていくような構造である。大きなプログラムを複数の基本ブロックに分割してからそれら同士の関係を有向グラフとして処理するのがプログラミング言語処理の常套手段だ。</p> <p>ところがrubyでは事情が異なる。例外があるからだ。つまり例外が起こるような任意の場所は基本ブロックの途中には出現できない。この制限は思いのほか強く、メソッド呼び出しなどほとんどの操作は例外を発生しうるので、rubyにおいては基本ブロックというのはたいてい単一の操作しか含まないようにしかできない。</p></li> <li><p><strong>クズポイント</strong> (くずぽいんと) コミッターに付くポイント。計算方法はバグ管理上、何件のバグがその人にアサインされているか。多い方がよい(その人の責任を表す)という意見と少ない方がよい(その人の几帳面さを表す)という意見がある。</p></li> <li><p><strong>Quine</strong> (くわいん) 自己複製プログラム、つまり自分自身を出力するプログラム。ある種のパズルとしてGolfなどと似た要素がある。が、rubyのQuineは短く書こうと思うとすごく短いやつでも書けてしまうのであんまり面白くない。どちらかというと字面の面白さなどを狙う方がよく見かける。</p></li> <li><p><strong>計算量</strong> (けいさんりょう) Rubyistならずともプログラマーであればプログラムの書き方とかより先に最低限理解しておくべきもの。有り体に言えば「スケーラビリティー」をもうすこし学術的に厳密にしたような概念であり、厳密な部分をさておくとすれば(しないほうがよいが)、概論を追うのは本当に容易だ。にもかかわらず今年も多くのプログラマーが計算量を理解しないまま実践に投入されてゆく。嘆かわしい限りである。</p></li> <li><p><strong>言語</strong> (げんご) 自然言語とか人工言語とかそういう分類を越えたところに言語の面白さはある、と思う。</p></li> <li><p><strong>コミッターに必要なもの</strong> (- ひつよう -) rubyコミッターなんて</p> <ul> <li>神聖ローマ皇帝をシャルルマーニュからフランツII世まで順にそらんじることができなくてもなれるし</li> <li>ヘイムスクリングラやベオウルフを読んだことがなくてもなれるし</li> <li>EsperantoやfrançaisやKiswahiliやΚοινὴやLatinaやLogibanや文言文やसंस्कृतम्が読めなくてもなれるし</li> <li>amd64やia64やmips64やppc64やsparc64のアセンブラーが読めなくてもなれるし</li> <li>pthread_cond_timedwait(3posix)のRATIONALEを読んでなくてもなれるし</li> <li>LALR(1)パーザーを手書きできなくてもなれるし</li> <li>application/x-www-form-urlencodedを目で見てデコード後のエンコーディングを推定できなくてもなれるし</li> </ul> <p>なんだ、簡単じゃん。</p> <p>もう少し真面目に言うと、rubyコミッターになるには、そりゃ、持ってたほうがいいスキルはたくさんあるけど、最低限必要なのは、</p> <ul> <li>rubyコミッターになる理由</li> </ul> <p>これだけですよ。マジで。</p></li> <li><p><strong>Golf</strong> (ごるふ) コードゴルフとも。少ない打鍵数でプログラムを書くパズル。愛好家はゴルファーと呼ばれる。rubyにはゴルフ用ruby実装gorubyがついてくるように、ゴルフとの親和性は高めである。</p></li> </ul> <h3>さ</h3> <ul> <li><p><strong>3PI</strong> (さーどぱーてぃーいしゅー) 3PIと書いてあっても3×πで9.5くらいか?と思うと全然関係なくて、3rd Party&rsquo;s Issue == だれか他の人が怪しいよ、ということ。あるいはライブラリーのユーザーからのバグ報告に対して、「まずライブラリー作者にライブラリーが悪いかどうかを切り分けてもらってください」といったニュアンスのもとに発効される場合もある。</p></li> <li><p><strong>サピア・ウォーフの仮説</strong> (- かせつ) 人間はものを考える時に使ってる言語にひっぱられて考え自体が変わってしまうんだよ(大意)、という仮説。仮説というくらいだから何ら証明されたものではないが、SFの世界ではもはや真説を通り越して定説に近く、この説を採用する例はオーウェル「1984」を嚆矢として、ディレイニー「バベル17」、チャン「あなたの人生の物語」、伊藤「虐殺器官」など枚挙にいとまがない。</p> <p>もちろんrubyに関係する人物はもれなくこの仮説を篤く信奉している。</p></li> <li><p><strong>GC</strong> (じーしー) Garbage Collection. まあ今時あるのが普通。rubyのものは非compaction非copying非exact非generational非parallel型と分類できるGCで、この非○○という部分を回避できれば勇者。ただし現在のアルゴリズムはそれなりの経緯でこのチョイスになっているわけで、そう簡単に変えられるわけではない。</p></li> <li><p><strong>.gdbinit</strong> (じーでぃーびーいにっと) rubyのソースコードに付いてくる。使うとrubyのデバッグがしやすくなる。</p></li> <li><p><strong>GVL</strong> (じーぶいえる) GILとも。Global VM Lock。嫌われもの。だがパフォーマンスを犠牲にしつつもみんなを[BUG]から守ってくれてるんだぞ。もっと感謝すべきだ。</p></li> <li><p><strong>signal</strong> (しぐなる) どこからかやってくるなにか。ただし問題はどこから、ではない。どこにくるかと、いつくるかだ。シグナルはこの2点に関して非常に困った特徴を備えている。また、それは考えなしに設計したから困ったのではなくて、どちらかというと人類の智慧では現状が限界、といった趣き。</p> <p>なおrubyにおける実装方針は参考になると思われるので解説しておく。signalには付随するhandlerとmaskという資源があり、ハンドラはプロセス固有でマスクはスレッド固有だ。そこでrubyではほぼすべてのスレッドはすべてのシグナルをマスクしており、シグナルを受け付けるスレッドを同時にたかだか一つに制限している。このスレッドのことをシグナルスレッドと呼び、専用スレッドだった時期もあればメインスレッドが兼務していた時期もある。さらにハンドラはタイミングの問題があるので、来たことを記録するだけのとても簡素なものになっている。シグナル固有の複雑な処理はあとでゆっくり行われる。これはカーネルにおける割り込みの処理(upper half/bottom half)などと似ているとも言える。</p></li> <li><p><strong>仕様</strong> (しよう) 仕様とは何か? 近年rubyはISO化の経緯から仕様に対する理解が進んだ。</p> <ol> <li>まず de jeur standard としての仕様がある。ISO30170 / JISX3017 が該当する。</li> <li>次に de facto standard としての仕様があり、これは現在であれば rubyspec などがある。rubyの実際の実装もこれに含む。</li> <li>そして最後に、みんなの心の中にある「こうなってたらいいなー」の総体としてのrubyのあるべき姿、とでもいうべきものがある。これを漠然と仕様と呼ぶことがある。</li> </ol> <p>1と3が同じならよかったのかもしれないが、現実には異なるので、得体の知れない3ベースで会話が進むことがあり、気が抜けない。しかし3がないと2のバグが発見できないのでまったくなくすのも無理である。</p></li> <li><p><strong>真偽</strong> (しんぎ) 何をもって真とするかは大別して</p> <ul> <li>真の値trueと偽の値falseがある。それ以外はそのどちらかに変換してから真偽判定する</li> <li>偽の値falseがある。それ以外は全部真</li> </ul> <p>というパターンが多いが、rubyはそのどちらでもない、少々珍しい判定方式である。</p></li> <li><p><strong>Symbol</strong> (しんぼる) 文字列のような見た目をしているが実態はどちらかというと整数である。そもそも1.6くらいまでSymbolクラスは存在しなかったし、Symbolを文字列っぽくしようという過去の試みは失敗に終わった。Symbolという概念がLispから由来していることに疑いの余地はないが、じゃあLispのSymbolは何が由来なのかというのは、rubyistたちの間ではすでに失伝してしまっており、よくわかない。人工知能だからシニフィアンとかシニフィエとかあのへんと関係あるのかなー、と漠然と思う。</p></li> <li><p><strong>人狼BBS</strong> (じんろうびーびーえす) 説得ゲーム。他の人狼系ゲームと違ってロールプレイは程々でみんなガチ勝利を目指している点が特異である。ruby界隈に経験者多し。rubyにおけるSFと並ぶ二大基礎教養と思われる。</p> <p>人狼BBSは日本語専用なので当然海外ではそのものは行われないが、それでも海外rubyistにおいても人狼系ゲーム熱は熱い。RubyConfなどで夜中に集まって車座でオフライン人狼をやる集団が目撃されている。</p></li> <li><p><strong>ZSUPER</strong> (ずーぱー) ほとんどすべての局面でrubyにおける括弧は演算子優先順位などの統語論には影響するが意味論には影響を与えない。ところが唯一、superにおいては、 <code>super()</code> と <code>(super)</code> では意味が異なる。このような例は他にはない。この、後者のsuperの用法から出来上がってくる意味論のことをZSUPERと呼ぶ。</p></li> <li><p><strong>スタック</strong> (-) 普通の言語と違ってrubyは実行時コンテクストにおけるスタックが一本ではない。RHGでは七本がリストアップされており、その後実装の変遷にともない本数は上下している、というか誰も把握していない。</p></li> <li><p><strong>正規表現</strong> (せいいひょうげん) rubyの正規表現エンジンは現在のものになるよりも前からずっとNFAとよばれる種類のものである。このクラスのエンジンは正規表現の書き方によっては指数時間計算量で走る。そのため正規表現が(人間が生きてる間には)止まらない、という現象が起こりうるが、これは正規表現の書き方が悪いのである。ちなみにrubyの場合のようなバックトラックがあるNFAエンジンはNP完全なので、計算量を本質的に下げる方策はない、と多くの専門家が信じている。あと、正規表現を実行する前にわるい正規表現かどうかチェックすればいいじゃないか、という発想は、チューリングマシーン停止問題なので、輪をかけて難しい。眼力によるデバッグしかない。</p></li> <li><p><strong>select</strong> (せれくと) システムコール。あまりに使い方が難しいためLinuxでは <code>select(2)</code> のマニュアル自身に加えて <code>select_tut(2)</code> というチュートリアルが別途用意されているほどである。なおPerlのselectはシステムコールのselectの機能の他に出力を選ぶ機能もついていて輪をかけてイミフ。</p> <p>Rubyにおいてはファイルディスクリプタは「読み込めるようになるまで読み込まない」「書き込めるようになるまで書き込まない」という方針である。なんでかというと読み込めないのに読み込もうとするとブロックするからだ。そしてブロックしてほしくない。このため、読み込めるかや書き込めるかの確認のために(UNIXにおいては)selectが使われている。</p></li> <li><p><strong>即値</strong> (そくち) いまいち定義が怪しいリテラルに比べて、即値に関してはいわゆるVALUE埋め込みオブジェクト、すなわち TrueClass FalseClass NilClass Fixnum Symbol のインスタンスということでおおむね衆目が一致している。</p></li> </ul> <h3>た</h3> <ul> <li><p><strong>大クラス主義</strong> (だい - しゅぎ) rubyのクラス階層に関してしばしばこのように形容される。たとえばデータ構造のスタックとキューと配列は、それぞれ別とすることにもそれなりの妥当性があり、実際にC++などそのように分かれているが、rubyでは全部ひとまとめにしてArrayクラスだ。</p></li> <li><p><strong>タイマースレッド</strong> (-) rubyにはGVLがある。ではそのロックはいつ開放するのか、というと、タイマーで定期的に開放させるということになる。そのためのタイマーが動いているスレッドがタイマースレッド。OSレベルのスレッドであり、rubyスクリプトからは観測することができない、はずなのだが、ときどき影響が出ることがある。たとえばちょっと前のNetBSDでforkできなかったりとか、こいつのせい。</p></li> <li><p><strong>tagged pointer</strong> (たぐどぽいんたー) ポインターと同じサイズで、かつ、そのメンバーうちの少なくとも一種類はポインター型であるような共用体のこと。中身がポインターかどうかを判定するのにタグとよばれるビットを使うことからこの名前がある。rubyの場合( → VALUE)、LSBがタグであり、これが立っているものはポインターではない。</p></li> <li><p><strong>多言語</strong> (たげんご) 難しいものの代表。難しくした犯人はバビロニア人。</p></li> <li><p><strong>他言語</strong> (たげんご) Rubyistは意外に他言語について詳しい。単にそういうの好きな人達だからというのもあるだろうが、やはり他山の石として他言語にあるバグrubyにもないかとか他言語の新機能がrubyにも適用できないかとか研究すべき部分が多いということと、あわよくば他言語にてrubyを実装できないかと虎視眈々と伺っているからでもある。ただし最後の意味ではJVM系の言語はすでにJRubyがあるため、あまり興味を引かないようだ。</p> <p>執筆時点では特にD言語およびGHCによるruby処理系に期待が高まる。</p></li> <li><p><strong>多値</strong> (たち) 様々なモデルが提唱されたが結局どうなったんだろう。</p></li> <li><p><strong>deoptimization</strong> (だつさいてきか) プログラムを最適化する際に、最適化しやすい便利な夢(たとえばプログラムの途中でメソッドの再定義は起きない、とか)を見ながら最適化する、と、最適化しやすい夢なんだから当然最適化が効く。で、その夢から醒めるような事態が発生した時に、やおら正気に戻って真面目に再計算しなおせば、その再計算はペナルティとしても、とりあえず夢が見つづけられている間は幸せなんじゃないの、という戦略。あるいは、概ねのプログラムは夢から醒めるような変な事はしないからだいたい幸せなんだけど、万が一そうじゃないときにも一応遅いながらもちゃんと動きますよ、とも言える。この「遅いながらもちゃんと動きます」のことを脱最適化という。</p></li> <li><p><strong>Akrの^C原則</strong> (たなかさんのしゅみ) ユーザーがCtrlキーとCキーを同時押しした瞬間にフォアグラウンドなプロセスは可及的速やかに死ね(大意)、というルール。これを達成するため、rubyではすべての操作は^Cに関係なく可及的速やかに処理が終了するか、そうでなければ^Cで中断可能であるように設計されている。</p> <p>しかしこれはかなり厳しい条件であり、たとえばrubyの場合Mutexがブロックしているのであっても^Cで中断できる。つまり、Mutexをlockしようとした際にlockの呼び出しが戻ってきても、必ずしもロックが取れているとは限らないということである。これは強烈。こんな特性のMutexは他の言語にはない。</p></li> <li><p><strong>AST</strong> (ちゅうしょうこうぶんぎ) Abstract Syntax Tree, 抽象構文木。 rubyスクリプトを意味を保ちつつ、構造体が複数連なった形式に変換したもの。構文木というくらいだから木の形をしている。1.8まではこれを直に解釈していた。現在はASTからさらにISeqへと変換する。</p></li> <li><p><strong>定数</strong> (ていすう) rubyには定数と呼ばれるものはあるが、少々警告が出る程度で何事もなく再代入できるのであり、まったく定数としての責務を果たそうとしていない。しかも逆に普通のローカル変数のような見た目をしているのにどう頑張っても再代入できない変数、などというものもrubyには存在する。rubyはいいかげんだ、とみなすか、そんなのでもそれっぽく運用できているあたり人間の方がいいかげんだ、とみなすか。</p></li> <li><p><strong>独語</strong> (どいつご) Eigenclassなどの用語からrubyコミッターはみんな独語が読めるかのような錯覚を受けるが、実はそうでもない。ただ独語圏内から無活用独語とでもいうしかないような謎の英文(現地ではそういうのを <em>Denglisch</em> と呼ぶらしいぞ)でバグレポートが来ることはたまぁーにある。</p></li> <li><p><strong>特異クラス</strong> (とくい -) rubyではあらゆるすべてのオブジェクトは通常の意味のクラスの他に、そのオブジェクトだけをインスタンスとするようなクラスを持ち得て、これを特異クラスと呼ぶ。ところでrubyではクラスもオブジェクトである。だから特異クラスもオブジェクトだ。すなわち特異クラスにもクラスがあり、また特異クラスの特異クラスがある。特異クラスの特異クラスもクラスだから、以下無限に続く。</p></li> <li><p><strong>TravisCI</strong> (とらびすしーあい) 最近、rubyでも使ってるCIツール。githubと連携してくれるので便利。</p></li> </ul> <h3>な</h3> <ul> <li><p><strong>名前</strong> (なまえ) 名前重要といいつつrubyの場合は実は実装上ローカル変数は配列で管理されているのであまりたくさん(数十万個とか)名前があると変数の検索に時間をとられてパフォーマンスが悪化する。なにごともやりすぎはよくない。</p></li> <li><p><strong>native thread</strong> (ネイティブスレッド) ふつうのスレッド。nativeとわざわざ言うからにはnon-nativeなスレッドも当然存在する。それのことをgreen threadと呼んだりする。</p></li> <li><p><strong>NODE</strong> (のーど) データ構造。ASTのメモリ上の表現である。オブジェクト (→ RVALUE) と同じサイズであり、1.9の途中のタイミングまではRVALUEと一緒に混在してた(→ heap)。なのでビットパターンにある種の互換性があり、rubyのGCは今でもNODEを理解する。しかしながらNODEは一度作ったら滅多に減らないという特徴がある(ASTなんざそう頻繁に書き換えない)。これを毎回GCがスキャンするというのはコストがだいぶ無駄である。という理由により現在はheapからは隔離されている。</p></li> </ul> <h3>は</h3> <ul> <li><p><strong>parser</strong> (ぱーざー) 魔窟。ruby 1.0が出たころのruby 2.0の目標としてパーザーと評価器の刷新、があったはずだが、評価器はYARVが入ったものの、parse.yに関してはついに秘伝のタレを継ぎ足しつづけて20年だ。底のほうでどんな虫が繁殖してるか分かったもんじゃない。また、理解している人間が少ないので数人欠けるとやばい。後継者の養成は急務といわざるをえない。</p></li> <li><p><strong>Bug</strong> (ばぐ) → 仕様</p></li> <li><p><strong>[BUG]</strong> (ばぐ) ruby処理系がなんらかの理由でそれ以上正常動作しつづけることができなくなった時に、断末魔として出力する内容に含まれている特徴的な文字列。転じて、ruby処理系がそのような状況に至ること。「[BUG]った」など。</p></li> <li><p><strong>RHG</strong> (はっきんぐがいど) 「Rubyソースコード完全解説」という名前で出版されたが皆ハッキングガイドと呼ぶ。UNIXにおけるLions&rsquo; Commentaryのようなものである。よい本。今となっては情報が古いのが難点。また、よいからと言って売れたわけでもないらしいというのが悲しい。現在古書としてプレミアがついている。</p></li> <li><p><strong>patch</strong> (ぱっち) モンスターから手に入れるもの。</p></li> <li><p><strong>バベル17</strong> (- せぶんてぃーん) 必読書。 → 完全言語の探求</p></li> <li><p><strong>VALUE</strong> (ばりゅー) 型。Cレベルにおけるrubyの値の表現。だいたいポインターだが時々違う。→ tagged pointer → 即値</p></li> <li><p><strong>RVALUE</strong> (ばりゅー) データ構造。VALUEがポインターである場合は(ぶっこわれてなければ)その指すポインターの先はRVALUEだ。そしてRVALUEのホモジニアスな配列がheapだ。RVALUEは伝統的に構造体であり、ポインター5個ぶんのサイズで、先頭からポインターひとつぶんの領域が管理領域、その次がクラスへのポインター、残りがクラス固有のデータである。この仕組みは正直にいって古く、現代のプロセッサ・アーキテクチャから見ればいけてない。キャッシュラインの幅で割り切れないからだ。典型的なケースであるamd64アーキテクチャでLLP64の場合、RVALUEは40byteとなるが、1word減らして32byteとするか、3word増やして64byteとするのが現代的には妥当といえる。</p></li> <li><p><strong>heap</strong> (ひーぷ) rubyコア用語としてはheapとはrubyオブジェクトプールのことである。この用法は特殊なのでruby以外では通じない。実装上はrubyオブジェクトはheapとよばれる単位でOSから確保され、これを少しずつ切り売りしていく。なくなったらGCが走る。GCの結果heap上のすべてのオブジェクトが回収された場合、OSに返すこともある。このような管理機構はobjspaceと呼ばれ、rubyスクリプトからは定数ObjectSpaceとして見える。</p></li> <li><p><strong>bigzero</strong> (びっぐぜろ) Bignumのインスタンスで値が0のもの。というと、みんな最初は「えっ」という顔をするのだけれど、BignumとFixnumというのは実は互いに素ではない。というかBignumはFixnumの真のsupersetである。とくに0付近の、0, 1, -1 といった代表的な値は、Fixnum, Bignum, Float, BigDecimal, Complexのいずれでも表現可能といえる。</p></li> <li><p><strong>Fixnum</strong> (ふぃくすなむ) VALUE埋め込みオブジェクト。いくつかの点でその他のrubyオブジェクトとも、あるいはJavaなどのプリミティブ型などとも異なった振る舞いをする。</p> <p>Fixnumの幅は必ずしもintptr_tと同じではない。同じではない例としてWin64が挙げられる。したがって変にFixnumの幅を仮定したプログラムを書くと変なことが起こる。そのようなプログラムはrubyスクリプトとしては稀だが、拡張ライブラリーとしてはありえる。</p></li> <li><p><strong>fairness</strong> (ふぇあねす) 単にfairnessと言った場合は大抵、スレッド間のコンテキストスイッチの公平さに関して言っている。これを本当に公平にしつつちゃんと物理コア数に対してリニアにスケールさせるのはマジムズい、らしい。</p></li> <li><p><strong>仏語</strong> (ふらんすご) 仏語話者の人は独語話者の人たちに比べて結構違和感のない英文でバグ報告してくる気がするなあ。なんでだろう。</p></li> <li><p><strong>flip-flop</strong> (ふりっぷふろっぷ) rubyで一、二を争うへんな機能(もう一個は → once)。意図的にプログラムを難読化する目的か、ワンライナーで使われる。「rubyから削りたい機能」という話題で毎回必ず提案される(読めないから)が、flip-flopで実現できるものをflip-flopなしで書くのがひじょうに面倒なので、毎度却下されている。</p> <p>ところでまったく同じものがPerlにもあるのだが、Perlでflip-flopが特別へんな機能という認識の人は少ない気がする。なにがこの差を生んでいるのか。</p></li> <li><p><strong>flonum</strong> (ふろなむ) VALUE埋め込みオブジェクト。最近導入された。64bitマシンにおいて整数と浮動小数点数とポインターはマシンレベルで全部幅が一緒だ。だからそれらを共用体として一緒に扱おうというのはある程度妥当な発想ではある。ただ浮動小数点数には余ってるビットとかは(常には)ないので、ある64bitのなにかが整数か浮動小数点数かの判定をどうするかが若干トリッキーではある。rubyのflonumの方式はささださんが一本論文を書いた程度には新規性のある方式。</p></li> <li><p><strong>BASERUBY</strong> (べーするびー) rubyのソースコードは一部、名状しがたいレシピファイルのようなものから機械的に生成されているが、その生成機構もrubyで書かれているので、再生成しようと思えば完動品のrubyが必要になる。このときに使うrubyのことをBASERUBYと呼ぶ。普通に生きている限りはよほどのことがないかぎり再生成は不要で、したがって普段は問題にはならない。普通ではない、再生成が頻繁に必要なタイプの人間は、普段から十指に余るrubyバイナリーに囲まれて暮らしているような人種であり、これも問題にならない。</p></li> <li><p><strong>Concurrentとparallel</strong> (へいれつとへいこう) なんかよくわからんということだけは確かだ。</p></li> <li><p><strong>母衣小</strong> (ほろしょう) 松江市立母衣小学校。これといって何の変哲もないただの小学校だが、NaCl本社をその校区に含むという点が少々特殊である。ちなみに上は二中→東高。</p></li> <li><p><strong>本屋</strong> (ほんや) rubyistたちが本気を出すとジュンク堂書店池袋本店の総合売上ランキングが歪むくらい売れる。あれはただの書店というより、ほとんど兵站。</p></li> </ul> <h3>ま</h3> <ul> <li><p><strong>matzruby</strong> (まっつるびー) 昔そういうブランチがあった。今はもう放棄されている。</p></li> <li><p><strong>micro benchmark</strong> (マイクロベンチマーク) プロパガンダ以上の意味はない。とはいえプロパガンダだからやらなくてよいというものでもない。</p></li> <li><p><strong>MVM</strong> (まるちぶいえむ) 昔あったブランチのひとつ。一つのrubyプロセスの上で複数の処理系を走らせることで、プロセスよりも細粒度だがスレッドよりは粗粒度な並行実行を実現しようとしていた。一応諦めてないことになってるが、だいぶ放棄ぎみ。</p></li> <li><p><strong>M17N</strong> (まるちりんがらいぜーしょん) 昔あったブランチのひとつ。名前のとおり多言語化を目的としていた。現在は放棄済みで、実現しようとしていた機能はもう取り込まれている。→ 多言語</p></li> <li><p><strong>malloc</strong> (まろっく) mallocに一家言持つ人は多いが残念ながらrubyではmallocが少々速くなったところでさして意味はない。GCがあるうえにGVLもあるから、mallocが一般的に想定しているマルチスレッドアプリケーションのメモリ確保戦略とはまるで違うのだ。</p></li> <li><p><strong>miniruby</strong> (みにるびー) rubyをコンパイルするためにrubyが必要なので、rubyのコンパイルでは初段としてまずはブートストラップのために最低限の機能だけをもったrubyのサブセットを作成する。これがminiruby。動的リンクモジュール機能を欠くため、あらゆる必要な機能が単一バイナリーに詰め込まれており、そのため実は最終的にできあがるrubyよりでかい。なおminirubyを作成するにもrubyが必要で、それはBASERUBYと呼ばれる。</p></li> <li><p><strong>メソッド探索</strong> (- たんさく) rubyで一番か二番目に重い処理。他のボトルネック(ファイルIOとか)をどんどん改善していくと最後にこれが残ることが多い。</p> <p>rubyのメソッド探索は動的、つまりメソッド名や引数からどのメソッド実体を呼ぶかコンパイル時には決められない。じゃあ実行時に一回決まればあとは同じかというと、そうでもなくて、呼び出すメソッド実体がどんどん変わっていくことがよくある。もちろん、変わらないことの方が全体としてはよくあるので、一回でも探索したメソッド実体はキャッシュされている。が、どんどん変わるようなやつがいるとキャッシュがどんどんパージされていってヒット率が下がり、パフォーマンスが悪化する。メソッドキャッシュのinvalidateアルゴリズムが本来残っててもいいキャッシュエントリまで消してしまっていることはよく指摘されるが、じゃあどれが本来残っててもいいのか、というのを判定するのはそう容易ではない。後から検証したら不要な操作でしたね、というのと、操作を行う前にそれが不要かどうかを判定するというのでは、難しさが全然違う。</p></li> <li><p><strong>メソッド呼出し</strong> (- よびだし) rubyで一番か二番目に重い(中略)これが残ることが多い。</p> <p>rubyのメソッド呼出しは動的、(中略)変わっていくことがよくある。ということはつまり、メソッド呼び出しのインライン展開ができないということである。rubyにおいては 1+2 のような常識的に考えて 3 だろそれは、みたいな状況でも律儀にメソッドを呼び出す。このオーバーヘッドが積み重なって無視できないペナルティになるのだ。</p></li> <li><p><strong>vm_exec_core()</strong> (めいんるーぷ) rubyのメインループは一個ではない。というのも、C関数と入り乱れる事があるからだ。なんらかのrubyのコードがメソッドを呼び出したときにそれがC関数に帰着することが良くある。しかしそのC関数の中から(yieldしたりして)またrubyのコードが実行されるというのも、これまたよくある。そのときにrubyでは、Cスタックを巻き戻してメインループに戻るようなことはせずに、メインループの中から伸びたCスタックの上にさらに新しいメインループを開始する。面倒なことをしていると思うかもしれないし実際面倒だが、もとのメインループに戻るのよりはまだ簡単なのだ。このようなことが積み重なって、ある瞬間のrubyにはメインループが何個もあることになる。</p></li> </ul> <h3>や</h3> <ul> <li><p><strong>YARV</strong> (やるう゛) というコードネームがあったのさ。一時期言わなかったけど最近またYARV言うようになってきたのはなぜだろうね。</p></li> <li><p><strong>yield</strong> (以ーるど) よみづらさに定評がある。</p></li> </ul> <h3>ら</h3> <ul> <li><p><strong>羅語</strong> (らてんご) rubyコミッターはみんな羅語が読めるかのような錯覚を受けるが、実はそうでもない。というかせいぜい羅語のフレーズは読めても、羅語の作文ができる人はいないと思われる。</p></li> <li><p><strong>LSP</strong> (りすこふのちかんげんり) Liskov&rsquo;s Substitution Principle, リスコフの置換原理。サブクラスに関する設計指針として有名だが、rubyではユーザークラスにおいて必ずしもLSPを強制しない。rubyでは変数に型がないので、変数への代入によるダウンキャスト・アップキャストが行われないからだ。rubyにおいてはキャストのような操作は常にオブジェクトのコピーが生成され、bitcastやreinterpret_castとよばれるものはない。したがって、暗黙のうちにあるオブジェクトが別のクラスとみなされるということがない。そのため、LSPは、依然としてとても有効な設計指針ではあるものの、かならずしも言語側で強制する必要がなくなっている。</p></li> <li><p><strong>リテラル</strong> (-) コンパイル型言語と違ってrubyにおいてはリテラルという概念は曖昧だ。たとえば多くのコンパイル型言語では文字列はリテラルの代表的なものだが、rubyだと <code>"string#{rand()}"</code> のような例はいくらでも作れる。</p></li> <li><p><strong>例外</strong> (れいがい) 1.8までは例外はbeginでコストがかかりrescueではほとんどノーコストだったが、1.9移行で逆転し、現在はbeginはほとんどノーコストだがrescueが重い。つまりrescue節に実際に入ってこなければ、beginやrescueが書いてあったとしてもさしてペナルティーにならないということである。意外に最近でも1.8のくせを引きずったスタイルを見かける。気をつけよう。</p></li> <li><p><strong>Rails</strong> (れいるず) べつにrails嫌いじゃないですよ。好きでもないけど。</p> <p>Railsの人たちにとってrubyがないとrailsが成立しないけど、rubyにとってrailsなくてもべつにrubyは成立する、という非対称さから、rails側から見るとrubyの開発は冷淡に見えるのかなあ、とは思われる。しかしrubyの側から見ればべつにrailsだけを特別どうこう思っているというわけではない。</p></li> <li><p><strong>Redmine</strong> (れっどまいん) rubyのIRCでredmineと言ったらそれはプロダクトのことではなくてredmineを使って動いている bugs.ruby-lang.org (旧アドレス redmine.ruby-lang.org)のことである。</p></li> <li><p><strong>long</strong> (ろんぐ) Cの整数の一種。昔からrubyのさまざまな箇所でlongを悪用して整数じゃない意味で使ってる部分がある。1.9の期間を通じて、それらは徐々に <code>intptr_t</code> や <code>st_data_t</code> に置き換えられていった。ただ、時々まだ残ってる。そのためソースコードでlongが出現する箇所をいじる際にはある種の緊張感がある。</p></li> </ul> <h3>わ</h3> <ul> <li><strong>once</strong> (わんす) rubyで一、二を争うへんな機能(もう一個は → flip-flop)。rubyの正規表現には「一回だけ評価」というモードがあるが、この機能を実現するためだけにスレッド間でブロックすることすらあるという、どうしてこうなった感しか残らない機能である。</li> </ul>https://shyouhei.tumblr.com/post/64498820681https://shyouhei.tumblr.com/post/64498820681Sun, 20 Oct 2013 03:54:00 +0900おれはzshというシェルを常用しているが、たとえばこのシェルにはヒストリを際限なく記録しつづける、という、たったそれだけの機能がない。その程度の機能もないのにzを名乗るなと思う。ここから得られる教訓はや...<p>おれはzshというシェルを常用しているが、たとえばこのシェルにはヒストリを際限なく記録しつづける、という、たったそれだけの機能がない。その程度の機能もないのにzを名乗るなと思う。ここから得られる教訓はやはりDQNネームは良くないということだ。実状に即した名前をつけよう。</p>https://shyouhei.tumblr.com/post/63160800869https://shyouhei.tumblr.com/post/63160800869Sat, 05 Oct 2013 19:17:27 +0900たとえば俺が「タバコ吸わなくても生きていけるしタバコない人生考えられないとかどんだけ人生ちっちゃいの?お前」っていえば深く共感してくれる人が多いのに、タバコをiPhoneに置換するだけで激昂する人が多い...<p>たとえば俺が「タバコ吸わなくても生きていけるしタバコない人生考えられないとかどんだけ人生ちっちゃいの?お前」っていえば深く共感してくれる人が多いのに、タバコをiPhoneに置換するだけで激昂する人が多いあたり、iPhoneに手を出してしまうとヤバいって感じしかしませんよね。</p>https://shyouhei.tumblr.com/post/62045874889https://shyouhei.tumblr.com/post/62045874889Mon, 23 Sep 2013 16:28:38 +0900testingcasual...<h1>testingcasual 出張入っちゃって出れなくなって残念なんですけど、まあなんというか、こう、自分としても普段は「ちゃんとテスト書きなさいよ」とか言っちゃうほうの立場なわけで、お前がそれを言うかと言われるとぐぬぬって感があるのをなんとか許していただくとすると、「ちゃんとしないテスト」っての、もっとやるべきだとおもうわけですよ。っていうと、やっぱ語弊があるので、多分誤解されるんだろーなー、っての思いつつもさらに言うと、そりゃちゃんとテストしたほうがいいに決まってますよ。いいに決まってるんだけど、だからといってちゃんとテストできないときに全然テストしないのは、やっぱ、やらないくらいならちゃんとしてなくても多少でもやったほうが断然いいんですよ。完璧な家事が存在しないからって家事放棄するのは違うでしょ。それと同じですよ。もっというとじゃあ逆にちゃんとしたテストってなんやねん、って、実はさほど自明じゃない。そこでちゃんとしないとと思ってちゃんとしようと考え込んだ挙句手が動かないくらいなら、ダメでもかまわんからとりあえずなんか書けって思うわけですよ。そりゃ、ものすごくたくさん見てきた中で、書かない方がマシだったテストとかいうのも実際たまにはありますけど。でもそんなの結果論だよ。シュート外すことができるのはシュート打った奴だけってこと。</h1> <p>テストというと、とかく「正しく」とか「きちんと」とか言い出しがちだし、その気持ちは分るし、自分でも普段はそういうこと言う係ではあるのだけれど。でもあえて言う。テスト書かないくらいなら、「ちゃんとしないテスト」を書きましょう。</p>https://shyouhei.tumblr.com/post/56015360441https://shyouhei.tumblr.com/post/56015360441Sun, 21 Jul 2013 12:40:15 +0900Visualizing git blame Git には git blame...<img src="https://64.media.tumblr.com/cade7426ae10ccf6b671946ab9c2e397/tumblr_mnr2kfmSXg1qzt98vo1_500.png"/><br/><br/><h2>Visualizing <code>git blame</code></h2> <p>Git には <code>git blame</code> というコマンドがあり(他のツールでも同様の機能は提供されている)、これを使うことでソースコードのどこを書いたのが誰か、という情報がline-by-lineで取得できる。この情報は行単位なので一次元の情報だけれど、適切な空間充填曲線に乗せることで二次元にマッピングできて、それに適当に作者ごとに色をつけるということをやってみると色々楽しい。そのスクリプトはひじょうにstraight-forwardな記述だと<a href="https://gist.github.com/shyouhei/5692655">こういった感じ</a>になる。上の絵はruby 1.8.7に対する実行結果で、ChangeLogとかのあきらかに面白くないファイルは除外してあるからまあ、そのままの結果ではないけれど、これを見ると色々な思いが去来する。</p> <ul> <li>Ruby 1.8.7 は多数の開発者が手を入れており、少数の支配的な貢献者といったような存在をみいだすことができない</li> <li>しかしながら、全体がのっぺりと灰色になっているわけではなく、局所的に色がぜんぜん違う。これは、開発者ごとに専門性があり、すべてのファイルに手を入れている人がいないことを示している。</li> </ul>https://shyouhei.tumblr.com/post/51945063131https://shyouhei.tumblr.com/post/51945063131Sun, 02 Jun 2013 14:14:39 +0900#rubykaigi バイヤーズガイド '13<p>あえてアマゾンのリンクは貼らないので会場で会おう</p> <h3>たのしいRuby 第四版</h3> <ul> <li>これを買うべき人: 全員</li> <li>ひとこと: ついにRuby 2.0の時代が本格的に始まったことを宣言する決定打的一冊であり、必携。今後「情報がないから2.0は不安」などとうそぶくことはこれで不可能になった。</li> </ul> <h3>テストから見えてくるグーグルのソフトウエア開発</h3> <ul> <li>これを買うべき人: テストを日常的に書いている人と、テストを書く習慣がない人</li> <li>ひとこと: これはずばり俺が読みたいので買います。こちらからは以上です。</li> </ul> <h3>白と黒のとびら</h3> <ul> <li>これを買うべき人: 「記号と再帰」がおもしろかった人</li> <li>ひとこと: まあなんていうんですかね、形式言語とか好きな人って結局そっちに道を踏み外しちゃうきっかけってテングワールだったりするわけじゃないですか。だからこういうふうに攻めてくるのって変化球のようでいて実はど真ん中だと思うんですよね。</li> </ul> <h3>型システム入門</h3> <ul> <li>これを買うべき人: RHGがおもしろかった人</li> <li>ひとこと: 久々に本気手加減なしの全力投球本が来たってところ。これに「入門」とつけるセンスはさておき、内容はといえば大学院レベルなので流し読みではなかなか辛い。そういうのが好きな人にはたまらない。ええ。1章だけですでに価格分の価値はあります。</li> </ul> <h3>講座ITと日本語研究4 Rubyによるテキストデータ処理</h3> <ul> <li>これを買うべき人: 俺とうささん</li> <li>ひとこと: 数ヶ月か1年くらい前にIRCで話題にしてた本! なぜ入荷している… これはRubyプログラムとして読むべきものは書いてなくて、日本語研究が好きかどうかでしかない。なので好きな人だけ買えばいいです。</li> </ul> <h3>プログラマの考え方がおもしろいほど身につく本</h3> <ul> <li>これを買うべき人: じつはプログラマこそ読むべき</li> <li>ひとこと: 俺が知ってる中でこれにもっとも近いのは「エレガントな問題解決」あと「いかにして問題をとくか」。ようするにプログラマの考え方とは、そういうことだと分かる。そして意外に実践されていないので、ぜひ身につけるべき。</li> </ul> <h3>インフォメーション</h3> <p>これについては<a href="http://d.hatena.ne.jp/wlj-Friday/20130403/1364975154">山形浩生の書評</a>があるので自分が何か付け加える必要性はあまり感じない。</p> <h3>進化するアカデミア</h3> <ul> <li>これを買うべき人: 表紙に騙された人</li> <li>ひとこと: 進化と呼ぶべきかは分らないが、敷居は確実に低くなってきてるよね。研究で食べようとさえ思わなければいいだけで、すごい時代になったもんです。</li> </ul> <h3>その他</h3> <p>まだまだたくさん入荷してるっぽいけど時間がないのでこのへんで。多分、たとえばオライリーのとかはガイド以前の問題として全員全種もれなく購入されることと思いますので、そういうのはまあ、言うまでもないかと思います。けど誰の趣味が反映されてるのか知らんがRubyKaigiでは案外人文系が売ってる(何年か前にダールグレン置いてたのはびびった)ので、そういうのもちょっと読んでみるとよいですよー</p>https://shyouhei.tumblr.com/post/51690065306https://shyouhei.tumblr.com/post/51690065306Thu, 30 May 2013 10:56:00 +0900"People blame me for merging others people changes to fast. But this merge button looks just to..."“People blame me for merging others people changes to fast. But this merge button looks just to tasty. It’s kind of a sin to not use it.”<br/><br/> - <em><p><a href="https://www.facebook.com/bovensiepen/posts/10200155061579359">https://www.facebook.com/bovensiepen/posts/10200155061579359</a></p> <p>「マージ早すぎっていうけどさー、このマージボタンが燦然と輝いてるんだよ。押さないなんてある種の罪」</p></em>https://shyouhei.tumblr.com/post/50427710917https://shyouhei.tumblr.com/post/50427710917Wed, 15 May 2013 01:50:45 +0900nonnon21: CiNii 論文 - ...<p><a href="http://nonnon21.tumblr.com/post/16620808021/cinii-tumblr" class="tumblr_blog">nonnon21</a>:</p> <blockquote><p><a href="http://ci.nii.ac.jp/naid/40017040127">CiNii 論文 -  Tumblrにおける情報の伝播経路に着目した記事の特徴付け</a></p><p><a class="tumblr_blog" href="http://effective-tumblr.tumblr.com/post/16585732679/cinii-tumblr">effective-tumblr</a>:</p><div> </div><blockquote><div> <p>少し前に論文「<a href="http://effective-tumblr.tumblr.com/post/14567393425">マイクロブログの文脈付き投稿情報の体系化に基づく重要ユーザ推薦と情報集約支援への応用</a>」を紹介しましたが、これの参照している先行研究である表記論文を、共著者の<a href="http://www.slideshare.net/kiyoya/hitsbased-tumblr-ranking/1">kiyoya</a>こと<a href="http://www.slideshare.net/kiyoya/hitsbased-tumblr-ranking/2">山口清弘</a>さんから送っていただきました。論文は次のような背景認識から始まっています。</p> <blockquote><div> <p>オンラインコマースにおけるコア技術となっている,アイテムのクラスタリングや推薦においては,アイテムをどう特徴付けるかが,その結果を大きく左右する.ここで,記事の特徴付けとは,記事を何らかの視点で数理的に表現すること,および,それに基づいて記事同士の類似度を算出することから可能であると考える.</p> </div></blockquote> <p>統計学を知らない僕なりに読み進み、砕いてみます。最近はニュースサイトでもオンラインショップ(eコマースサイト)でも「お勧め」をされることが増えてきました。これは、よく似た記事、よく似た商品をグループ化しておいて、そのグループ内の一つがピックアップされたら、別の一つを推薦してみる、ということをしています。でも「よく似た」と簡単に書きましたが、ある記事と別の記事、ある商品と別の商品が「似ている」というのは、どういう意味で、どうやって決めるんでしょう?</p> <blockquote><div> <p>一般に推薦システムにおけるアイテムの特徴付けには,誰がどのアイテムを評価したかという共起関係用いられる傾向にある.Tumblr のような,記事が人の間を伝播していくネットワークにおいては,共起関係のみを考慮するよりも,記事の伝播経路を用いた記事の特徴付けの方がより有用であると考えられる.</p> </div></blockquote> <p>一般的に広く使われているのは、「この商品を買っている人はこんな商品も買っています」という情報を活かした判断です。AとBとCはよく同じ商品を買っている。つまり彼らは好みが似ているということだ。そして彼らの好みにあった商品が二つあるなら、それの二つは似ているということだ。こういう判断が下せれば、二つのうち一方を買った人には、もう一方も勧めると買ってくれそうだ、と考えられることになります。</p> <p>こうした「誰と誰と誰が」という関係、共起関係で似ている度合いを図ることもできますが、Tumblrではさらに「誰がいつ誰からリブログしたか」という時系列や伝播経路を考えることもできます。則のぞみ氏、山口清弘氏らはこれらを考慮したほうが、より妥当な(精度のよい)にている度合いを測れるだろうという仮設を立て、実際に実験して確かめています。</p> <p>ここから実験方法と実験結果になると、数式と数値が乱れ飛ぶ、私にはなんとなく程度には分かっても正確なところはギブアップの世界に入るので割愛。いきなり考察のうち、特に面白かった、木構造、順序指標を考慮した結果を。</p> <blockquote><div> <p>カット率6割から,順序指標が共起指標に比べて有意に高い再現率となった.これは,共起指標では,カット率の増加に応じて再現率も下がっていくが,順序指標では,カット率6 割から8 割の間で再現率がほぼ変化しないことによる.この理由として,Tumblr においては,ある記事を誰が最初の方でリブログしたのかという,最初の方の順序が,後の伝播を決定付ける重要な要因になっていることが考えられる.Tumblr においては,特に伝播の初期における順序を考慮することが有用であると言える.</p> </div></blockquote> <p>言い換えれば、「誰と誰と誰が」という共起関係に基づいたアプローチでは、興味を示す層のうち実際にリーチできた層が減るほど、残りの人たちを推測する精度が悪くなります。ところが「誰と誰と誰がそれぞれいつごろ」という順序を指標に入れると、5割を切ったあたりと2割まで減ったあたりで同等の推測制度が出ています。</p> <p>もっと言えば、共起関係だけで考えていた頃であれば5割、多分アーリーマジョリティまでを観察してはじめて浮かんできた潜在顧客層が、木構造における順序にも注目することで2割、多分アーリーアダプタぐらいを観察すれば浮かんでくるということです…だと思います。もちろん「マイクロブログの…」もこの論文も、Tumblrのような「リシェアの経路と時刻が可視化された」世界だからこそ役立つ、ある種のニッチな世界向けのアプローチといえるでしょう。でもニッチだったそのリシェア・ワールドが、いまやTwitterやFacebook、そしてGoogle+へと領地を拡大しています。</p> <p>おそらく「バイラルでは経路が重要」という考え方は新しくないでしょう。ですが購買層という古典的な視点でも、つい先日、4,500台の自販機から集めた<a href="http://tsukamoto.tumblr.com/post/16544743253">2億件のビッグデータをもとにすることで新製品が生まれた</a>ことが報じられました。現在(※’12/01/27)165億件強の<a href="http://www.tumblr.com/about">Tumblrの投稿合計数</a>から経路情報を調べ上げると、そこにはまた新しく見えてくるものがありそうです。そしてオンラインコマースにおけるリコメンドを背景に上げたこの論文は、やっぱりそこを睨んでいるんだろうな、と思います。</p> <p>それが来た時に、その手法に先鞭をつけ、かつデータを総なめするのではなくある程度小規模なサブセットで代替したときの精度に言及したこの論文は、結構面白いポジションにあったりしないかな、と思いました。</p> </div></blockquote><div> </div></blockquote>https://shyouhei.tumblr.com/post/49776550122https://shyouhei.tumblr.com/post/49776550122Mon, 06 May 2013 23:55:01 +0900#naruhounix について<p>どうなんですかねえ。まあぶっちゃけ、この本にツッコミを入れることが容易な種族はいる。たとえば「プロセスがfork(2)するときにPOSIX semaphoreをsem_wait(3)してたらそのセマフォはどうなってまうの?」とかそういうの(実際書いてない)ね。けど、それって、そういうの目ざとく気がついてしまう人、はっきりいって対象読者じゃないというべきだろうなあ。LinuxとBSDのカーネルコミッターの皆さん、セプキャン講師陣の皆さん、未踏スーパークリエーターの皆さん、お疲れさまです。おまえらはお呼びじゃない。</p> <p>でね。俺もどっちかというとお呼びでない側っぽいので、色々考えた。昔はCで書くしかなかったサンプルコードがRubyで書いてあるというのはよいですね。なにがよいかってCほど煩瑣じゃないから、本質的な記述(だけとは言わないまでも)の割合が大きくて、いわゆる密度が高い気がする。なのでページ数のわりに内容薄い印象は受けない。高速道路理論ってやつだな。この本で学べるところまでいけば、まあRubyでプログラム書く上では標準的と言ってよい理解度なのだろうし。</p> <p>もちろん上に書いたように、抜けてる箇所は多々あって、それは自力でmanを読んだりしてなんとかする必要がある。ただ、この本を最後まで読めばmanを使う体力は得られるだろうとは思いました。あとは<a href="http://www.jstorimer.com/books">原著は実は3部作</a>だったりするので、全部通して読めばもう少し理解が深まるとかはあるのかもしれない(が翻訳されるかは…売れ行き次第なのかも)。</p> <p>というわけで率直な感想を言えば「目次見て知らなそうな事が書いてそうなら、買いじゃないっすかね」とかそういう感じ。これと同様の知識を得るためには一番の近道ではありそうに感じました。</p> <p><a href="http://tatsu-zine.com/books/naruhounix">http://tatsu-zine.com/books/naruhounix</a></p>https://shyouhei.tumblr.com/post/49219879388https://shyouhei.tumblr.com/post/49219879388Tue, 30 Apr 2013 09:39:09 +0900OSの標準インストールでPerl入ってるからPerl最強とか言ってるそこのおまえら、10年古い。<p>Heroku使いなさいよ。</p> <p>10年前、たしかに、自宅サーバでApacheでCGIでPerlっていう時代がありました。でもさすがに今それはないわ。10年前それやってたサイトのほとんどが結局メンテナンスコスト払えなくて鬼籍に名を刻んだ。あるものはクラックされ、あるものは更新が止まった。そういう歴史の流れですので。今更OS標準だから偉いとか偉くないとかさすがに。ありえんです。</p> <p>ああ、おまえらがプロのシステム管理者なら(つまりサービス提供側なら)ちょっと話は違う。<strong>システム管理者のくせに贔屓の言語とか持っちゃいかん</strong>。本当に。どんなシステムでも同様に管理できないようではプロ失格。Perlが来たらPerlでRubyが来たらRubyを鼻歌歌いながら管理できないようでは、半人前です。猛省すべき。</p> <p>まあいずれにせよ、今更OS標準だから強いとか強くないとか、ないわ。</p>https://shyouhei.tumblr.com/post/45836775066https://shyouhei.tumblr.com/post/45836775066Wed, 20 Mar 2013 23:58:10 +0900どうも。グリーのアカウントは持ってる1けどモバゲーのアカウントは持ってない卜部です。 ところでPerlリスクですか。まあ、あるんじゃないですか。ぶっちゃけ。でもさあ、さすがにPerlしか書けない人たち...<p>どうも。グリーのアカウントは持ってる<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>けどモバゲーのアカウントは持ってない卜部です。</p> <p>ところで<a href="http://anond.hatelabo.jp/20130228002211">Perlリスク</a>ですか。まあ、あるんじゃないですか。ぶっちゃけ。でもさあ、さすがにPerlしか書けない人たちは転職先の選択肢のなさくらい自覚してると思う。なのでPerlがどうとかいう話はしないです。各自でどうぞ。</p> <p>でね、ポイントはそこじゃないだろうと思うわけですよ。どんな選択をしても同様のリスクはあるんですよ。たとえばMacromedia ShockwaveでLingoで作ってたソフトとかさあ。今ではだれもメンテできないでしょう? だから今隆盛をきわめてる技術で作ったものが、何年か後にリスクになるってのは、それはそういうものなんですよ。べつにPerlに限らん。Perlはたまたま今そういうフェーズってだけで、明日は我が身ですよ。hamlとかsassとか。</p> <p>だからまあ、こう言ってしまうと身も蓋もないかもしれないけど、リスクはPerlじゃない、Perlに固執することにあるのです。</p> <h3>あなたがプログラマなら:</h3> <p>いつでも今のスキルセットを捨てれるようにしましょう。捨てれる==他を獲得できるってことです。たとえば俺はRubyやってから逆にモダンPerlの世界に来てるけど、そういうことね。今の俺はPerlが死んでもRubyが死んでも生きていける自信がある。まあ、実際捨てるかは状況次第だけれども、捨てれるってのは強さですよ。</p> <h3>あなたが事業者なら:</h3> <p>いつでも今のシステムを捨てれるようにしましょう。いや、サービスを捨てろとは言ってない。今動いてるそのシステム、それが動き出した瞬間から、すでに技術負債になっているのです。システムを「安心して」作り直せる仕組みを考えましょう。たとえば明確な外部仕様に基づく機械による検証などです。所詮、システムはシステム。それに引きずられて本当に革新的なビジョンが実現できないのは、本末転倒ですよ。</p> <h3>あなたが言語作者なら:</h3> <p>いつでも今の文法を捨てれるようにしましょう。言語にとって「変わらない」のはとっても簡単。放置すりゃそれでいい。でもね、それって立ち枯れっていうか、立ち腐れですよ。なんでか。世の中はこっちの都合におかまいなくどんどん変わるからです。そして話者いてこその言語です。言語ってのは、ここに挙げた中ではもっとも長期的なビジョンが求められる。それが、当たるか外れるかは、分からない部分もあるけど、外れたなって思ったら迷わず軌道修正しないと。良いものは良い、と素直に受け入れるようにしましょう。</p> <div class="footnotes" role="doc-endnotes"> <hr> <ol> <li id="fn:1" role="doc-endnote"> <p>id:18667。アカウントをとった当時まだグリーはゲーム屋じゃなかったどころか会社ですらなく、ただの <strong>田中さんの個人サイト</strong> に過ぎなかったという点は指摘しておくべきであろう。2004年くらいの話だ。 <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> </ol> </div>https://shyouhei.tumblr.com/post/44451702850https://shyouhei.tumblr.com/post/44451702850Sun, 03 Mar 2013 22:34:34 +0900RabbitMQ と再送について<p><strong>概要</strong> : AMQP のプロトコルを読むと、一瞥して送信はパケットを送るだけ、受信はソケットを読み込むだけのようにも見える。しかしながら、実際に書いてみると、再送処理を自前で実装する必要があるため、現実には大変に複雑な処理が必要だ。</p> <h3>そもそもなぜ RabbitMQ を使うのかという話、あるいはなぜ再送が必要かという話</h3> <p>たんにコンポーネント同士が疎結合で通信したいのであればわざわざ MQ を使う必然性は皆無である。ごくあたりまえに TCP で通信すればそれでいい。暗号通信が必要なら当然 SSL でいいし、パケットエンティティに依存する複雑な L7 リバースプロキシを MQ を使って実現することも、不可能ではないが、普通そういうのは varnish とかでやるだろう。</p> <p>MQ において優れているのはデータの durability だ。つまり、一旦キューにためておけば、その両側のコンポーネントは好き勝手に落ちたり立ち上がったり、あるいは数を増やしてスケールアウトしていい。複数のコンポーネントが複雑に入り乱れているシステムでは、その一部だけを落としてメンテナンスできるというのは非常に重要な要件だし、通信で間に MQ をかますことで、それを実現できるというのが非常に大きなアドバンテージである。</p> <p>だから逆に言うと MQ を使うのであればピアのエンドポイントが突如いなくなるというのは、最初から考慮しておかなければ MQ の意味がない。システムが神のように無停止で動くのであればそもそもキューなんぞ不要である。ただのバグでプロセスが落ちるのが仮に排除されたとしても、おかんが掃除機かけたらブレーカーが落ちたとか、落雷で電話線からサージ電流が来てモデムが爆発したとか、光ファイバーだから平気だぜと思ったらセミが産卵したとか、様々な理由でシステムというのはすぐ落ちるものだし、みんな知ってるとおり 100% の SLA というものは存在しないのだ。</p> <p><strong>この節のまとめ</strong> : おまえらは本当に MQ が必要なのか? もしどうしても必要なのであれば、一切の希望を捨てよ。</p> <h3>再送処理の実際 (#1) 受信編</h3> <p>MQ から受信する側のプログラムは(比較的)そんなに難しくない。なぜかというと MQ からデータが来ていて自分のプログラムも動いているということは要するに、両側が生きていることは自明だからだ。</p> <p>しかしながらそれが自明なのは受信側だけで、送信側である MQ からしたら、受信プログラムがだんまりを決め込んでしまうと、生きているか死んでるか分からんということになってしまう。そこで、プログラムは MQ からデータを受信した後に、適切に <code>basic.ack</code> パケットを返してあげる必要がある。逆に言うと、ack しなかったパケットはやがて MQ 側から再送されてきてしまう。</p> <pre><code>#! ruby require 'amqp' EM.run do AMQP.connect $your_settings_here do |conn| AMQP::Channel.new conn do |ch| ch.queue $your_another_settings do |q| q.suscribe $your_yet_another_settings do |hdr, bdy| hdr.ack # &lt;- don't miss it end end end end end </code></pre> <h3>Ack 戦略を考える</h3> <p>ここでいくつかの戦略が考えられる。つまりどこまで処理したら ack することにするかという話だ(図)。</p> <p><img src="https://64.media.tumblr.com/f35827fd121dd89b7e2123f2d64223bc/tumblr_inline_mfrvdefUlq1qzt7z1.png" alt=""/></p> <p>受け取った直後に ack するというのは、 ack したあとに処理の途中で例外で死ぬこととかをかんがえると筋が悪いかのようにも見える。しかしながら、処理の最後に ack するというのだと、処理自体が無限ループしちゃったら永遠に ack できないとかありうる。一長一短と言える。どちらにせよ正常時には問題ない。が、今回考えているのはプログラムが突如死んだりする場合なので、そこを勘違いしないように。</p> <p>別の考え方としては nak (not ack, 「受け取れませんでした」)を積極的に応答するというのもありうる(図)。nak されたパケットは、当然、MQ から後で再送されてくる(されてこないようにも指定できるが)。最初の受信時に処理をトリガしておいてから nak を返信して、再送時すでにトリガされた処理があれば、それが終了しているかで ack/nak を出し分けるということだ。</p> <p><img src="https://64.media.tumblr.com/39c6904d69330727c78aab57d8834451/tumblr_inline_mfrvfpPnFT1qzt7z1.png" alt=""/></p> <p>これは賢そうに思えるのだけれど、実際どうかというと、処理するワーカーが一個だけしか動いてなければまあ、そこそこ程度にはうまくいく。しかしながら MQ 使っててワーカーが一個というのはかなり考え辛くて、普通は横方向にたくさんスケールアウトしているだろう。そうなってくると、再送パケットがどのワーカーに届くかはロシアンルーレットだ。つまり処理をしているワーカーではないワーカーに再送されるというのが典型的なシナリオである。</p> <p>この際、当然、二重に処理をしてしまってはいけないので、ちゃんとロックをとる必要がある。当然、プロセス間にまたがったロックだから、いわゆる分散 Mutex という話になるだろう。ところで、今、正常に動く場合の話はしていない。つまりプロセスが Mutex を握ったまま死んだらどうなるのか? このシナリオは、別途考える必要があるといえるし、そう一筋縄で解決できる話ではない。</p> <p><strong>この節のまとめ</strong> : 再送されてくるパケットを適切に無視するために分散 Mutex に逃げるというのは複雑さのレイヤーが MQ から Mutex に移動しただけの話で、本質的な解決になってない。</p> <h3>再送処理の実際 (#2) 送信編</h3> <p>さて、送信側では先程「 MQ からしたら、受信プログラムがだんまりを決め込んでしまうと、生きているか死んでるか分からんということになってしまう。」と書いたことの逆が発生する。つまり、 MQ が生きているかどうかを判定して、死んでそうなら手元にためておき、再起動してきたら送り直すというコードを自分で書かなくてはいけない。 Ruby の <code>amqp</code> ライブラリの場合で言えば、再接続まではライブラリの責任範囲だが、データの送受信は当然、クライアントプログラムの領分だ。とりうる戦略は二つある。</p> <h3>トランザクションを使う</h3> <p>MQのプロトコルにはトランザクションを宣言できる機能がある。これの流れ(図)は、まずクライアント側がトランザクションを宣言、次に通常のデータ通信を行い、最後に <code>tx.commit</code> を発行すると、トランザクションが有効であった間に送信したデータが確実にMQのデータストレージに書き込まれて再起動に耐えれる状態になるまで、 <strong>ブロックする</strong>。つまり間に MQ の再起動とかはさまってても、 commit-ok が返ってきたら送信できてたということをキュー側で保証してくれる(ちなみに失敗したら例外が発生)。簡単であるし、確実でもある。</p> <p><img src="https://64.media.tumblr.com/05142ef9da0f06a3d1cf1fb6a33b2bcf/tumblr_inline_mfrva7ntFp1qzt7z1.png" alt=""/></p> <pre><code>#! ruby require 'amqp' EM.run do AMQP.connect $your_settings_here do |conn| AMQP::Channel.new conn do |ch| AMQP::Exchane.new ch, $your_another_settings do |xchg| ch.queue $your_yet_another_settings do |q| q.bind xchg, nowait: false do xchg.tx_select # start transactoin $your_ary_to_send.each do |i| xchg.publish i xchg.tx_commit # this blocks end end end end end end end </code></pre> <p>ただ問題は明らかなようにブロックするので速さが出ない。下層の RTT にもろに影響されるし、 MQ 側でも様々なロックをとったりディスク書き込みで <code>fdatasync(2)</code> したりするだろうから、ばーっとアクセスがくると今度はサーバのディスク速度が律速しだす。MQ に DB のような行の概念はないので、行単位にロックしたりとかということもない。</p> <p><strong>この節のまとめ</strong> : MQにもトランザクションがある。それはそれで便利ではある。が、万能ではない。</p> <h3>Publisher confirmation を使う</h3> <p>ようするにトランザクションはちょっと overkill なのである。どうせ TCP で通信しているのだからパケットの再送とかは基本は TCP でなんとかしているはずなのだ。そこはわざわざ待ち合わせる必要はない。問題はピアの MQ ブローカーが落ちたときで、それだけ検出できればいいでしょう、というのが、 RabbitMQ の拡張プロトコルである publisher confirmation だ。</p> <p>Publisher confirmation はようするに MQ 側から「今ここまで読んだわー」っていう情報を送り返してくれる。そんだけである。したがって、流れ(図)としては送信すべきデータは送信後も一旦手元に残しておく。で、完了の通知を待たずにどんどん次のパケットも送ってしまう。のちに、完了通知が来たら、そのパケットはもう届いたから捨ててよくて、完了通知が来なかったら対向は死んでるので、再接続して送りなおす。</p> <p><img src="https://64.media.tumblr.com/8c81ceda7887941f7ca891d370087139/tumblr_inline_mfrwa7Ef831qzt7z1.png" alt=""/></p> <p>これはクライアント側に待ちが発生しないし、正常系(つまり運用時間の 99%)ではほとんど何も負荷がないので原理的には TCP のプロトコル限界までスピードが出せるし、ピアが死んでも救済できる。素晴らしそうに思えるのだけど、問題は正しく実装するのがめどい。つまりデータの再送はライブラリでは手助けしてくれないので、自力で正しく書くしかないのだけど、データの送信は exchange というエントリに向かって投げるのだけれど、どこまで読んだかの応答は channel というエントリから返ってくるという謎仕様(いや作りから考えれば謎ではないがまあ頭悪い感はある)になっているため、それをつきあわせたりしないといけない。</p> <p>というわけで、たとえば以下のようなコードが必要になる。本気で必要な人以外は「ああ長くて面倒ですね」「ひどいコールバック地獄ですね」ってのが理解できればだいたいOK。興味がある人は、上と比べてみてどこがどう変わっているかを追いかけてみると良い。</p> <pre><code>#! ruby require 'amqp' PendingEvents = Struct.new :tag, :retry, :xchg, :msg, :block do def publish $publishing_events ||= [] self.xchg.publish self.msg, $your_yet_yet_another_settings $tag += 1 self.tag = $tag $publishing_events.push self end end EM.run do AMQP.connect $your_settings_here do |conn| cap = conn.server_capabilities raise 'RabbitMQ TOO OLD; please upgrade' unless cap and cap["publisher_confirms"] AMQP::Channel.new conn do |ch| ch.confirm_select do $tag = 0 ch.on_ack do |ack| n = ack.delivery_tag ok = [] ng = [] if ack.multiple ok, $publishing_events = $publishing_events.partition {|i| i.tag &lt;= n } else ng, $publishing_events = $publishing_events.partition {|i| i.tag &lt; n } if $publishing_events.empty? # the packet in quesion is lost? elsif ev = $publishing_events.shift ok = [ev] end end ng.each do |e| EM.next_tick do # we need to re-send e.retry += 1 publish e end end ok.each do |e| EM.next_tick do # OK, reached e.block.call if e.block end end end ch.on_nack do |nack| n = nack.delivery_tag ng = [] if ack.multiple ng, $publishing_events = $publishing_events.partition {|i| i.tag &lt;= n } else ng, $publishing_events = $publishing_events.partition {|i| i.tag &lt; n } if $publishing_events.empty? # the packet in quesion is lost? elsif ev = $publishing_events.shift ng = [ev] end end ng.each do |e| EM.next_tick do e.retry += 1 e.publish e end end end AMQP::Exchane.new ch, $your_another_settings do |xchg| ch.queue $your_yet_another_settings do |q| q.bind xchg, nowait: false do $your_ary_to_send.each do |i| $publishing_events ||= [] e = ::PendingEvents.new 0, 0, xchg, i, nil e.publish end end end end end end end end </code></pre> <p><strong>この節のまとめ</strong> : publisher confirmation は限界近くまでパフォーマンスを引き出しつつメッセージ到達性を確保するには最適だがライブラリ側からの支援が不足している等の理由により扱いが面倒。</p> <h3>まとめ: 結局どうすればいいのか?</h3> <p>まあ、結論はない。 RabbitMQ を導入することにより得られる利便性と、コンポーネントが増えたことによる複雑さの上昇は一種のトレードオフなので、あたりまえの話ではある。最悪なのがコンポーネントは増やして複雑さを上昇させたのに利便性はさして上がってないパターンで、これは防ぐ必要があるだろう。たとえば RabbitMQ を使わないというのは立派な選択肢の一つだ。 MongoDB にトランザクションがないからといって MongoDB がゴミではないのと同様に、 RabbitMQ を使わなかったからといってあなたのプロダクトはゴミではないだろう。</p> <h3>おまけ: 正しいシャットダウンのやりかた</h3> <p>上では「ピアがふいに死んだらどうするんだ」という話をしていたが、当然、行儀の良いプログラムとしては死ぬときはちゃんと死ぬと宣言してから死ね、というのはある。それをどうやるかというと、まずqueueから取り出すのをやめて、停止したのを確認したら次にchannelを消して、消えたのを確認したら次にconnectionを消して、消えたのを確認してから死ね。つまりこう:</p> <pre><code>#! ruby require 'amqp' def setup_traps conn, ch, q %w(INT TERM HUP QUIT KILL).each do |signal| trap(signal) do q.unsubscribe do ch.close do conn.disconnect do EM.stop end end end end end end </code></pre>https://shyouhei.tumblr.com/post/39095264626https://shyouhei.tumblr.com/post/39095264626Sat, 29 Dec 2012 12:29:32 +0900やっぱ社内mixiとか社内facebookとか社内twitterとか社内LINEとかもうあるからこれからは社内tumblrっしょ、と思って企画でも書くべとワード開いたものの課金する方法がないから回収でき...<p>やっぱ社内mixiとか社内facebookとか社内twitterとか社内LINEとかもうあるからこれからは社内tumblrっしょ、と思って企画でも書くべとワード開いたものの課金する方法がないから回収できないしダメだこりゃ。アイディア放流しとくので他社さんで適当に実現しといてください。pixivさんとか。</p>https://shyouhei.tumblr.com/post/34606381864https://shyouhei.tumblr.com/post/34606381864Tue, 30 Oct 2012 09:58:15 +0900