RubyKaigi 2019 Day 3 (written by t-okuaki)

株式会社ねこじゃらしの奥秋です。

このたび福岡で開催された RubyKaigi 2019 に参加してきました。参加された方々、お疲れ様でした!参加した感想と 3 日目に聞いたセッションのメモを下記に残しておきます。

感想

RubyKaigi への参加は初めてでした。これまでは「行っても話についていけないのでは」という不安から参加のハードルが高く、参加を見送っていましたが、今回思い切って参加しました。会社から旅費や参加費を出してもらえたのはありがたかったです。

参加して、Ruby という言語が目の前で作られていくのを見られたのはよい体験でした。講演の内容はやはりというか難しいものが多かったです。Ruby を作る(より良くする)話がメインなので、普段 Ruby を使うだけの私が、聞いてその場で理解するのは難しかったです。一緒に参加したメンバーは理解していたようなのでぐぬぬ...となりました。精進します。しかしなんとなく理解できたものだけでも面白かったです。Ruby は楽しく書けるようにするため、ある程度自由な書き方を許し、裏でよしなにやってくれますが、その「よしなにやってくれる部分」を実装するのにコミッターの方々が苦労されていることがわかりました。セッションの随所で「つらい」と話されていたのが印象的でした。

セッション以外でも盛り上がっていて、各スポンサーが様々な企画をされていて、楽しませていただきました。ちなみにねこじゃらしもシルバースポンサーだったりします。Official Party もすごかったです。商店街を貸し切るとか 正気の沙汰ではない 素晴らしい企画でした。

参加して得られたモチベーションをもとに今後もやっていこうと思います。最近は JavaScript と格闘することが多いですが...。

セッションメモ

下記は 3 日目に奥秋が聞いたセッションのメモです。 セッション中のメモを多少手直ししてそのまま載せています。雰囲気が伝われば幸いです。ふわっとしているところは私の理解が追いついていないところです...。おかしなところがあればご指摘ください。

💭:私の思ったこと、つぶやき

Ruby Committers vs the World - by CRuby Committers

💭 非常に面白かった。感想で書いた「Ruby という言語が目の前で作られていくのを見られた」というのはまさにこのセッションで思ったこと。

注意喚起

  • RubyGems のパスワード変更のお願い

質疑応答タイム

M: Matz C: Committer

  • 「非互換の変更に対して慎重。もっと攻めてほしい。Ruby は保守的になっていくことにどう思うか?」
    • 今の Matz の方針に賛成か?
      • (挙手を求めた結果)保守:攻める = 1:1
    • C: 古いコードを壊すのは NG
    • M: 投票は信じるな
      • キーワード引数はしょうがない
      • 福岡まで ruby の勉強しにくるひとはそもそもアグレッシブなのでそこで過半数だったとしても、採用したら炎上するよね。そして責任取るのは自分。
    • C: キーワード引数
      • 壊したほうがきれいな仕様だよね
      • ruby 3 はこれでいいとして、今後は...
        • M: 1.8 を使ってる人もいないだろうし、10 年単位とかなら古いのを壊してもいいかもしれません...ね
          • 1.8 使ってる人?(挙手を求める)... ちらほらいる
            • C: (バージョン)上げたほうがいいですよ
  • 「この辺の分野やライブラリで、担当メンテナがいると嬉しい、みたいなところってありますか?」
    • C: あんま使われてないものはそっとしておけばいいのでは。windows 対応は足りてない。
    • C: ドキュメントの Contribution がほしい
    • C: JSON のライブラリ
      • C: オリジナルな作者の反応がないので、長期的にどうしようか
    • C: Date ライブラリ
      • C: 長期的には Date を削除して Time と統合することを勧めている
        • M: 賛成
        • C: Time.parse の仕様がぼんやりしてる
          • M: (ぼんやりした仕様で)使いたいのでは
          • C: Time.parse('123') がエラーにならないのはどうなのか
      • DateTime
        • C: Rails ではカスタマイズして使われている。ActiveSupport に実装し直してもらえば...。
      • 「お客様の中で TimeZone に詳しいかたはいらっしゃいますか?」
    • C: Ruby core からライブラリに切り出している物が多いので、だれでも contributes できる
      • 本体も Git(cgit)に入りそう
    • OSS Gate というのがあるよ

開発者会議

💭 hackmd 使ってた

次回

  • 2019/05/22 13:00- pixiv

新機能の議論

新しい呼び出し(パイプ)
  • Elixir にインスパイア
  • |> :今は SyntaxError にならないから後方互換 OK
## elixir
x |> func1 |> func2
func2(func1(x))

## ruby
x |> method(1) |> method2(2)
x.method(1).method2(2)

右代入

  • M: @ だけはやめて!
  • :::
    • M: あんまりコロンが並ぶと集合体恐怖症の人が...
## ruby
x |> method(1) |> method2(2) 👉 y
x |> method(1) |> method2(2) =| y
  • 2.6 で大文字が constant、小文字が local variable
  • 3.0 で新しい呼び出しと右代入が入る...?
  • Matz にっき
    • 「バージョン上げたほうがいいですよ」
Numbered Parameters
1.times do |i,| p i end
1.times do p @1 end
1.times do p ① end
## などなど
  • 懸念
    1. 想定された動きか?
    2. @ がインスタンス変数を想起するため見にくい
      • 人間慣れるから大丈夫では
    3. 使いたいのは一要素だけのときだけなんじゃないか
  • it 使うと RSpec が...

Cleaning up a huge ruby application - by Sangyong Sim さん

はなすこと

  • cookpad_all というシステムのコードを消す話

cookpad_all

  • rails になってから 10 年
  • ruby コード 50 万行...
  • shared をベースに web, api, batch, admin, mobile がある

巨大なプロダクトだと

  • バグを治すとバグが生まれる
  • Gem が古い
  • 期待動作をしない
  • => 生産性の低下

何を消すか

  • 不要なコード
  • 不要かわからないコード
    • 実行できるが意味のないコード
    • not executed code

なぜ消すか

  • 理解するコードをへらす
  • ライブラリー依存をへらせる
  • => 生産性上がる

困難

  • コストが高い
    • ほんとに消していいかの判断
    • ruby が自由
      • alias_method_chain などで名前がかわる
    • => 取り組みは以下
  • low priority
    • => 優先度をあげる
  • どんどん glow していく
    • ほこりのようなもの
    • => 継続的に削除していく

取り組み:継続的に削除するしくみづくり

  • 「KitchenCleaner」
  • 自動検知して、issue 自動作成

取り組み:IseqLogger

  • iseq: instructionSequence
  • 何が実行されたかをログにする
  • vm_core rb_iseq_check にパッチをあてる
  • performance への影響もあまりない
  • 💭 新しい言葉が多くわからなくなってきている
  • どの iseq が使われているのか
  • 💭 どのコードが使われてるかをいい感じに調べるということか
  • ログをどう使うか
    • 💭 ログ収集中にコードが変わることがあるということかな
    • 「そんなに頑張らなくても消せるものはたくさんあるだろう」という考えでやっている
  • Good
    • template も検知できる
  • Bad
    • Ruby にパッチを当てる必要がある
    • こまかい単位での削除には向いてない
      • ファイル単位での削除に向いていた

取り組み:Oneshot coverage

  • 各行が 1 回でも実行されたかを検知する
    • Coverage.start oneshot_lines: true
  • 工夫
    • ログ送信 / 1 h
  • Good
    • Ruby 2.6 にすればパッチなしで使える
  • Bad
    • データ量が多い
    • 未使用コードがパッと分かりづらい
  • coverband gem
  • oneshot_coverage gem
    • シンプル

成果

  • 起動時間が 1.5 s 早くなるまでになった

まとめ

  • 上記困難を参照

結論

  • まあまあ頑張れば消せる

Best practices in web API client development - by Go Sueyoshi さん

スライド

自己紹介

  • sue445 さん
  • pixiv
  • gem
    • rubicure
  • SRE: site reliability engeneer

Goal

  • 失敗しない API クライアントの設計

API クライアント

  • 4 パターン

1. Public APIs made by ourselves

  • 使う側は便利
  • 作る側は大変

2. Private APIs made by ourselves

  • 「作ったこの gem を入れといて」ができる
  • dogfooding

3. Public APIs made by others

  • マイナーなやつは自分で作るしかない

4. Private APIs made by others

  • ドキュメントはエクセル、次に PDF

どこに API クライアントを作るか

  • 1 つのアプリしか使わないとしても Gem 化したほうがいい
  • Gem 化しないと
    • 密結合になってしまう
    • CI が大変
  • Gem として切り出すと
    • アプリ本体と疎結合
    • CI が早く終わる
    • シンプル

APi クライアントの責務

  • single responsibility principle (SRP)

API クライアントで作るもの

  • パラメータの変換機能(は API の責務)
    • 時刻の変換
  • Ruby クラスに エラーコードをラップ
    • faraday gem
    • サンドイッチメソッド(書籍:refactoring: ruby edition)
  • OAuth2 access token の自動更新

API クライアントでつくるべきでないもの

  • API response を一定時間キャッシュすること
    • memcached
    • メンテが大変
    • アプリ側に作るべき
  • request params validation

いままで作った API クライアントとその TIPS

  • pixela
    • pixela の api
    • データを "草化" できる
    • Tips
      • keyword args を使う(引数 1, 2 個でも)
        • アプリ側の変更に柔軟に対応しやすい
  • chatwork-ruby
    • ChatWork の API クライアント
    • Tips

7 good patterns

  1. 依存をなるべく少なく
  2. Faraday は銀の弾丸
    • faraday_boolean gem
  3. 主題を目立たせる
  4. prefer keyword args to hash args
  5. パラメータオブジェクトの導入
    • 引数に配列やハッシュを渡すと、コメントが書きにくい
    • パラメータオブジェクトなら
      • YARD でコメント書きやすい
      • パラメータオブジェクトにメソッドをもたせられる
      • テストを書ける
  6. メソッドでアクセス可能なレスポンス
  7. curl は万国共通

The future of the Bundled Bundler with RubyGems - by Hiroshi SHIBATA さん

  • 💭 登壇者に Asakusa.rb に参加されている方が多い気がする。

なんで bundler を Ruby にマージしたいか

  • 「最初に入れる Gem は Bundler」をやめたい
  • 去年の進捗
    • マージは進捗なし
    • RubyGems 3 が ruby 2.2 未満のサポートを切る
    • Bundler 2 をリリース
  • RubyGems 2.7 には Bundler が integrate される
  • Ruby 2.6 以降は必ず Bundler がある

Ruby 2.6

  • RubyGems 3
    • 2 ファクター認証対応
    • deprecated なコードを削除
  • Bundler 2
    • Gemfile から gems.rb にする案はなしになった
    • ruby 2.2 未満のサポートを切った
    • build matrix が小さくなった
  • ruby 本体にマージするため
    • bundler のテストを miniruby で実行できるようにした
      • これで RSpecRuby 本体に入れられる
      • すごいこと
  • Bundler のテストが大変
    • 外から叩いてエラーをパースして... みたいな感じ(?)
      • => 実行時間が長い
    • どうしても正しい結果が得られないテスト
      • Ruby がインストールされている前提のテスト
        • miniruby で実行しないといけないので
        • そういうのはスキップ
  • the location fo execution wrapper
    • gem wrapper と original executable
    • gem update で Bundler の「オリジナルファイル」が消え去る
  • Update BundlerVersionFinder
    • e.g. 1.17.1 なら 1.x.y がマッチ

Ruby src に bundler をマージ

  • Heroku で問題
    • 当時 Heroku は Bundler 1 しかサポートしてなかった
      • 使う Bundler を 2 から 1 系に直してリリース
      • 今は Bundler 2 系も対応

リリース後の問題

  • LOAD_PATH が変になっている
  • The invalid gemspec generation issue
  • The bundler switcher issue of Heroku
    • 上記
  • Ruby 2.6.3 は最高
  • rubygems と bundler で SSL 証明書が重複 → fixed
  • rubygemsjson-2.1.9 を require すると 1.8.x が使えない

RubyGems 4 の展望

  • 非互換の変更
    • conservative option をデフォルトにしたい
      • インストールされていたらインストールしないオプション
    • default オプションの動作の変更
    • --user-install をデフォルトにしたい

Ruby 3 に向けて

Timezone API - by nobu さん

Timezone

  • UTC との差分を表現
  • TZ 環境変数
  • IANA tz dtabase が管理
    • "Area/Location" の形式

Time クラス

  • (C の)time_t のラッパー
  • 3 models
    • UTC
    • Local time (system 依存)
      • Time.now
      • Time.new, Time.local
      • Time.at
      • Time#getlocal
      • Time#getutc
      • Time#+, Time#=
    • Fixed offset
      • 1.9.2 から
      • Time.new( ... "+09:00")

2.5 まで

2.6

  • Time.find_timezone をユーザが定義すると Time.new( ... "Area/Location") とできるようにした(?)

interface

  • local_to_utc method
  • utc_to_local method
  • name
    • Marshal.dump/load (?)
  • abbr
    • Time#strftime の問題

質疑

  • in の命名について議論

The send-pop optimisation - by Urabe, Shyouhei

💭 初めて聞く概念が多くて正直わからなかった...。内容としては「メソッドの返り値が使わずに捨てられることをなくせばパフォーマンス上がるのでは?」という仮説を実証した話(のはず)。

結論

  • 「send-pop」を自動で検知して最適化して早くした

インストラクションシーケンス

  • send して pop している

ruby

  • 使われるかわからない戻り値
  • 使われない戻り値を捨てるとき send-pop
  • mame/optcarrot

mame/optcartot で測定

  • leave -> pop
  • 2-grams

最適化 first step

  • 意味のある値を返さなくてもいい
  • 戻り値が使われているかを呼び出し側に伝える
    • 伝えるためのフラグを用意
    • フラグをどのように使うか
    • 自動化
      • "pure" という概念
      • メソッドの末尾にある pure な部分があれば、....

C API

  • C で書かれている部分はコンパイルされていてどうしようもない
  • スペースを消す場合、スキャンしたスペースには興味が無いため、最適化の余地あり

無駄な pop を消したい

  • 常に可能ではない
    • 可能なものを区別するためのフラグを用意

return value を push しない

  • 3 つ の return value
    • C method retrun value
    • あと 2 つ
  • ブロックの中でリターンする場合が大変

ベンチマーク

  • make benchmark の結果
    • 一部項目で明らかに早くなっている
    • 明らかに遅くなっているものはない
  • mid-sized benchmarks
    • time make rdoc は若干遅くなった
    • optcarrot は若干早くなった
  • discourse/discourse (Rails application) ... アプリのなかにベンチマークがある
    • ちょっと早くなったか同じ

質疑

  • 遅くなる原因
    • rdoc だと、プロセスの起動で遅くなるなど

関連記事

RubyKaigi 2019 各日程のレポート

1 日目:中山村上 2 日目:市川 3 日目:古川、奥秋(本記事)

また例年動画で各セッションの様子が公開されているため、今年も公開されるか要チェックです。

ねこじゃらしについて

ねこじゃらしでは Ruby (Ruby on Rails) や JavaScript での開発経験がある Web エンジニア、また、ネイティブエンジニア、UI/UX デザイナを募集しております。

ご興味をお持ちいただけましたら、以下のリンクからお問い合わせください。

www.nekojarashi.com

RubyKaigi 2019 Day 3 (written by r-furukawa)

RubyKaigi 2019 Day 3

はじめまして、株式会社ねこじゃらし エンジニアの古川です。

今回福岡にて行われた RubyKaigi の Day 3 report を行わせていただきます。

私は今回が RubyKaigi が初参加でしたので、初参加なりの感想 (もしかしたらいつもの RubyKaigi どおり、かもしれませんが) を書かせていただきます。

Sessions

今回 report する session の一覧です

Ruby Committers の session で、主に参加者からの質問や、現状構想中の ruby information に関して

アジャイル開発型企業特有の、無意味なコードが膨大に増えてきたときの refactoring 方法 (その手引き)

今後 Ruby に実装される予定 (正確には外部実装だが) の目玉 rbi type checking の実装に関して

現状 rubyist たちがこぞって入れている bundler を RubyGems と共に ruby に梱包しようと言う取り組みに関して

-> 飛行機に乗る都合で最後の session は聞くことはできませんでした...

Ruby Committers vs the World

質問 (抜粋)

  • 最近 ruby は保守的 (非互換性に対して気にしすぎ) なのでは?

これに関しては、 matz 氏以外では大多数の人が もっと攻めた実装を行って欲しい との意見だったよう。かく言う私もそのような意見でした。しかしながら、それを実現するためには様々な施策 (安定板サポート期間の延長・拡大等) が必要だが、そのための人員不足や知識を持った人が行う必要性など、考慮すべき問題点が複数存在する。とは言っても、

しかしながら、 keyword 引数に関しては、後方互換性など考えずに、どうにかする必要性がある。

とのことで、どこかのタイミングで大きく既存の仕様を変更する必要がありそう。

また、今回様々な session とも関係する Ruby 3.0.0 の実装では、

後方互換性を意識して、本来の美しい仕様を壊してしまった。

とのこと。

それも含め、既存の仕様からの変更は 4.0.0 に着手することには、初めていきたい、とのこと。

  • 特定のライブラリなどでメンテナンスが行き届いていないのでは?

しかしながら、メンテナンスが行き届いていない上で bug が見つかっていないのは、誰にも使われていない証拠なのでは?とのこと。誰にも使われないような機能に対して、メンテナンスの為の人員を投入するのは人的リソースが厳しいらしい。

しかしながら、今後の実装 (GVL・MJIT の一部) に関しては、現状メイン開発者がメンテナンスをする気がないらしい。

また、 JSONCSV 等の非常に使用率の高い汎用公式 gem に関しても、メンテナーとの連絡がつきづらく、少し不安なよう。

Time に関しては、どんどん仕様が曖昧になっているようで、今回の議題としては Time.parse '123' が error してくれなくなった、とのこと。これはつまり、 123 という string に対し、 Ruby に何を求めているのか、 ruby committer もユーザも曖昧な状態を指している。

これを受け matz 氏は、

人間が時間を曖昧に捉えていることの表れ

とし、ある意味 developer friendly の現れなのかもしれない そんなことないか...

また、余談だが、 Ruby 本体の repository が SVN から git に移動する予定の様 githubには、歴史的背景により行かない様だ

開発者会議

  • |>

ある意味観客の興味を一番引かせた内容であったかもしれないのが新 syntax である |> だ。

これは、 matz 氏の構想レベルの話で、まだ仕様などは決まっていないらしく、それを相談することも会議の一部の様だ。

今まで ruby の記法での

b(a(x))

x |> a |> b

として記述する syntax で、 Elixir から着想を得た様です。

また、この様な新 syntax の実装の際に話題となる、 @ の扱いに関して、今回も使用したく無いとのこと。

また、上記記法で実行順番が右辺への代入を行っている為、最終的な戻り値も右辺への代入で記述できる syntax の方がいいのでは?とのこと。

その為、

x |> a |> b => y

の様な右代入式で y への代入も行える様に仕様修正も行うかもしれないらしい。

  • Numbered parameter

@1 の様な記法を用いた、簡略記法の提案で、こちらも matz 氏からのもの。

1.times do |i ,| p i end
1.times do p @1 end

上記コードは共に同様の結果を出力するもので、この様な動作を期待するコードが書かれがちであるために考案したとのこと。

しかしながら、ここでも @ の扱いについて討論が始まり、様々な意見が出た。

感想

  • 最近 ruby は保守的 (非互換性に対して気にしすぎ) なのでは?

私としても、 matz 氏の提案する様な新しい syntax が多く取り入れられた方がいいと思うし、それ以外にも後方互換性を多少度外視した実装が存在してもいいと思っています。

しかしながら、職業で Ruby を使用している以上、やはり互換性の問題は常に付きまとい、心ではそう思いながらも、実際に大幅な仕様変更があった場合自分に降ってくるのは明白…

なんとも言い難い状況ですが、それでも新機能・新 syntax に関してはどんどん追加してもらった方が嬉しいかな、とは思います。

  • |>

この仕様に関して、私としては非常に面白いのでは無いか?と思っています。

その理由として、 Ruby では主に右辺の戻り値を元に左辺の評価を開始する記法が多く、その逆を用いることはコードの幅を広げるのでは無いかと考えている為です。

後置 if など、その式に最も会う記法を選択できのは Ruby の特徴でもある為、この様な選択肢の拡張は非常に好感が持てます。

  • Numbered parameter

これに関して、議論の中ででた 扱える変数を一つに限定して it (他の妥当な単語でも可) とする と言う案に共感しています。

と言うのも、正直この様な記法を用いることが多い部分では、複数の値を操作したいことはあまり無い。単数を持つことが多いのであれば、不必要に多くの可能性 (nil が帰ってきそうな後続の変数名) を増やす必要は無い。と考えている為です。

開発者会議の内容に関しては、特に興味を引くもの (主に syntax) が多く、今後の Ruby version に対しても期待を持てる内容でした。

Cleaning up a huge ruby application

着手理由

cookpad エンジニアの Sangyong Sim 氏は、 cookpad サービスの基盤となっている cookpad_all の Ruby on Rails コードに対して、 bug を消すと bug が増える, 既存の gem 等を patch している為、期待通りの動作修正が行えない, test がいつになっても終わらない 等のことから、不要なコード削除の必要性があるとのこと。

また、不要なコード削除の必要性として、

読むコードは少なくなり、修正を行う際の効率にも関わる。 gem への patch での不必要な依存性や、 test の実行速度の改善に役立つのでは。

と説明しています。

  • なぜ進まないのか?

しかしながら、実際にその様な活動 (不要なコード削除) を始めたところで一向にコードを削除できなかった、とのこと。

なぜなら、コードを削除するためには、 そのコードが、全体に対して不必要であることの証明 が必要であると、語っていました。

また、 Ruby 特有の自由性によって method を全文検索したところで、証明できない ことも語っていました。 Ruby では、 alias_method_chainsend の様な、 method 名を隠して実行する様な操作も可能であるため、証明が難しいとのこと。

しかしながら、これを行う必要性があることは確信しているため、この問題の優先順位を上げ、継続的に行う仕組みを作成することが必要であると提起していました。

解決方法

この問題において、本 session で上げられた内容は主に 継続的に行う仕組み不必要の証明 です。

そのため、二つの方法を試行した様ですが、結果的に現状使われているのは Coverage を用いた方法のよう。

  • Coverage.start oneshot_lines: true

CoverageRuby 2.6 系でサポートされたライブラリで、 load した Ruby ファイルのコードに対して行レベルで実行の hook を行います。

これを用いることで、対象のコードに対して コードのどの部分が実行されたか を result として受け取ることができる様になります。

また、 oneshot_lines option は、この hook を最初の一回のみに限定するもので、これを用いることで log 収集の overhead を大幅に削減できます。

この手法を用い、実行情報を NoSQL へ保存し、実行されることのなかったコードを抽出する様な仕組みとなっている様です。

また、この様なやり方にした理由として、他の方法では overhead も考えると cruby への patch を当てる必要があった。とのことでした。

また、この Coverage では、そもそも行レベルでの情報を収集できるため、結果も細かく読み取ることができる様になる。とのこと。

感想

この様な不必要なコード削除は、弊社でも問題となっています。

その為、この session の内容はかなり興味深く、実際に取り入れる場合の模索なども行いました。

また Sangyong Sim 氏が、やり方など以上に特に推していたことが この様な対応の優先順位を上げること だそうで、実際に直近のメリットが感じ辛い対応である為、実践する必要がある様に感じました。

The challenges behind Ruby type checking

内容

この session では Ruby 3 系に追加される予定である、外部 type checker である .rbi ファイルの syntax などに関する経過報告です。

type checker を今回実装するにあたって、 ruby では重きを置いている Duck Typing に影響が無いか。も重点的に考慮している様です。

Ruby では type checker の種類が多岐に渡り、実際に運用するのが他の言語と比べて難しい理由として、 eval, has_many (active_record) などの様なコードの仕様が変更される meta-programming が多く存在している為であると説明されていました。

また、現状開発済みである .rbi の syntax として、以下の様なものを発表していました。

Integer # instance
singleton(Integer) # signleton
Array[Integer] # generic
Hash[Symbol, String] # generic
Integer | String # union
any # dynamic
nil # Base types
bool # Base types
void # Base types
Integer? # optional
1, :hello, 'world' # singleton type
[Integer, String] # Tuple
{name: String, email: String?} # record
^(Integer, String) -> void # Proc

また、 Demo として実際に IO.open.rbi にて type check する場合の記述も公開。

しかしながら、実際の .rbi ファイルを IO.open に適用すると、考慮すべき対象が多すぎ、非常に大量なコーディングが必要な様。

既存の gem (Rails など) に対して type check を付与した gem を公開できる機構も必要であるとのことでした。

  • sorbet, steep

既存の type checker である sorbetsteep に対してもサポートする予定である様で、それぞれの内で存在する公理を満たす様に設計する必要があるとのこと。

感想

.rbi ファイルに関しては以前から話に出ていましたが、実際の syntax をコードレベルで公開されるのは初めて?の様で、今後のコーディングパターンを想像しやすく、有用な session でした。

また、既存の type checker に対してのサポートなどを鑑みるに、今から sorbet などを利用することもアリなのでは…と

私の方で最も心配していたのが既存 gem への対応で、今回 session では type checker も内包した状態の gem を公開する様な仕組みに関しても言及していた為、うまく使っていければかなり有用になるのではないか、と感じました。

The future of the Bundled Bundler with RubyGems

内容

RubyKaigi 会場であった Ruby で最初に入れる tool 投票 で見事一位になった bundler のお話。

また、上記投票からのフィードバックを含め SHIBATA 氏は、

Ruby を入れて最初に install するのが bundler であるならば、それは Ruby に含まれている方がいいのでは

とのことでした。

それも踏まえ、 RubyGems, bundler が古い gem に対する support を切ったことを皮切りに、すでに Ruby に内包されている RubyGems の様に bundler も cruby へ merge する様に作業したとのこと。

また、これらはそれぞれが Ruby の内外に存在している為、使用する変数に差異が出てしまったりする。しかし、どちらも Ruby に merge されている状態になれば、 bundler 特有のエラーなども起きず RubyGems との摩擦も軽減できるはずであると、このプロジェクトの必要性を説明していました。

感想

実際のところ私も bundler は Ruby のお供として、常に使用している為 Ruby に内包されていた方がいいのは自明であると考えています。

また、 bundler が意味不明なエラーを吐くことも Ruby 外部の tool であることが原因の一つで、この問題が早く解決されるのであれば非常に嬉しいと思っています。

全体の感想

今回の RubyKaigi では、やはり Ruby 3 系へ向けての session が多かった様で、特に type checker などの設計は sorbet からも説明がありました。

私としては、新しい syntax も興味がありますが、 MJIT, Guild などの改善要素にも興味があり、現状弊社で使用している Ruby の version up も検討しています。

Ruby 3 系への乗り換えは、非常に困難を強いることになる様な気もしますが、なるべくならば、最新安定版を使用できる用にしたいと考えていますので、今後の発表にも注目しなくては、と思いました。

また、 Ruby 3 系では、上記に挙げた様な改善要素が複数入っている為、コード全体のリファクタリングなどを行い、 Ruby 3 系に適したコードにしていく様な展開もできればなぁ、と思っています。 できるかは別として

ってかそもそも今の最新安定板にversion-upする仕事があるのですが...

Rubykaigi 2019 Day2 レポート

Rubykaigi 2019 Fukuoka

どうも!皆様初めまして!
株式会社ねこじゃらし の エンジニア スクラムマスター 市川です!
2019年4月18日から 3日間、福岡県で開催されている Rubykaigi2019 に 弊社エンジニアと共に参加させて頂いております🙇
昨日、1日目の内容について、中山村上 が記事を書いておりますのでそちらもぜひ御覧ください!

私の方では、2日目についていくつか書かせて頂きます!

All bugfixes are incompatibilities

登壇者: nagachika ( @nagachika ) さん

f:id:nekojarashi-Inc:20190421090639j:plain
公演の様子

このセッションに入る前に RubyGems.org から重要なお知らせがありました。 RubyGems.org のアカウントがハックされ、悪意のある Gem がリリースされる事象が発生しているので アカウントをお持ちの方は、パスワードの変更を行ってほしいとのことです。

セッションの内容としては、Ruby の安定化メンテナンスとしてどのようなことを普段されているかという内容でした。

Ruby の ブランチ運用について

Ruby のブランチ運用では、Trunk をベースに開発を開発を行っていて Trunk から 安定版のブランチを切り出しているそうです。
作成された安定版ブランチには、1人ずつ安定化メンテナーがつき Trunk にて修正された bugfix を様子を見ながら、各安定ブランチ へマージを行っているとのこと。
ちなみに安定版ブランチが Trunk に戻ることはないそうです。

安定化メンテナーが普段されていること

上記で話されていた、bugfix を 安定版ブランチへマージする 部分等のより具体的な話になりました。 中でも印象的だったのが
メンテナンスを行った時の失敗談の内容で
修正されたパッチの修正内容がとても綺麗だったので、思わずマージしたら処理が重くなってしまったため revert した
ってエピソードがエンジニアらしいなと思いとても印象的でした笑

Better CSV processing with Ruby 2.6

2つ目のセッションは
Ruby 2.6 で CSV が早くなった話

登壇者: Kouhei Sutou (@ktou) さん、 Kazuma Furuhashi (@284km)さん
このお二人の掛け合いは、コントのようなやり取りで進む発表方法でとても面白くめちゃくちゃ笑わせて頂きました笑

CSV の Parsing 速度向上について

Ruby2.5 と Ruby 2.6 のCSV の Parse の速度についてご説明されていて シンプルな CSV だと
1.7倍 💨

ダブルクオートが含まれる CSV だと
2倍弱 💨

,(カンマ) の内側に ダブルクオートが入っている CSV だと
1.5倍 💨

開業コードが含まれている CSV だと
3倍 💨

上記のような速度改善となっているようです。

CSV の Writing 速度向上について

今度は Write の 速度について

generate_line を用いた場合
2.4倍 💨

<< (左シフト) を用いた場合
1.6 倍 💨

上記の結果を見ると generate_line  を用いたほうが早いように見えますが↓

generate_line vs << (左シフト)

Ruby 2.6 だと 約7倍 💨
Ruby 2.5 だとなんと 10倍 💨
左シフトのほうが早いという結果になってました。
なので、書き込みを行うのであれば左シフト推奨とのことです。

CSV Parsing Writing のまとめ

Parsing については、1.5 ~ 3倍 💨

Writing については、1.5 ~ 2.5倍 💨

CSV の読み書きについては、様々なシステムで関わってくるので、こういう速度改善は本当に大切ですよね。

intimate Chat with Matz and mruby developers about mruby

登壇者: isshi さん with Matz さん Yamaneさん (nora mrubyist)

mruby について ishii さん と Matz さん、そしてゲストの Yamane さん お三方の対話形式による発表でした。

yamaneさん について

nora mrubyist という肩書(?)とのことで
nora mrubyist と名乗っている理由は、仕事で ruby を使っているわけでもなく趣味で mruby を使われているからとのことです。
具体的には ロボコン で使用するロボットのプロブラムに使用しているそうです!

mruby を作った背景

経緯としてははじめ国から『なにか冒険的なことを始めるための制度』があるのでそれを活用するために
福岡県と協力して、『軽量 Ruby プロジェクト』 として始めたのがきっかけ。

mrubyを作っていく中で、 Matz さん も大変だったみたいで
ギブアップしたいと漏らしていたとおっしゃってました。

『0から作るのは大変。差分の開発は数日で終わる。0 からの開発は最初は全然動かいので、"きっとこれは未来に動く" ってモチベーション管理が大変だった。』

と言っていて本当に作るのに苦労されたんだなってことが伝わってきました。

mruby 開発プロジェクトにかかったプロジェクト費用は
1億3000万円くらいかかったそうです。
めっちゃ費用かかったんですね

mruby は ruby の反省点を踏まえながら開発されたそうで ruby よりもメモリ管理に気を使うように作っているそうです。

ruby と mruby の違いについて

ruby = All in one!
それに対して
mruby = myruby!

mruby は、組み込み先のメモリ容量などを考慮した上で、必要なライブラリを選択し 自分用にカスタマイズした ruby を作れるようです。

ちなみに mruby が主に活用されているものとして、ロボットや人工衛星があげられます。

追記:番外編 ( Rubykaigi 開催中に食べた美味しいご飯 )

Rubykaigi 開催中に色々なものを食べました! どれも大変美味しかったので紹介させて頂きます!

株式会社ドリコム さん が YataiSponsor として Rubykaigi に屋台を出していて、そちらで食べたご飯になります↓

f:id:nekojarashi-Inc:20190421093712j:plain
ruby ラーメン

f:id:nekojarashi-Inc:20190421094259j:plain
うどん (何うどんだったか美味しすぎて名前をわすれてしまった・・)

f:id:nekojarashi-Inc:20190421094454j:plain
焼鳥丼

どれも大変美味でした(๑´ڡ`๑)

また、会場以外でも食べました !

f:id:nekojarashi-Inc:20190421095217j:plain
久留米ラーメン ( スタイリッシュ?バージョン)

f:id:nekojarashi-Inc:20190421095313j:plain
久留米ラーメン ( 昔ながらのこってりバージョン )

番外編のほうが写真が豊富
そしてほぼ麺類

本当にどれも美味しくって麺類以外にも色々食べてみたくなりました笑 また 福岡 に来る機会があったときはもっといろんなものを食してみようかと思います🍴

感想

今回 Rubykaigi に初めて参加させて頂くにあたって不安な点がありました。
昨年、ねこじゃらしに入社してすぐに スクラムマスター として仕事をするようになり、しばらく仕事でコードに触れていなかったので
正直 Rubykaigi に参加して参加者の皆さんとお話できるだろうか・・・と少し不安でした。

しかし、懇親会等でお話してくださった方々に
『え!めっちゃ大変じゃないですか!』や『スクラムマスターが技術のこともわかるってとても大事ですよね。』
等々暖かく 受け入れていただけて、Ruby界隈ってすごく優しいコミュニティが構築されているんだなって実感しました!

今回の Rubykaigi 中に個人的に嬉しかったことがありました。 1日目の商店街を貸し切った懇親会時のことですが、近くに まつもとゆきひろさん がいらっしゃったので思い切って話しかけてみました!
実は、私は 10年ほど前に まつもとさんとお話する機会がありまして、その時のことを覚えていらっしゃるか聞いてみた所
『 OSC のときですよね?覚えてますよ!懐かしいですね!』
と覚えていてくださっていて大変嬉しかったです。
相変わらずとてもお優しい方でした。
まつもとゆきひろさん 、貴重なお時間を頂きありがとうございました!

まだ最終日がありますので、最後まで楽しんでいこうと思います! 3日目についても、弊社エンジニアの 古川・奥秋 からレポートがあがると思いますので そちらもお楽しみに!

それでは! 最後までお読み頂きありがとうございました。 そして、Rubykaigi を運営されている皆様、登壇された方々、懇親会でお話させて頂いた方々
楽しいイベントを本当にありがとうございます!

RubyKaigi 2019 Day1 レポート「 The Matz Keynote! 」

はじめに

株式会社ねこじゃらし エンジニアの村上です. 株式会社ねこじゃらしは2019年4月18日から21日にかけて福岡で開催される RubyKaigi 2019 のシルバースポンサーです. その一日目に参加してきたので,感想などを簡単にまとめようと思います. 他の講演内容に関しては同僚の中山さんが記述されているようなので,そちらに任せ, 本記事では Matz の Keynote について記述したいと思います.

Keynote

Day1 の KeynoteRuby の生みの親である Matz によるもの Keynote のタイトルは「 The Matz Keynote! 」 前回の RubyKaigi 2018 では ”名前重要” など Ruby という言語コミュニティが大切にすべきコンセプトについて話しており,割と抽象的な話がメインだった 今回の RubyKaigi 2019 では Ruby3 の話がメインとなっており,前回よりもテック寄りな内容になっていた 以下にその内容をまとめていく.

現在の Ruby について

始めにアイスブレイク的な話として,現在の Ruby について語られた

Ruby is ~

Ruby is Good

Ruby はいいと言われている

  • Productive
  • Flexible
  • Fun

Ruby is Bad

一方で Ruby は悪いとも言われている

  • Performance
  • Multi-Cores
  • Bigger Team/Project

Ruby is Good Enough

それでも Ruby は大体のことには十分に良い

よく遅いと言われるが,上記のような複数の大きなサービスに利用されており,かつ実用レベルなことを考えると Ruby は十分に早い

RubyTwitter

Ruby の話をするときにいつも Twitter が引き合いに出される

TwitterRuby をやめたから Ruby はもうダメだと言う人がいるが, そもそも Twitter のようなサービスに Ruby は向いてないし, 10年経っても Ruby は全然生きてる

Ruby の実行速度

Ruby1.8 は遅かったけど, Ruby1.9 以降はだいぶ早くなった. Ruby2 は2013年にリリースされたが,性能改善を続けてきてちょっとずつ性能は良くなって来ている Ruby3 はより頑張る

Ruby3 で改善されたこと

ここから本題

Ruby3 で大きく改善された3つのこと

  • Performance (性能)
  • Concurrency (並行性)
  • Static Analysis (静的解析)

1. Static Analysis

1つ目,先に静的解析の話から

Ruby のスタンス

最初に Matz のスタンスについて話があった その後,他の言語における静的解析について話があり, Ruby のスタンスについての紹介された.

Matz はテストが嫌い

本当はテストを書きたくない 「It's not DRY. (DRY じゃないから)」

テストの記述量が少なければ機能の実装に集中できるのでとても生産的 でも人間はミスをする生き物だからテストを書かざるを得ない

他の言語はどうしているか?

他の言語は静的解析にどのように取り組んでいるか? → 型注釈を導入している

  • Python: Type Hints
  • PHP: Typed Properties
  • JavaScxript: TypeScript

など,型注釈は最近のトレンドっぽい

じゃあ Ruby はどうするか?

型注釈は入れない 他の言語は入れてるけど入れたくない 型注釈嫌い 「It's not DRY. (DRY じゃないから)」

DRY じゃないものをタラタラ書くのはコンピュータに仕事させられている感じがある 人間がコンピュータに仕事させるべき テストは妥協するけど静的解析には妥協しない

Ruby3 のプラン

型注釈はやらないけど,型チェックはやる

Ruby3 では4つのコンポーネントを入れようとしている

  • 型定義文法
  • ライブラリの型定義
  • Type Profiler
  • Static Type Checker

型定義文法 (Type Signature Format)

ruby のコード自体は変えず,外部に型を定義するファイル(.rbi)を用意する rbi File は自分で書き直すことが可能

Type Profiler (Level-1 Type Checking Tool)

Type Profiler で警告する 型の情報を集めて,すでに定義されている型情報と矛盾があればエラーを出す 自動生成は頑張っている.けどできてない

ライブラリの型定義 (Type Signature Prototyping Tool)

型推論のようなことをする,実際は違う

Static Type Checker (Level-2 type checking tool)

トラディショナルなやつ

  • Sorbet
  • Steep

など. Sorbet は Fast で Nominal だけど Ruby っぽくない

こういうの入ると型注釈を書かなくても型チェックすることができる

Ruby3 の型チェック

型チェックについてはすげぇ頑張ってる 各内容については個々の講演を参照してね 3.0 は期待していいよ

2. Performance

二つ目, Performance 改善の話 Performance (性能), Concurrency (並行性), をまとめて

プログラミング言語の悲しき運命

そもそも,どんな言語も早すぎるといわれることはない どんな言語も遅いって言われる ただ ruby は伝統的に遅いって言われる 😢

より多くのトラフィックを処理するには

mruby とか JIT の開発を手伝って頂いている中国の方と話した結果,以下のような知見を得た.

Memory is the First Bottleneck

GC の改善が重要

Fragmentation の改善は意外と容易

しかし,実際の問題はそれだけに留まらない

Memory is not the only Bottleneck

→ CPU とか I/O も Bottleneck になる

Just in Time Compiler の存在

MJIT を去年導入した

良い点 - Portabele - Reliable - Optimized

悪い点 - Heavy - Inefficient(Memory-wise)

CPU ボトルネックに関して, 2.6 は 2.0 に比べて8倍早い ただ, Rails に関しては遅くなる (MJIT Runs Slower)

理由はいくつかある 非常に沢山のメソッドをコンパイルする必要がある たくさんのスレッドが起動している など

Multi-Cores の活用

去年,マルチコア活用に関してはあまり進んでいなかった 今年はがんばる

WWW はもともとマルチコアに向いている

今の Ruby は Thread, Fiber を持っているが,ボトルネックの改善は難しい

より良いコンカレンシーモデルの提供

状態を共有しないのが重要 Shared State は良くない

Erlang / Elixer は Data Immutable なので安全 Immutable は良いけど,今更 Ruby に導入できない(そもそも Ruby は出自が違う ) その代わり Guild を導入した

Guild は分離されたオブジェクト チャンネルの受け渡しはイミュータブル

Guilds ≒ actor Guilds ≒ Web Worker(JS) Isolated Block これ導入するとマルチコアを有効に活用できそう

慣れるまでは使いづらいけど……

I/O 改善

Non-blocking I/O が重要

Node.js を参考にしてる

AutoFiber I/O 操作のコンテキストスイッチが今までの Ruby のように時間で切り替わらない.

Avoid I/O blocking

AutoFiber が導入されたら現在のスレッドはだんだん消えていくだろう というか Ruby にスレッドを入れたことは後悔している…….

マルチコアとかマルチスレッドの時代がくるとは思わなかったんだもの.

名前決めで紛糾

Guilds(Isolates) AutoFiber(AsyncWhatever) 名前と役割が異なるから名前決めで紛糾している

他の言語は一つしかないよ

  • Go: goroutine
  • Elixir: process

他の言語は初期からそういう設計してるけど, Ruby は違うから使い分けるしかないよね 今までの Ruby を動かなくするわけにはいかない

われわれに必要なのは名前

Static Analysis Keeping Compatibility 互換性を維持しながら,いろいろ発展していきたいよね

Guilds って名前はゲーム業界からすげぇクレーム来てるけど……

3. まとめ

以下,まとめ

今回導入されないもの

Frozen Sting Literals(3.0 では導入されない,断念した) Obsolete '?' Literals(3.0 ではなくならない) Obsolete Backquotes(3.0 ではなくならない)

Keyword Argument は変える 静的型づけと相性わるそう……どうなんだろ?

Numbered block parameter [1,2,3].map{@1 *2} 一番目のパラメータにアクセスできる もう入っているけど紛糾したので考えさせて. (@ はインスタンス変数に見える)

関数型言語の)パターンマッチングについて

昨日マージされた.ぜひ試して秘孔を突いてみて.

Ruby の今後

我々は生き残らなければならない Ruby 好きだし,仕事なんすよ,ご飯食べないと Python とか JavaScript とかに行きたい人は行けばいい ただ, Ruby がこの先生きのこるために賢く選択していく

ユーザに Ruby を使い続けてよかったと思って欲しい 前進し続けたい 闇雲進むのではなく賢く進みたい 賢く進むのは一人ではできない 後悔はたくさんしてる(特にスレッドやキーワード引数,なんで入れちゃったんだろう……) 自分は天才じゃないからこういう失敗もする.

今の Ruby は良くも悪くも使う人がたくさんいるので直しづらい どんな些細な機能でも使われる そのため,賢く選択しなければならない 決まってしまったことは変更できないので決まる前に言って下さい Ruby を作り続けて世界を良くしたい

コミッターの方々によって Ruby の世界は良くなってきた これからもよろしくお願いします たくさんの意見下さい.

(この記事の)まとめ

RubyKaigi では Keynote 以外にも Ruby に関する様々な講演が聞けます. 今回の記事では Keynote の焦点を当てましたが, 機会があれば Keynote 以外にも焦点を当てて記事化したいと思っています. 私が初めて RubyKaigi に参加したのは去年の5月でした. 当時は入社1ヶ月だったため, RubyKaigi に参加してもエモい話しかできませんでしたが,今回は講演内容もだいぶ理解できるようになっていたので,自身の成長を感じられとてもいい経験になりました. 次回も機会があればぜひ参加したいですね. それでは,ここまでお読みいただきありがとうございました.次の記事でまたお会いしましょう.

RubyKaigi 2019 Day1レポート

RubyKaigi 2019

株式会社ねこじゃらし エンジニアの中山です。 2019年4月18日から3日間、RubyKaigi 2019が開催されます。 その1日目に参加してきましたので、その感想などを簡単にまとめようと思います。

まつもとゆきひろさんのKeynote

Ruby の生みの親である Matz こと、まつもとゆきひろさんの講演から始まりました。 Ruby 3 についてがメインで、パフォーマンス改善・静的型付け・その他新機能など盛りだくさんでした! 個人的にはRubyが静的型付け可能となるためにどうするかがなかなか興味深かったです(ガチガチに型宣言するというよりは、型プロファイラや型チェッカによって型付けをおこなう)。まつもとさんの話から、Ruby 本来の設計思想である Enjoy Programming が根底にあるんだなぁと改めて感じました。

印象に残った講演

午後は各ホールに別れての講演がありました。 その中でも特に印象的だったお話を少しご紹介します。

Write a Ruby interpreter in Ruby for Ruby 3

クックパッドの笹田さん(Ruby のフルタイムコミッタとして有名!)による講演。 題の通り、RubyインタプリタRuby (+C) で書くための定義やその性能評価について。 英語の講演ということで少し緊張しましたが、とても聞き取りやすい英語で、しかも日本語で書かれた発表内容の事前資料 までご用意されていて、大変わかりやすかったです。ここで色々書くよりもご覧になった方がわかりやすいと思いますので、ぜひご覧ください。私もあとでまた読み返します......!

RMagick, migrate to ImageMagick 7

弊社のサービスでも RMagick 使わせていただいていた(はず)と思い、会場へ。 決して他の会場が全て In English だったから... とかではないです。 登壇者は Shizuo Fujita さん (@watson1978) RMagick の主要なメンテナー3名のうちのお一人。Fujita さんがプロジェクトに参加された当時、RMagick には主に「セットアップの不具合」「メモリリーク」「SEGV」という問題があり、それをコツコツと解決されていたそうです。 私が特に印象的だったのは「メモリリーク」に関して。Fujita さんはメモリリークの問題だけで56件もの修正をされているみたいです! Fujita さん曰く「死ぬほど大変だった」とのこと......。 メモリリークの原因も様々で 例外が発生によって、メモリ領域解放のコードまでたどり着かない 単純にメモリ解放のコードがない(忘れている) 間違ったAPIの使い方をしている など、コーディングあるあるのような身につまされるような、そんなお話でした。 が、第4の原因として挙げられていた そもそも ImageMagick でメモリリークをしていた という内容には会場のみなさん爆笑でした。そちらもすでに修正依頼を出されて、修正済みだそうです。ご利用の際は最新の ImageMagick にアップデートしましょう。 このようなバグの修正や ImageMagick7 をサポートするためなど色々手を焼かれているようで、「だいぶつからった」と講演中に4, 5回おっしゃっていたような気がします......。Fujita さんのような方のサポートがあって Gem やライブラリが使えていることを、我々エンジニアは忘れてはなりませんね。

まとめ

上記講演以外にも、Ruby 3の話や 2.7で実装されるパターンマッチングについてなど、興味深いお話がたくさん聞けました!一方で、いくつかの講演の中でよく理解できていない部分もあり、自分はまだまだ勉強不足だなぁと感じました。次回参加する機会があれば、Ruby に関してより成長した状態でまた参加したいですね。 それでは、ここまでお読みいただきありがとうございました。 また、登壇者ならびにRubyKaigi運営の皆さま、スポンサーブースでお話していただいた方々、名刺交換していただいた方々などなど、誠にありがとうございました。 とても充実した RubyKaigi 1日目でした。

生まれ変わらNight に参加しました!

こんにちは、松下です。 2018/11/29 に ヤプリラクスル さん合同のイベントが開催されたので参加してきました。

yappli.connpass.com

今日はこのイベントのレポートを書こうと思います。

続きを読む

KotlinFest 2018 に参加して Kotlin を愛でてきた。

こんにちは、松下です。

2018/08/25 に KotlinFest という「日本 kotlin ユーザグループ」さん主催のイベントが開催されたので参加してきました。

本日は KotlinFest で気になったところレポートを書こうと思います。

続きを読む