最近のruby-core (2016年6月)

こんにちは。卜部です。

ruby-coreというRuby本体の開発の議論がされているメーリングリストがあります。

新機能やバグ報告などがだいたいここに集約されてくるので購読しておくとRubyの動きが分かります。

先月忙しかったためすっぽかしたら逆に今回量が増えて大変です。小分けにしたほうがいいのかもです。

過去分はこちら
最近のruby-core (2016年4月)
最近のruby-core (2016年3月)
最近のruby-core (2016年2月)

[#12435] Using connect_nonblock to open TCP connections in Net::HTTP#connect

Net::HTTP#connect というメソッドがあって、いまはブロッキングIOを使っているわけですが、それだと不都合がある(タイムアウトのためだけにスレッド立ち上げたりいろいろ無理している)ので、ノンブロッキングIOを使おうという提案です。わかるし、方向性は共感できる。

しかしながら事態はそこまでシンプルではない。TCPのソケットを開くときに完全にブロックしないようにするのはめっちゃむずいんですよ。特に問題になるのは名前解決でブロックしてしまうところで、これはlibcに名前解決させてる限りは、タイムアウトを制御するようなAPIはありません(glibcにはあると紹介されているが少なくともglibc固有なので移植性に問題がある)。名前解決をlibcじゃなくてc-aresとかでやればいいのかもしれないけれど、外部ライブラリ依存するのもそれはそれで微妙なので困るね、とコメントついています。

というわけで一刀両断な解決策は現状なさそうです。だれかたのむ。

[#12039] Fixnum#infinite?/Bignum#infinite or Numeric#infinte, consistent with Float#infinite? and BigDecimal#infinite?

これ進捗どうですか。だいぶ前にもうリクエスト自体は通ってるから、あとは実装するだけの気がするんだけれど。

[#11741] Migrate Ruby to Git from Subversion

またこれか。

いつも「なぜRubyはGitに移行しないんですか」とかいうスレッドが立つんですけど、結論としては簡単で、移行するモチベーションがある人がいない。外野でガヤガヤ言うだけの人がどんなにたくさんいても無意味で、きちんと結果にコミットしていく係になるだけの気概のある人が必要で、そういう人が出てこない限りは何も変わらないと思います。

[#12463] ruby lacks plus-plus

炎上狙いぽいタイトルとは裏腹に、内容は案外にシリアスでした。文法レベルでRubyに++がないのはよく知られた話ですが、だからといって実装レベルで++を作っちゃいかんという話はなくて、実際にプログラムに対してパターンマッチで++っぽいところを検出して自動的に++っぽく最適化することで、最大180%の高速化が達成できる、という提案です。

ただ問題はそういうパターンにマッチしてしまうプログラムがどれだけあるのかというところで、ファミコンシミュレータみたいなめっちゃ大量に++ありそうなプログラムに対して適用しても102%とほとんど高速化しないため、費用対効果が悪いのではないかと指摘されています。

[#12474] Wishlist for Windows Unix compatibility features

なんだっけ。どういう経緯か忘れたんだけど、WindowsとUnixの互換性としてRubyの場合ここで困っているというリストができていました。

内容はそうですねという感じですが、経緯がわからなすぎるので経緯を書いておいて欲しいです。いきなりこのリストだけあっても意味がわからない。

[#12456] tmpdir.rb raises Errors in Windows 10 Subsystem for Linux

最近発表されたWindowsで動くLinux(という言い方で正しいかよくわからないのですが)で、さっそくruby動かしてみたけど動かないよという報告が来ています。

とはいえさすがにリリース前のプロダクトはこちらからは手出しできないわけでして、開発元がんばれという話にしかなれませんでした。

[#715] Ruby interpreter should understand UTF-8 symbols with special meaning

a≥b ? :a → ¬b : ∅ などと書きたいそうです。いや、読みたいのかな?「そんなの誰も書かないんじゃないの」という疑問が出ていますがさもありなんという気がします。

[#12283] Obsolete ChangeLog and commit message in Git-style

上にも書いた通りgit移行はあんまり進んでいないのですが、そうは言っても現実的な問題として各自でgit使うのは使うわけでして、gitのコミットログでChangeLogの代替にならないかという話はこのブログの以前の回でも紹介したかと思います。

いま何が残件になっているかというと、コミットログはsvnの場合サーバにアクセスしないとローカルにはないから、インターネット接続できない時(特急やくもで移動中とか)に困るわけです。なのでChangeLogを手書きする必要はないとはいえ、ChagenLog的な何かを自動生成するのは必要とされていて、今だとその生成プログラムがない、というところまで来てます。

[#12086] using: option for instance_eval etc.

鳴り物入りで入った割にあんまり使い道が現状では限定的なrefinementsをもう少し使いやすくしたいという提案というか要望があり、これはそのうちの一つです。

なぜinstance_evalかという点ですが、refinementsを使いたい用途で考えるとだいたいRakefileみたいのである可能性が高く、そうなってくると結局eval系のやつと混ぜて使うという話になっちゃうんですね。であれば、そもそもevalに引数で渡せるようになってないと意味がない。

とはいえinstance_evalからrefinementsでメソッドの解決順をいじれるようになってしまうと、メソッド探索パスが逐一変わる危険性が出てきて、そこを都度チェックするようになると、(たとえばJRubyでは)相当なオーバーヘッドになってしまうと聞きました。

どこのあたりに落とし所がくるか注目です。

[#6647] Exceptions raised in threads should be logged

今回入ったRuby 2.4の新機能(の候補)。例外がどこからもrescueされずにスレッドの外まで突き抜けてきた時に、これまで黙って捨てるしかありませんでしたが、stderrにログが出せるようになりました。

ただ、これまで意図的に例外をにぎりつぶす用途でスレッド使ってた場合(つまりある種のサンドボックスですよね)もありえるというか、昔は$SAFEとかそういう使い方だったので、既存のコードにどれだけ影響あるかわかりません。これに関しては各位でリリースまでにきちんと試して、困るなら困ると声をあげて欲しいです。

[#12427] Defining methods with the same name to both Fixnum and Bignum classes could cause SEGV in C extensions since Feature #12005

今回入ったRuby 2.4の新機能(の候補)。これまでFixnumとBignumという別々のクラスだったものが、実装的には同じIntegerというクラスに統合されました。

FixnumとかBignumとかいう定数は残っているため、Rubyレベルでの書き直しはたぶん極小のはずなんですが、一方で実装面で大きく変わったので、Cで書かれていた部分は対応しないと壊れてしまう可能性があり、というか実際壊れていて、このようにバグ報告されている次第。

これは現時点では「壊れていることが分かった方が、なんとなく壊れたままよりもよいはず」ということになって、Cレベルのグローバル変数が削除されることになりました。この影響で、拡張ライブラリは手当てしないとコンパイルが通らない可能性があります。ぜひ皆さん確認しましょう。どうしても困るケースなどを発見した人は至急バグ報告ください。

[#12447] Integer#digits for extracting digits of place-value notation in any base

今回入ったRuby 2.4の新機能(の候補)。たとえば12345を入力すると[5, 4, 3, 2, 1]が返ってくる、といった関数が欲しいことがあって、典型的な利用用途としてはマイナンバーのチェックディジットの計算とかそういう系のやつですが、これまではあまり効率的でない(一旦文字列にしてから数値に戻すとか)やつしかできなかったのを、標準機能として提供するようにした、というものです。

とはいえ負の数のときどう動くのとかあんまり自明ではないという話はあって、そこはとりあえずDomainErrorという例外にしてあります。今後自然な定義が出てくれば定義域が拡張されるかもしれません。

[#8214] デッドロックチェックに全スレッドのバックトレースダンプの追加

今回入ったRuby 2.4の新機能(の候補)。デッドロックしたときにどこでしてるかを表示してくれるようになりました。

ただ一応解説しておくと、デッドロックの検出というのは完全にやるのは難しくて、お互いに待ってそうに見えてもたとえばシグナルで喝入れされて動き出したりする設計もありえるとか、極端なやつは色々あるので、Rubyの場合は検出しようとはしますけれど、あくまでベストエフォートです。信頼しないように。そもそも設計段階できちんとロック取り合わないように設計する(つまりリソースを共有しあわないようにする)べきです。

[#10473] Date.to_datetime.to_time != Date.to_time

Dateというクラスは日付をあらわすクラスです。一方でTimeというのは時刻をあらわすクラスです。なので、TimeからDateに変換しようとすると情報が削れる(日より細かい部分がなくなる)のはあるいみ自明ですよね。でも逆はどうでしょうか?DateからTimeに変換することは可能か?

じつはそうでもない。改暦を考慮しないといけないからです。たとえばサモアという国では大変最近(2011年)改暦があって、その年は12月30日という日が存在しないのですが、Dateでは表現できる。12月30日そのものは実在しないとはいえ、そのような概念はある以上、表現できることはおかしくないです。一方、Timeのほうは秒単位で保持している(整数で保存してるとも限らないがとにかく単位は秒)ので、秒からそういう実在しない日付が導出できない以上、Timeとしては表現できないのです。

したがってDateとTimeを変換するようなことを考える場合は改暦などを考慮しなくてもいいようにUTCにしておくべきという話になりそうです。

[#12484] Optimizing Rational

今回入りそうなRuby 2.4の新機能(の候補)。Rationalが高速化されそうです。

Rationalは、もともと太古の昔に初期実装がRubyで書かれていたということもあり、途中でCに書き直されたとはいえ、あまり最適化を意識した実装になっていませんでした。とはいえさまざまの要因から最近需要が高まってきているんで、高速化という機運になったようです詳細

今の所レビュー中のようです。諸々整理されたら入ることでしょう。

[#12020] Documenting Ruby memory model

以前から何回も(というか毎回ですかね)紹介しているこの件ですが、さらに議論が続いていて、今月はJRubyの作者が参加です。JRuby固有の事情としてJavaのスレッドでRubyと同じことを実現する必要があるので、そりゃやはりメモリモデルといった基礎的な部分に関してはかっちりと決まっていた方が嬉しいに決まっていますね。

[#12361] Proposal: add Geo::Coord class to standard library

たとえばMongoDBにあるような、位置情報データ型がほしいよというリクエストですね。

そういったものをユーザーが自作することは容易(言語側で手当てしないとどうしても実現できないものではないという意味で)なんですが、そのため逆に俺定義が乱立していて困るという主張でした。そこまでは、割とわからなくもない。

ただその解決策としていきなりGeoという短すぎる名前をトップレベルの名前空間に追加するとか、「実装したからこれを入れてください」と俺実装を添付するとかはよくなかったですね。そういった点が嫌われており、リジェクトとなったようです。

基本的な問題意識は理解するので、攻め方を考えて再度チャレンジしてほしいとおもいます。

[#9569] SecureRandom should try /dev/urandom first

この件は前回も紹介した気がしますが、その後HackerNewsで炎上してしまい、なかなか荒れた展開になってしまいました。まあ、登場人物みんな悪いよね、といった論調で語られることが多かったようです。

さておき炎上しっぱなしで放置していても何も進まない(というかOpenSSLが修正されるのを待ってても無限に直らない)のですが、現実的にはどのように落としどころを見つけるか、悩ましいところですね。

[#6946] FIPS support?

そもそもFIPSとは何かという話ですが、米国で連邦政府が規定している使っていい暗号アルゴリズムとかそういう系のやつの総称で、素人から見ると日本でいうCRYPTRECみたいな話という理解でいます。

で、それがどうRubyに影響するかというと、OpenSSLで使える暗号とかそのへんに影響が出てくるわけです。OpenSSL自体はFIPSの標準に含まれていませんが、FIPS互換性のためのモジュールが提供されているらしい(この辺りは詳しくないですので誤解があるかも)。

日本で住んでりゃあんまり関係ない話ですが、それに気づかないうちに新しすぎるcipher使っちゃうとか、あるいは逆に古すぎるMD5使っちゃうとか、そういうのがときどきあって、ときどき報告されてくるという感じになっています。

[#9999] Type Annotations (Static Type Checking)

静的型が欲しいですか。

まあ欲しいのは分かるのですが、文法レベルでクラスを指定するというのはRubyでは少なくとも採用されない(色々と理由はつけれるけど一言で言うと「そういう文化じゃない」)ことになっていて、ただニーズはあるんでしょうから、そのあたりをどのように落としどころを決めていくかというのが次のフェーズかなと思っています。inferするとかね。

[#11735] Porting String#squish and String#squish! from Ruby on Rails’ Active Support

ActiveSupportにあるsquishを本体に入れてほしい(Cで書き直した実装つき)、というリクエストです。

それはいいのだが、squish自体の用途はどこか?というところに疑問が呈されています。squishの挙動は、文字列から何かを削る挙動です。こういうのをユーザー入力などに無思慮に当ててしまうのは危ないのではないかと思うのですが。

もちろん各自が自分の責任で「俺のアプリでは問題ない」と判断するのはそれは自由なわけですが、本体に入れて欲しいってのはそれとはややレベル感が違いますよね。

[#9962] Numeric.new

Numericというのは、他の言語でいう抽象クラスのようなもので、普通に使っていればNumericのインスタンスを生成することはないはずです。

しかし、だからといって、Numericのインスタンスを作れないようにnewをつぶしてしまうと、その継承した子クラスももろともに巻き込んで全部インスタンスが作れなくなってしまうわけです。なので、newできないようにするのは無理という結論になったようです。

これはもう少しスコープを大きくすると、Rubyに抽象クラスがないことが根本的な問題と言えるかもしれません。普段はあまり問題にならないわけですし、問題あったと言ってこの程度か、という感想もありますが。

最後に

マネーフォワードでは、ruby-coreが気になって夜も眠れないエンジニアを募集しています。
ご応募お待ちしています。

【採用サイト】
マネーフォワード採用サイト
Wantedly | マネーフォワード

【プロダクト一覧】
家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』
家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 iPhone,iPad
家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 Android
クラウド型会計ソフト『MFクラウド会計』
クラウド型請求書管理ソフト『MFクラウド請求書』
クラウド型給与計算ソフト『MFクラウド給与』
経費精算システム『MFクラウド経費』
消込ソフト・システム『MFクラウド消込』
マイナンバー対応『MFクラウドマイナンバー』
創業支援トータルサービス『MFクラウド創業支援サービス』
お金に関する正しい知識やお得な情報を発信するウェブメディア『マネトク!』

Pocket