Ruby会議2015

Ruby会議2015 1日目

家で Ruby 2.3.0-preview2 のsvnタグを打ってから優雅に会場に到着し、オープニングでリリースを行う予定だったのだが、雨で時間ロスしつつ会場へのラストワンマイルで迷ったため、焦ってしまっていまいちいい感じにならなかったのが残念だった。 そもそもこの手の公開なんちゃらの類では出演者は観察されるアリになりきって何が起ころうともありのままをみせることが正義だという認識が足りなかったのがよくなかったので、今度はリリースに際して何をしているかへろへろと見せるのが正しいのだろうと思いました。

Matz

2020年までにRuby3というのがびっくり。まぁ、バージョニングはCRubyにいくつかあるMatzの専権事項の一つではある。しかし、個人的にRuby3は高速化だけじゃなく、型とMVMも入っていて欲しいなぁ。

haml

闘争本能に身を任せてコードを書くってとてもいいことだと思うんですよ。 そういう純粋な心をずっと持ち続けて欲しいと思いました。

JIT

Rubyの実行系を改善しようという試みはこれまで何度か行われてきた。

TRICK

いい感じのネタが思いつかなかったので観客でした。正規表現でSAT解く

ESM Drinkup に入れなかったよぅと泣いていたら、しばたさんがうなぎに連れて行ってくれたので、中止のはずだったUnagiAwardが唐突に開催されました。 厳正なる議論の結果、今回は r50412 dln.c: check incompatible libruby を実装したなかださんに決まりました。おめでとうございます! なお、本人は件のESM Drinkupで呑んでいたので欠席でした。

Ruby会議2015 2日目

kosaki

世界のこさきさんによる、Linux上でのデバッグ記法紹介でした。 最近ついにLinuxはprofilingやtraceの機能が豊富なことに気付いてしまったので、高速化するときはLinuxを使うことにします……。

/\Atest.*unit\z/

知られざるRubyのテストを巡る長い戦いについての話。100% compatibilityとかひどいはなしでしたね……。 さておき、紹介されていたRuby自信のためのテストライブラリtest/lib/ですが、envutil.rbとかはコアをテストするためには何が必要なのかの知見が詰まっているので、なんかそういうのを作る人(誰?)にはとても良いと思います。

fake.rb

なんか2.3だとビルド中にfake.rbを生成する際にerb.rbを読めなくてこけるという問題があってhsbtさんが追いかけていたのだが、原因も再現条件もわからなくて困っていたのです。なので、再現する環境を求めていたのですが、ついにRubyKaigiで再現できたという方を見つけたのでそらさんと調べていました。そらさんがrbenvの問題だという所まで突き止めたので見てみたら、なんかクロスコンパイルのため?にWindowsでしか作っていなかったfake.rbを2.3からUnixでも作るようになったのが原因で、rbenvの最近のバグを踏んだのだとわかったのでPRなげた Remove leading `:` by eagletmt · Pull Request #836 · rbenv/rbenv · GitHub

つづきはいつかかくかもしれない・・・

Treasure Data に入社しました

今日から Treasure Data で働くことになりました。
前職が一段落して(退職エントリ)転職を考えた時に、ちょうどtagomorisさんが何社も回った末にTreasure Dataに決めていたので、TDにしました。

もちろん物事を決めるときに理由はいくつもあるわけでして、

  • OSS開発者として暮らしやすそう
    • Twitterを勤務時間中にできるとかそのほかもろもろ
    • 知り合いの有無
  • 何を目指しているかわかりやすい
    • 目指しているところが不明瞭だと迷走しやすい気がする
  • これからの成長の余地が大きそう
  • Ruby開発に際してビッグユーザーであるTreasure Dataのユースケースを得たかった

あと、AmazonGoogleMicrosoftと戦って、その戦う武器がOSSってのがよいですね。OSS派の旗を降ろせる条件がめちゃくちゃ厳しいのがよいです。

ちなみに今心配なことは、みんなも気にするであろう英語・アメリカ関連なんですが、まぁ長期的な日本の経済状況を考えるとリスクヘッジのための投資ですかねぇ。

  • 英語(TDは、創業者は日本人だけど外資なのだ)
    • 読み書きはどうとでもなるけど、会話きびしい
    • なお、東京社内は日本語会話でした
  • シリコンバレー研修(シリコンバレー企業にはしばしばある)

なお、わたくしのミッションは入社エントリ書き…は終わったので、次はfluend for Windowsらしいです。わたしが新しいことやるとヤクの毛刈りでものすごい時間かかるんだよなー。

というわけで、ヤクの毛刈り等で相談するであろう皆様、その他この記事をご覧いただいた皆様今後ともよろしくお願いします。

Visual C++ 14 と Ruby その2

というわけで、Rubyに普通にマージして良さそうな修正は既に入れてしまいつつ、workaroundをPull Request #884 として載せておきました。なんか妙にstack over flowしますが、おおむねtest-allも動きます。
また、Microsoft Connectにfeedbackも書きました。(なお、ここで言及されている事情についてはusaさんの日記が詳しい)
さて、どうなることやら。

Visual C++ 14 と Ruby その1

Microsoft Visual Studio 2015 CTP6がでましたね。VS14ではVisual C++ Runtimeに大きく変更が入るそうで、とてもイヤな予感がしますから、ちょっと様子を見てみましょう。
Azure使いの人はMicrosoft Azure virtual machine galleryにあるVisual Studio Ultimate 2015 Preview on Windows Server 2012 R2を使うと手間が省けます。そうでない人は頑張ってインストールしましょう。インストールの際はGitを一緒に入れておくとbison.exeやsed.exeが一緒についてくるので楽です。
インストールが終わったら早速VS2015 x64 Native Tools Command Promptを起動してとりあえずcl.exeを叩いてみるわけですが、なんと起動しません (上記Azureでの場合)。cl.exeはVisual C++ 2015 再配布可能パッケージに依存しているのに、なんと愚かなことに普通はこれがインストールされないんですね。C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\1033\vcredist_x64.exe にあるので、インストールしましょう。 (注: RCでは直りました)
気を取り直してrubyソースコードを取ってきて、win32\configure.batを実行です、失敗します。これはランタイム名とバージョンを検出するツールwin32\rtname.cmdが見事に上記の変更を踏んだからですね。前向きに直して次に進みます、失敗します。よく見るとverconf.mkの \ の後に余計なスペースが入っています。これはnmake14をいじって壊したようです。困りますね。
まじめに対応するのもばかばかしいので、C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\nmake.exeを適当においてお茶を濁しましょう。 (注: RCでは直りました)

つづく

「文字列」について

「文字列を文字の列とみなす単純化」について議論がありますが、前提が抜け落ちてるように思うので書くことにします。
そもそもこの話はどのような文脈の上にあるかというと、テキスト処理 (wikipedia:en:Text_processing) の文脈になります。ここでいう「テキスト処理」とは plain text (wikipedia:プレーンテキスト) の検索・加工のことで、ここでは特に UNIX Text Processing の系譜が念頭に置かれています。つまり、複雑な装飾を含むリッチテキストではなく、処理の対象を ASCII 文字列といくつかの制御文字へと抽象化することで、正規表現のような強力な道具を用いた処理を可能とした世界です。UNIX でのお話ですから、ここでの具体的な処理の単位は char であり、全体としては char[] になります。この char の中身は上で述べたとおり、ASCII 文字列ですので、値は 0〜127 です。 (実際初期の UNIX tools は 8-bit clean ではなかった)
さて、アメリカ以外の国では (制御文字込みで) 128文字では当然足りないので、拡張が必要です。拡張の方針には

  1. ワイド文字: char を大きくする
  2. マルチバイト文字: 複数の char を組み合わせて、「1文字」にする

の2種類があります。

ワイド文字

ヨーロッパの言語ではアクセント付き文字を用いますが、これらは ASCII に収録されていません。ここで取られた策が 7 bit から 8 bit への拡大です。とはいえ、UNIX において char はたいていの場合もとから 8 bit でしたから、何か新しいものを導入する必要はありませんでした。
その後の wchar_t の導入や TRON コード、Unicode などでは、16 bit や 32 bit などのより大きな文字型が提案されています。
ワイド文字のメリットはプログラミングモデルはそのままで、型と関数だけを取り替えればより多くの文字を扱えることです。これにより、文字コードのことをよく知らない人でも国際化に対応したプログラムを開発出来ます。
デメリットは文字列型が変更されることでプログラムのインターフェイスが変わってしまうことと、ネットワークなどのバイトストリームではそのままでは使えないことになります。

マルチバイト文字

複数の char を組み合わせて一つの文字を表すようにするのが「マルチバイト文字」です。
この方法の場合、プログラミングモデルは複雑になりますが、既存のプログラムを改修する際に、そのインターフェイスを維持したまま文字数を数えるなど必要最小限の変更で日本語対応させられることがメリットでした。

世界の選択

当初、世の人々はワイド文字こそが長期的には正しい選択だと考えていました。1 wchar_t = 1文字 は明らかにわかりやすい抽象化だからです。また、単一の文字コードUnicodeを採用することで国際化は格段に容易となることが期待されました。しかし、この考えは何重にも間違っていたことがその後明らかになります。
まずはUnicodeが16bitに収まらなかったことです。これにより、シンプルな16bit固定長だったUCS-2サロゲートペアを用いたUTF-16へと改修せざるを得なくなり、複数のワイド文字 (code unit) で1文字を表すという両者のデメリットを兼ね備えた方式へと堕ちました。
また、Unicodeが本格的に IVS をはじめとした文字の結合を扱うようになったことにより、複数Unicode文字 (Unicode scalar value) を組み合わせて1文字を表す「結合文字列」を扱う必要が増し、結局プログラミングモデルの変更も必要となってしまいました。(なお、絵文字周りの話は文字コードのかなり上の方のレイヤーの話なので、今回の話とは全く関係ないと思う)
加えて、現代の多くのプログラムではネットワーク通信を扱うことが多いと思いますが、というかHTTPを扱うと思いますが、HTTPはASCIIをベースとしつつバイナリも混ざる混沌とした世界です。言い換えるとバイト列なのに文字列処理をしたいというワイド文字としては扱いづらいデータになります。(byte[]とStringの相互変換が乱れ飛ぶコードを目にした人も多いのではないでしょうか)
結局の所、ワイド文字という試みは失敗であったし、今となっては無意味な複雑化であると結論づけていいのではないかと思います。

Ruby の選択

Ruby はマルチバイト文字型のアプローチを採用しています。(「Unicode路線に見切りをつけ」たのではなく、ワイド文字路線に見切りを付けたのである)これにより、String#each_byte, String#each_char, String#each_codepoint などのメソッドを通じて、バイト列上に構築された様々な抽象化レイヤを自在に扱うことが出来ます。また、現在は要望やユースケースが皆無なために実装は見送っていますが、IVS を考慮した each 亜種も容易に追加することが出来ます。
加えて、複数文字コードを同時に扱う…ことは普通の人はやらないと思いますが、ネットワークプログラミングを行う際にバイト列と文字列をシームレスに扱うことが出来ます。つまり、HTTPヘッダ等を扱う際にbyte[]とStringを変換する必要がありません。

まとめ

ワイド文字はオワコン

Cの構造体や関数が定義された位置を表示するnadoka用bot、crubybotつくった

なにをつくったか

表題のとおり crubybot.nb ですが、その名の通りCRubyのソースを解釈して、与えた構造体や関数の定義位置を返します。返す時はGitHubのURLなんですが、まぁそこは枝葉ですな。

libclang

Cコンパイラにはプリプロセッサ構文解析構文木の構築などが含まれています。ですので、Cソースで何かをしたい場合、Cコンパイラのモジュールを使えると便利です。clang由来の便利なやつがlibclangです。

なにをしているか

find_def のあたりを見ればわかるでしょ。

まとめ

というわけで、libclangを使うと簡単にCソースで遊べるので便利です。

付録

きつねさんとおぼえる!Clang おかわり を読んだらもっと楽にできた気もするけれど、わたしは読めていません。

最近のFreeBSDのsignal trampolineの場所

しばらく悩んでしまったので、後世の人が悩まないように。

プロセスにシグナルが送られると、カーネルはsignal frameをスタック(またはsigaltstack)に積み、「signal handlerを呼び、戻ってきたら後片付けをして元々のプログラムの位置に戻る関数(=sigreturn)を呼ぶコード」を実行します。詳しくは「インタプリタとシグナル - 微酔半壊」で。
で、このコードが signal trampoline なわけですが、backtrace で得られるアドレスにもこの signal trampoline 内を指すアドレスがあります。具体的には signal handler を呼んだ直後のアドレスです(理由はDEBUG HACKSのHACK #27あたりで)。なので、FreeBSD amd64 の場合 sys/amd64/amd64/sigtramp.S がどこに置かれたか探すわけですが、sys/kern/kern_exec.c だけを見ていると実際の値といまいちずれることがあります。
理由は r217151 にて shared page なるものが導入されたからです。酷いのは、実際に確保される場所が場合によって違うっぽいことで……、[http://lists.freebsd.org/pipermail/freebsd-current/2013-November/046773.html:title=ある報告では0x00007ffffffff003だと言っているけれど」、手元では0x00007ffffffff193なんですよね……。
この問題は、r258661で実際に signal trampoline が置かれた場所を sysctl で取れるようになるようなので、それを待てば良いということになります。work around が必要ならば、shared pageの始まる0x00007ffffffff000以降のどこか、ということになりますが、まぁいいよね。