Timee Product Team Blog

タイミー開発者ブログ

モバイルアプリエンジニアが RubyKaigi 参加してみた

はじめに

はじめまして、タイミーでモバイルアプリエンジニアをやっている tick-taku です。

5/15 - 5/17 の三日間にわたって沖縄で RubyKaigi 2024 が開催されました。全国から Rubyist が集結するイベントで弊社からもたくさんのメンバーが参加しており、自分も初めて参加してきました。

今回はそんな RubyKaigi に参加して感じたことや気になったポイントを紹介します。

rubykaigi.org

タイミーメンバーの参加レポートはこちら。

みなさん各セッションを解像度深く解説されていてとても勉強になりました。

tech.timee.co.jp

tech.timee.co.jp

tech.timee.co.jp

なぜ参加しようと思ったか

冒頭で自己紹介した通り、僕はモバイルアプリエンジニアで普段は Android や iOS アプリ開発がメインです。

そんな自分がなぜ RubyKaigi に参加しようと思ったか。それはこれから Ruby (rails) の開発ができるようになりたいと考えているからです。

そこで、まずは言語やコミュニティの雰囲気を掴むため Ruby の中で大規模なカンファレンスに参加してみようと思ったのがきっかけでした。

タイミーでは開発組織においてチームトポロジーをベースとしたストリームアラインドチームを運営しています。

その中で僕が所属しているチームはクライアント様に向けた機能開発を目的としており、クライアント様が使う管理画面の改善などが多いです。そのため、稀にワーカー様向けであるモバイルアプリの開発タスクが希薄になることがあります。

逆にバックエンドタスクがまだまだ手が足りていないので、モバイルにクローズせずにケイパビリティを発揮していきたいと考えました。

また僕は専門領域特化型ではないと昔から感じているため、全体を満遍なくできるようになることでゴール達成のためにどこか人が足りていない部分を補う動き方をしていきたいと考えています。

チームの方向性ともマッチしているためバックエンドで採用している Ruby を勉強していこうと思いました。

後は沖縄で開催と言うのもかなり魅力でした。沖縄ですよ、沖縄。こんなに聞くだけで胸躍るキーワードなかなかありません。キラキラドキドキですね。

RubyKaigi は毎回日本各地を転々と開催しており、毎年同じチームの Rubyist がワクワクしていたのを羨ましく感じていました。

参加してみて

楽しかった

これに尽きると思います。

コミュニティの交流であったり「こういう事を考えて言語をよりよくアップデートしている」といった事が聞けたり、普段の関わりから遠い話がたくさん自分事として聞けたことがとても楽しかったです。

知識的な話

RubyKaigi に関しては参加理由にも少し言及していますが Ruby に慣れる事を目的として参加しました。

と言うのも、Ruby を使って開発している人たちによる「どういう課題をどう解決したか」と言った話が聞けると Ruby をより身近に感じられ、モチベーションに繋がるかなと思ったからです。 モバイル系のカンファレンスで言うと DroidKaigiiOSDC みたいなものを想定していました。

ですが、実際に RubyKaigi に参加してみるともっと低レイヤーの、Ruby の中はこう動いているだったりコンパイラの話などばかりでした。正直何言ってるか分からないことだらけでしたが、セッションの端々から NamespaceRBS など気になる単語が聞こえてきて知的探求心が刺激されました。

アスキーアートもあまり馴染みがなく新鮮で面白かったです。ゲームを動かしてみたりとスピーカーの Ruby が愛が伝わってきました。

以下に気になったワードを列挙します。

Namespace

今回のセッションの中で一番興味を持ったテーマがこの Namespace について です。

Java で言う package (や Kotlin の alias import)を Ruby でやりたいのかなと思いました。

自分は今まで Ruby (と言わずスクリプト言語全般) の変数がどう参照されているかが分かり辛く、またクラスや変数のコンフリクトが起きやすいのではと思っていました。Google が Ruby のライブラリなんか作ったらそれはもう大変なことに...

モジュラモノリスなアプリケーションにおいてチームの規模が増えるにつれ、こういった話の課題感は飛躍的に上がっていきそうな気がするので重要度は大きいのではないでしょうか。

Refinements

Namespace のセッション内で Refinements というワードが聞こえたので、Refinements について調べました。

こちらはメソッドに対してある特定のスコープ内の挙動を書き換えるものだとわかりました。Namespace が package に対して Refinements はどちらかと言うと extensions なのかな?少し違うかも...

Refinements が Namespace に成り代わる(統合される)わけではないと言及されていて、上記の比較が正しければ確かにそもそもの目的・用途が別物ですね。実際に触って理解していきたいと思います。

RBS

自分は Java からスタートしたので馴染みがありますが、動的型付けの Ruby でもタイプセーフのメリットを傍受したい!的な話でしょうか。コンパイルでエラーを吐き出されたりエディタ上で確認できた方がいいのは開発スピードや品質にも関わってくるのでそれはそうだと思います。

Java の記述が冗長になりがちなデメリットを Kotlin が型推論でカバーしていることを考えると自然な流れに見えます。

ただし定義が .rbs (別ファイル) に定義されることが、必要に応じて定義できるフレキシブルさを持っている反面運用時のネガティブコストにならないかは心配になりました。

TypeProf

そして型推論をやろうとしているのが TypeProf でしょうか。(Good first issues of TypeProf) .rbs ファイルを自動生成するから管理を気にしなくてよくなるのかもしれない? こちらも触って確かめてみようと思います。

Parser

今回の RubyKaigi で最も聞いた単語だと思います。普段プログラムの Parser を意識することはあまりありませんでしたが、実際にどういうアルゴリズムで動いているとかこの言語だとこうだけど Ruby やこのツールはこうなんですよみたいなのが聞けて面白かったです。

調べているとかなり歴史や思想があって興味深いのですが詳細を書くととても長くなってしまいそうなので割愛します。The grand strategy of Ruby Parserを発表されていた kaneko-san のこちらの記事がとても勉強になりました。

コミュニティの話

社内外問わずたくさんの人にはじめましてが出来たことも良い刺激でした。

モバイル界隈に生息しているため社外の Rubyist はもちろんのこと、タイミーではフルリモートを採用しており、自分はまだ入社して半年も経っていないためチームでも現地で初めて顔を合わせる人がたくさんいました。 そういった人たちとパーティやランチで普段何しているかだったり業務では聞けない話をたくさんできて楽しかったです。

RubyKaigi で驚いたと共にいいなと思ったことが、各スポンサーや有志がアフターイベントを企画しそのイベントをオフィシャルが公表していることです。

参加する人が口を揃えて RubyKaigi はお祭りだと言っている意味がわかりました。Official Party はもちろんですが、最終日にも懇親会があることも驚きましたし、各社が企画する DrinkUp やカラオケ大会、果てにはクラブを貸しきる DJ イベントもあり、なんでもありだな...と。 タイミーも初日から二日続けて DrinkUp を開催するという狂気っぷりを発揮しています。

timeedev.connpass.com

せっかく初参加なのでと時間に都合がつく限り参加してみました。 とは言え、初参加だし専門領域も違うので単身乗り込んで行って大丈夫か...?ちゃんとコミュニケーションできるか...?知らん人に囲まれて歌えるか...?と不安ばかりでした。

ですが実際に飛び込んでみるとそんな不安は杞憂に終わりました。話す人みなさんが歓迎ムードで相手へのリスペクトを感じ、Ruby コミュニティのウェルカムマインドはなんて素晴らしいんだと感動しました。

こちらは2日目の rubykaraoke で午前3時まで完走した猛者たちの様子。面構えが違う…

一人不安に思いながら参加しましたが、楽しみ過ぎて完全に声が出なくなりました😇

このお祭りみたいな雰囲気と、それをオフィシャルが大々的に謳っていることは社外の人と交流するハードルが一気に下がってとてもよい取り組みだと思います。旅先であることも盛り上がりの燃料となっている気がしますね。

だからこそ Ruby コミュニティはここまで規模が大きくなっているんだと実感できました。

ここまでの規模でこれだけ盛り上がりの大きいカンファレンスは自分が知る限り国内ではあまり見かけないので非常に良い機会提供の場になっていると思いました。(Android のカンファレンスでもこういうのないかなぁ) そりゃ毎年みんな行きたがるし帰ってきてからもわいわいしてるわけだ...

さいごに

まずは関わってくださったみなさまに感謝を。 Ruby を開発してくださっているコミッターの人、RubyKaigi を運営してくださったスタッフの人、雑に話に行って歓迎してくださった人、チームのメンバー、専門領域が違うにもかかわらず参加させてくれた上司・会社などなど、本当にありがとうございます。

タイミーでは KaigiPass と呼ばれる制度があって、レポートを書いたり登壇するなど何かしらのアウトプットでコミュニティに貢献することを前提に、国内外問わずカンファレンス参加の費用を負担してくれる制度があります。 冒頭で紹介した通り僕はモバイルアプリエンジニアで Ruby とはほど遠く、社歴もまだ半年も経っていないのに、それでも参加を認めてくれています。タイミーはなんて素晴らしい組織なんだ。

今後のための教訓として RubyKaigi や Ruby についてある程度事前に調べていくべきだったと反省しています

上述した通り RubyKaigi の趣旨もそうですが、知らない単語を調べながらセッションを聞いていると途中でついていけなくなったりしました。まぁついていけてもわかってなかったですが...

とは言え Ruby に関しては何から手をつけていいかわからなかったので、ワードからこういうことがあるんだなと調べるためのとっかかりが得られたのはとても大きな一歩だと感じています。

またネックストラップの色によって写真の掲載に承諾するかを意思表示できるようになっています。黄/赤 は 🙆‍♀️、白/青 は 🙅‍♂️ です。

ところがアイキャッチの写真をよく見てください。1人だけ青いですね。

そう、僕です。完全に理解していませんでした。自分のイメージカラーだから青にしよ♪くらいの気持ちでいました。 撮り終わった後に教えていただいて慌てて付け替えたんですが、ちゃんと会のレギュレーションをチェックしておけばと後悔しています...お手数おかけしました...

何事も事前準備が大事ですね。

以上、モバイルアプリエンジニアが RubyKaigi に初参加してみた参加レポートでした。 振り返ってみると圧倒的によかったこと・得られたものが多く、今回参加してみて本当に満足しています。

来年は愛媛県松山市ということでぜひ次回も参加したいですね! せっかくだから自転車持っていって帰りはしまなみ海道渡ってから帰ろうかな...

【RubyKaigi 2024 参加レポート】Namespaceを実際に触ってみた

こんにちは、タイミーの @masarakki です。

先日、5月15日から3日間開催された「RubyKaigi2024」に参加しました。
本記事で取り上げるのは、そのRubyKaigi2024の最後のセッションであるmatzのキーノートで、「これが入ったらRuby 4.0」とまで言われた @tagomoris 氏のNamespace機能。 セッション終了後、目の前に本人が座っていたので「責任重大だねwww」と煽りに行こうとしたところ、感極まって帽子を目深に被りなおしている瞬間だったのでそっとしておきました。

というわけで、セッションの内容 は他にいくらでも記事があると思うので、実際に手を動かしてみようと思います。

参考: https://gist.github.com/tagomoris/4392f1091f658294bd4d473d8ff631cb

作業ブランチが Namespace on readにあるのでビルドしてみましょう。

$ git clone https://github.com/tagomoris/ruby
$ cd ruby
$ git checkout namespace-on-read
$ ./autogen.sh
$ mkdir build
$ cd build
$ ../configure --prefix=$HOME/ns-ruby
$ make
$ make install

$ ~/ns-ruby/bin/ruby -v
ruby 3.4.0dev (2024-03-28T13:58:33Z namespace-on-read f0649a2577) [x86_64-linux]

どうやらうまくビルドできたようです (rubyのビルド人生で初めてやった)。

かんたんな検証コードを動かしてみましょう。

# foo.rb ------

require './bar'

class Foo
 def self.var=(val)
    @@var = val
  end

  def self.var
    @@var
  end
end

# -------------

# bar.rb ------

class Bar
end

# -------------

# nstest.rb ---

def dump(obj)
  puts "#{obj}: #{obj.object_id}"
end

require './foo'

ns = Namespace.new
ns.require './foo'

dump Foo
dump Bar

dump ns::Foo
dump ns::Bar

Foo.var = 'abc'
ns::Foo.var = 'xyz'

puts "#{Foo.var}, #{ns::Foo.var}"

# -------------

実行してみましょう。

~/ns-ruby/bin/ruby nstest.rb
Foo: 100
Bar: 120
#<Namespace:0x00007ff908cf1cd8>::Foo: 140
#<Namespace:0x00007ff908cf1cd8>::Bar: 160
abc, xyz

Foons::Foo が全く独立していることがわかります。

普段遣いのrubyでは動かないことを確認しましょう。

$ ruby -v
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux]
$ ruby nstest.rb
nstest.rb:8:in `<main>': uninitialized constant Namespace (NameError)

ns = Namespace.new
     ^^^^^^^^^

確かセッションでは例として Oj.default_options行儀の悪い gem によって書き換えられてしまう事例が挙げられていたので試してみましょう。

# foo.rb ------

require 'oj'
Oj.default_options = { symbol_keys: true }

class Foo
  def self.oj
    Oj.load('{"key":"symbol_or_string"}'
  end
end

# -------------

# nstest.rb ---

require './foo'

ns = Namespace.new
ns.require './foo'

Oj.default_options = { symbol_keys: false }

p Foo.oj
p ns::Foo.oj

実行してみましょう。

$ ~/ns-ruby/bin/gem i oj
$ ~/ns-ruby/bin/ruby nstest.rb
$HOME/ns-ruby/lib/ruby/3.4.0+0/date.rb:51: [BUG] Segmentation fault at 0x0000000000000168
ruby 3.4.0dev (2024-03-28T13:58:33Z namespace-on-read f0649a2577) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0013 p:0039 s:0052 e:000051 CLASS  $HOME/ns-ruby/lib/ruby/3.4.0+0/date.rb:51 
_人人人人人人人_
> 突然のSEGV <
 ̄Y^Y^Y^Y^Y^Y^Y^ ̄

ちなみに date.rb:51def coerce(other) です。 なぜ・・・
そういえばセッションで @tagomoris も祈りながら実行していたな・・・というのを思い出し、何度か実行してみたところ、確率10%くらいで成功しました。

$ ~/ns-ruby/bin/ruby nstest.rb
{"key"=>"symbol_or_string"}
{:key=>"symbol_or_string"}

他のライブラリでも試してみましょう。

json

標準ライブラリで oj と同じようにC拡張を持つライブラリです。
特に何も問題なく読み込めました。

csv '<top (required)>': uninitialized constant Array (NameError)

ネームスペースの中でArrayが見つからないみたいです。
もっと単純なコードで試してみましょう。

# foo.rb -----
puts "#{Array}: #{Array.object_id}"

module Mod
  def foo
    p :foo
  end
end
Array.include(Mod)

# ------------

# nstest.rb --

puts "#{Array}: #{Array.object_id}"

ns = Namespace.new
ns.require './foo'

[].foo

# ------------
$ ~/ns-ruby/bin/ruby nstest.rb
Array: 80
Array: 80
:foo

なにかおかしいですね。
Array は見つかるものの、予想外にトップレベルの Array まで汚されてしまっています。

さらに foo.rbrequire 'csv' を追加すると

$ ~/ns-ruby/bin/ruby nstest.rb
$HOME/ns-ruby/lib/ruby/gems/3.4.0+0/specifications/csv-3.2.8.gemspec:4: [BUG] vm_cref_dup: unreachable
_人人人人人人人_
> 突然のSEGV <
 ̄Y^Y^Y^Y^Y^Y^Y^ ̄

トップレベルで require ‘csv’ した後に ns.require './foo' するとuninitialized constant Array (NameError)のエラーに戻ります

jsoncsv

$ ~/ns-ruby/bin/ruby nstest.rb                                                                                                                      
$HOME/ns-ruby/lib/ruby/3.4.0+0/forwardable.rb:230: [BUG] Segmentation fault at 0x00000000000001da

-- Control frame information -----------------------------------------------
c:0017 p:---- s:0088 e:000087 CFUNC  :proc
c:0016 p:0004 s:0084 E:001920 TOP    $HOME/ns-ruby/lib/ruby/3.4.0+0/forwardable.rb:230 [FINISH] 
_人人人人人人人_
> 突然のSEGV <
 ̄Y^Y^Y^Y^Y^Y^Y^ ̄

問題のない jsonと問題のある csv を両方requireするとなぜか別の問題が発生しました。
面白いですね。
(自分のrubyのビルド方法が間違ってる疑惑・・・?)
こういう開発途中の機能を触ってみるのは初めてなので、Rubyがこんなに簡単にぶっ壊れるんだ・・・って新鮮な気持ちです。

いろいろなパターンでSEGVが出たので次回はコードを読んでみたいと思います。

最後に

コロナ禍で人生が一変し、結婚 + 出産 * 2 が続き、2019年以来 実に5年ぶりのRubyKaigi参加になりました。
RubyKaigi、やっぱりドチャクソ楽しいですね・・・特にrubykaraoke・・・ッ!!
1歳と0歳を連れて参加できたのも、ひとえに託児所やイベントに子供を受け入れてくださった各社様のおかげです。この場を借りてお礼申し上げます。

なお、RubyKaigiには「Kaigi Pass」という制度を利用し参加しました。
Kaigi Passとは、世界中で開催されている全ての技術カンファレンスに無制限で参加できるタイミーの制度です。
制度について気になる方はぜひ以下の記事もご覧ください。

productpr.timee.co.jp

RubyKaigi 2024に参加しました(パート2)

5月15日から17日の3日間、RubyKaigi 2024が沖縄県那覇市で開催されました。

rubykaigi.org

タイミーには世界中で開催されるすべての技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度があります。今年もこの制度を活用してタイミーから総勢12名のエンジニアが参加しました。

前回に引き続き参加レポートの2回目として、各エンジニアが印象に残ったセッションの感想をお届けします。

YJIT Makes Rails 1.7x Faster

rubykaigi.org

ShopifyでYJITの開発をしているk0kubunさんによるRuby 3.2から3.3(と3.4)にかけてのYJITの進化についての発表でした。YJITはRubyの実行速度を向上させるJITコンパイラで、Ruby 3.3ではいくつもの改善が施されています。 その中でも特にパフォーマンス改善にインパクトがあったものとして強調していたのが、メソッド呼び出しのフォールバック、例外ハンドラのコンパイル、スタックに置いていた値のレジスタ割り当て、メソッドのインライン化の4つでした。 こうした地道な改善の積み重ねにより、Ruby 3.3のYJITはRubyプログラムのパフォーマンスを10-20%も向上させることができるようになったそうです。今後のRubyの高速化に期待が持てるセッションでした。

3月末にRubyを3.3.0にバージョンアップした際にYJITのことを少し調べていたので自分ごととして聞けたセッションでした(タイミーではYJITはRuby3.2のときに有効化しています)。 リリースノートのYJITの"Major performance improvements over Ruby 3.2"というセクションにも目を通してはいたのですが、そのときは「なんかいろいろ最適化して速くなったんだろうな」くらいの気持ちで読み流していました。 このセッションでリリースノートの1行1行の背後で具体的にどういう改善を行ったのかがわかりやすく解説されたおかげで、自分の中でYJITに対する理解が少し深まった気がします。 同じくYJITに関する@maximecbさんの「Breaking the Ruby Performance Barrier」も聞いていて、YJITを最大限活用するようなコードの書き方やgemの選定といった観点がパフォーマンス文脈では重要になるかも?などと思ったりしました。 が、本来はあまりそういうことを意識しなくてもふつうにRubyのコードを書いてYJITが有効だったら速い、が理想な気もしますし、YJIT開発チームの精力的な活動を見ていると自分の想像を超えるようなブレイクスルーが起きる気もしていて今後が楽しみです。

須貝

speakerdeck.com

RuboCop: LSP and Prism

rubykaigi.org

セッションの大きなテーマは以下の二つでした。

  1. Rubocop and LSP
  2. Rubocop and Prism

「Rubocop and LSP」ではLSPがどう実装されているかやVSCodeやvimなどのEditorでどう利用されているか事例などの話がありました。加えて、LSPを利用しないと毎回CLIなどでコマンドを叩かないといけないが、LSPを利用するとその流れが省略されるのでフィードバックが早いメリットがあることや、VSCodeでは既にYJITを利用している話もありました。

メリットなどの話もありましたが、LSPの対応で新しく発生したイシューもありました。CLI上では作業を完了してからコマンドを実行するので問題ないが、Editorだとどのタイミングで作業が終わったのか判断が難しいというところです。現在Parser Gemではエラー耐性設計(Error Tolerance)をサポートしてないのでこの問題が解決できないが、それをサポートしているのがPrismで、「Rubocop and Prism」で関連の話がありました。

「Rubocop and Prism」ではどのタイミングで作業が終わったのか判断が難しい問題を解決するための説明やどういうメリットがあるかなどの話がありました。Prismではエラー耐性設計(Error Tolerance)をサポートしているため、作業が終わるタイミングの判断の問題が解決できるかつ、Parsingスピードが速くなるらしいです。

最後には現在はParser Gemのインターフェースを利用してPrismを利用しているが、将来的にはそれを無くして直接Prismを利用したい話、Prismを利用すると得られるメリットの話でセッションが終わりました。

rubocopがなんとなくパーサーで動いているんだろくらいは考えていたがどういう原理や技術で動いているか分かってなかったので、話を聞くだけでも非常に勉強になりました。現在vimを利用していて、素早くrubocopの結果がEditor上で表示されるのは非常に助かっていますが、それがLSPのおかげだということがわかりました。まだPrismではエラー耐性設計を対応してないので、すぐprismを利用するのは難しいかと思いますが、対応出来次第もっと速くなったrubocopを利用するのが楽しみです!

@JinsuKim26

speakerdeck.com

From LALR to IELR: A Lrama's Next Step

rubykaigi.org

概要

RubyのParserであるLramaは次にIELR化に取り組むよという話。

  • 課題

    現行のLramaのParserはLALR Parserであるが、Lexerの状態管理に関して課題がある。

    事例として p 1.. || 2 が正しくパースできない問題は、 シンボルを "||" と解釈するか "|" + "|" と解釈するかの問題に起因しており、これが文脈に寄って異なるというLexerとParserの複合問題である。

    これを現状のLALR Parserで対応しようとすると当該Parseロジックに個別カスタム処理を書く必要があるが、構文を管理するparse.yは既に現時点で16kLを超えており個別カスタム対応には限界がある。

  • 解決策

    この問題はLexerとParserを直列に動作させていることに起因しており、LexerとParserが相互に連携しながら解析することで解決可能である。

    これを実現するアルゴリズムがPSLRアルゴリズムである。

  • 実装

    PSLRアルゴリズムは Canonical LR parser で実装可能であるが、 Canonical LR parser は動作が重たいという問題がある。

    LALR Parser は Canonical LR parser を軽量化したものであるが、軽量化の代償としてPSLRアルゴリズムを実現するのに必要な表現能力を失っている。

    そこで両者のいいとこ取りをしたIELR Parser というものがある。

    着想としては高速な LALR Parser を基本としつつ、表現能力を超えた場合に Canonical LR parser を動かすと言ったシンプルなものもの。

感想

Parserが順当に進化しているなという所感。

言語工学の基本としては字句解析と構文解析は直列に動かすものですが、実際の課題としてそれでは解けない問題が存在するというのは興味深かったです。

LR Parserの改善の文脈でありLR Parserの知識があればベターですが、実際には字句解析処理の文脈依存性の問題です。非常に豊富な文法をもつRubyらしい課題であり、他言語ではなかなかココまで言語工学の研究に踏み込むことは無いのではないか思われます。

問題の複雑さに対して、実際の解法はシンプルに既存の技法を組み合わせるものであり、これは言語工学における先行研究の成果物の豊富さを物語っていると感じました。

(@Kazuki Tsunemi - tsunemin)

speakerdeck.com

Cross-platform mruby on Sega Dreamcast and Nintendo Wii

rubykaigi.org

概要

mrubyをドリームキャストとWiiで動かしてやったぜという内容。

なおスライド自体もWiiを動かして表示していた。

ドリームキャストは2020年Wiiは2023年にmrubyで正式サポートされている。

なぜこの2つを選んだかと言うとドリキャスとWiiをスペック対決させるため。両者はハードウェアアーキテクチャからSDKに至るまでが全く異なるのだが、ともにFreeSDKがあるので採用された。

実機デバッグは非常に辛いものがあるので、エミュレータが非常に助かるなどの苦労話があった。実機で動作デモも行われた。

感想

登壇者のSEGA愛がすごい。

SEGAロゴデザインのRUBYシャツ(多分自家製)を着て現れた時点ですべてを察しました。Wiiは如何にドリームキャストがすごいのかと伝えるために引き合いに出された感じもあります。

mrubyのv3.3.0のリリースノートを見るとNintendo Wii、Dreamcastがきっちり記載されています。(AndroidやMS-DOSと同じ並びにあることで異様さが際立つ)

ゲーム機は汎用PCとは違って独特のハードウェア構成をしており、特にVRAM周りの深い見識がないと動作させるのは難しいためハードウェアの話がメインになりました。

ドリームキャストはビジネスとしてはヒットこそしませんでしたが、技術としては凄いものがあったらしくハードウェアオタクの心を未だに掴み続けているようです。尺の都合でハードウェアの深い話にまでは踏み込まず、使われている技術の違いの話がメインでした。

エミュレータ開発を含めてゲーム機ハック界隈は独特の文化が醸成されていますが、ローレベルプログラミングの深淵を除きたい人はいい窓口かもしれません。

Rubyでやる理由は謎に思いつつ、Rubyでなければマージされないような気もします。

それだけRubyが「懐の深い言語」ということでしょうか。

  • 備考

    Ruby Conf in Taiwanで同様の発表が行われていた模様

(@Kazuki Tsunemi - tsunemin)

www.youtube.com

Finding Memory Leaks in the Ruby Ecosystem

rubykaigi.org

メモリデバッグやメモリリークの検出に使われるValgrindをRubyプログラムに適用して、メモリリークを検出するアイデアを実現した発表でした。

ValgrindをそのままRubyプログラムで用いるとRuby自体がシャットダウン時に全てのリソースを解放しないため、Valgrindのレポートで数千のエラーが誤検知され調査が困難な状態でした。そこで、 ValgrindのXML出力オプションを有効にし全てのエラーを標準出力し、その結果を1つずつ解析してRuby自体のメモリリークではなく、Rubyプログラムのメモリリークを検知できないかというアイデアから生まれたのが [ruby_memcheck](https://github.com/Shopify/ruby_memcheck) です。

ruby_memcheckでは、Valgridの出力したエラー1つずつのリークされた各メモリ割当てのスタックトレースを走査し、Ruby起因のエラーかネイティブGem起因なのかを確認しています。実際にこのツールによってnokogiriやprotobufといったGemでメモリリークを検知し、修正されたそうです。アイデア実現のアプローチも面白かったのですが、個人的にはその後が興味深かったです。

彼らはそこで終わらず、そもそもRubyインタプリタが終了する際に確保されたメモリ全てを解放してくれればメモリリークの検知は今より容易になるということで問題提起を行い、Ruby3.3から RUBY_FREE_AT_EXIT という機能が導入されました。このオプションを有効にすると、Rubyインタプリタ終了時に確保されたメモリを解放するため、より効率的にメモリリークの検出ができると言うものです。これによって最新の ruby_memcheckメモリリーク検出のコードもスッキリしているのも良かったです。

Day3のMatzのKeynoteで触れられていた様々な側面のパフォーマンスの話のように、YJITとRubyアプリへの直接的なパフォーマンス改善だけでなく、今回のようなメモリリークの検出を手助けする開発者体験向上文脈のRubyの発展の一例を知れて面白かったです。

今回の発表者の1人であるPeter Zhuさんが、最近RubyのGCのチューニングに使える示唆を与えてRailsアプリを高速化をサポートするAutotunerというGemに関する記事を公開していたので早速使ってみたいなと思っています。

ぽこひで

https://blog.peterzhu.ca/assets/rubykaigi_2024_slides.pdfblog.peterzhu.ca

最後に

パート1に引き続き、興味深いセッションが並びました。

あらためて、スピーカーの皆様に感謝をお伝えさせていただきます。貴重なお話をありがとうございました!

RubyKaigi 2024への参加で得たさまざまな知見を「タイミー」の開発にも活かしていきたいと思います。

Written by:須貝, @JinsuKim26, @Kazuki Tsunemi - tsunemin, ぽこひで

RubyKaigi 2024に参加しました(パート1)

5月15日から17日の3日間、RubyKaigi 2024が沖縄県那覇市で開催されました。

rubykaigi.org

タイミーには世界中で開催されるすべての技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度があります。今年もこの制度を活用してタイミーから総勢12名のエンジニアが参加しました。

今回から2回に分けて、各エンジニアが印象に残ったセッションの感想を参加レポートとしてお届けします。

Good first issues of TypeProf

rubykaigi.org

このセッションでは、動的型付け言語が苦手とするエディタ上でのエラー表示、コードジャンプ、コード補完などの機能を公式で提供しようとしている TypeProf の紹介と、TypeProf に貢献するための方法や tips の紹介がメインでした。

手元で TypeProf を動かして遊んでみる方法、バグを見つけたら修正しなくても known-issues として Pull Request を作るだけでも歓迎していること、TypeProf の実装における設計のコンセプトの紹介など TypeProf への貢献のハードルが下がるような発表でした。

自分としては、まず patch を歓迎していると分かったのが1つの収穫でした。TypeProf は mame さんが数年前から取り組んでいることは認知していましたが、まだ試験的な状態で他の開発者からの patch はあまり歓迎されないんじゃないかと感じていました。(そもそも patch を送るという発想すらなかった)

貢献へのハードルの下がった自分はいくつかの patch を投げてみました。迅速にレビューしてもらってありがたかったです。

github.com

github.com

github.com

patch を投げてみた感想として、難しいのは間違いないものの新しい構文をサポートすることはクイズを解くような楽しさや、少しずつ機能が増え成長していく育成ゲーム的な要素を感じました。楽しい。ウキウキしながら Ruby "enbugging" quiz を解いた人は多分楽しめるんじゃないでしょうか。

また、個人的な TypeProf の見どころの1つはシナリオテストを動かすための構文をサポートしている ScenarioCompiler クラスです。正直処理を追いかけるのは大変ですが、Ruby の表現力の高さを再認識させてくれます。

github.com

個人的には TypeProf をはじめとする Ruby の型システム周りの技術要素には Ruby での開発体験を大きく高める可能性を秘めていると感じています。これからの動向を追いつつ、自分でもできそうな貢献を見つけていきたいと思います。

@euglena1215

speakerdeck.com

Unlocking Potential of Property Based Testing with Ractor

rubykaigi.org

概要

Ractorを使う機会というのがあまりないというのが、Rubyを利用する側の正直なところだと思うが「Propaty based testingがRactorの良きuse caseになるのでは?」と思い、その仮説をもとに取り組んだ。

普段MinitestやRSpecで書くテストは、あるプログラムの実行結果が指定した期待値になっているかどうかというテストを行っているだろう。これをExample based testingという。このテストでは、プログラマの思いつく範囲のテストしか行えないという弱点がある。

Propaty based testingとは、入力値に取りうる値をランダムに多くのパターンを機械的に与えながら実行し、与えられたすべての入力値に対してプログラムの実行がパスするかどうかをテストするものである。こちらはプログラマが想定しなかったような大量で多様なテストケースが実行されるのが強みである。ただし、大量のテストケースを実行するため、テストの実行時間は当然長くなってしまう。これをRactorを使うことで軽減できるのではないか?というのが今回の仮説である。Propaty based testingは大量にテストケースが実行されるものの、それぞれに関連性は全くなく、順序など気にせず並列で動かしても何の問題もないことからRactorのuse caseにぴったりだと言える。

Propaty based testingを簡単に行えるようにするために、pbt gemを作成した。これはMinitestやRSpecといったテストフレームワークの代替となるようなものではなく、それらと組み合わせて使用されることを想定したライブラリである。また、pbtはテストが失敗した場合、その時点からシュリンキングという手法を使ってテストの失敗を再現する最小の入力値を求めに行く。

実際にPropaty based testingをRactorを使って実行したところ、CPU-boundな処理を実行するテストではRactorを使うことでシーケンシャルなものより5倍ほど速いという結果になった。しかしそれ以外のケースでは圧倒的にシーケンシャルなものの方が速いという結果であった。

Ractorを使うことで、Propaty based testingの実行時間が短くなるのか?という仮説に対する結果は「部分的にそう」と言える。また、今回の実験でRactorに対応したエコシステムがまだまだ不足しているなどの課題感も見えた。

感想

Propaty based testing自体には別件でraap gemを知った際に興味を持っていたため、デモ含めとても勉強になりました。確かに実行時間がネックになるだろうなとは思っていたものの、 Ractorではほとんど解決しないという結果に驚きました。勉強不足であるためにCPU-boundな処理というものが具体的にすぐにイメージできないのが悔しいところではあるのですが、少なくとも利用できるケースがあることがわかっただけでも学びになりました。

pbt gemについて言及させてもらうと、これは所謂テストにロジックを書くものになりそうだなというのがパッと見の感想です。しかし試したわけではないので、実際に使ってみるとまた違った感想になるかもしれません。仮に本当にテストにロジックを書くものになってしまう場合、好みは分かれてしまいそうだなと感じました。

周辺ライブラリがRactor互換ではないことは、Ractorを使いたい人たちからするととても大きな問題だと思います。自分もRactorに興味のある一人ではありますが、未だRactorを使うために真剣に動き出せてはいないので、いい刺激をもらいました。周辺ライブラリがRactor互換になることはとても良いことだと思う一方で、そのための実装は複雑になってしまうかもしれません。それでもRactor対応を歓迎してくれるライブラリは、その旨をどこかに明記しておくと、有志からのcontributeを得やすいのではないかと感じています。

(@rhiroe)

speakerdeck.com

It's about time to pack Ruby and Ruby scripts in one binary

rubykaigi.org

概要

Rubyで作ったゲームを配布したいが、配布先の環境でRubyのコードを動かすためには、Ruby本体やGemのインストールが必要であったり、それらのバージョンを揃えたりする必要があるため面倒である。これを解決し、配布先で事前準備なしで気軽にプログラムを実行できるようにするため、RubyをOne binaryに変換して配布したいと思うようになった。ここでのOne binaryとは単一ファイルのみで実行可能なプログラムを指している。

プログラムの実行環境をパッケージングして配布するという意味ではDockerやWasmも似たような手段として考えられるが、ちょっとしたプログラムを実行したいだけでDockerを使うのはヘビーだし、WasmだとRubyの機能が一部制限されてしまう。また、RubyのコードをOne binary化するライブラリはすでに存在するものの、以下のような課題を抱えている。

  • 対応しているRubyバージョンが古い
  • Ruby本体にパッチを当てているためメンテが大変
  • Windows限定
  • 一時ファイルに書き出す処理があり遅い

そのため、これらを解消したKompo gemを開発した。Kompo gemはモンキーパッチのみ、一時ファイルへの書き込みなし、gemのインストールのサポートをしているとのこと。

感想

Rubyで書かれたプログラムをOne binary化し配布するという発想は、Rubyが好きだからこそ生まれるものだと感じており、とてもRubyKaigiらしい話でした。なので、ここではあえてRuby以外の言語を使用するという話はしないことにします。

Rubyで書かれたプログラムをOne binary化したい動機をゲーム以外で考えてみると、CLIツールが真っ先に思い浮かびます。またGUIツールもRubyで作成可能なので、これを配布したい場合もOne binary化したい動機につながりそうです。自分の身の回りにはプログラムのことなんて全くわからないという人の割合の方が多く、そういった人たちに作業の効率化のツールとして配布したい場合に、One binaryであるという点はとても魅力的に感じました。

セッション中に、手元のRubyファイルに変更が加わると実行結果が変わるという、面白いデモを見せてもらいました。これは、Kernel#require等にモンキーパッチを当てることで実現しているそうです。One binary化するツールとしてKompo gemの紹介がされていましたが、モンキーパッチを当てていたりOne binary化するにあたってのキモの実装はKompo-vfsの方にありそうです。

Kernel#require等にモンキーパッチを当てたという話はこの辺りのことだと思われます。

github.com

RubyKaigi中の別の発表でKernel#requireはよく上書きされている話を聞いており、「ここでもKernel#requireが上書きされる事例が…!」と思いながら聞いていたのを覚えています。Kernel#requireの上書きって、具体的にどういう用途で使われるんだろう?というのが気になっていたので、勉強のための良い教材となってくれそうです。

普段の業務で「RubyをOne binary化したい!」と感じたことは残念ながらないのですが、趣味で作ったプログラムを「プログラムを1ミリも知らない友人に使って欲しい」と思ったことはあります。そういったものを作る場合にRubyが選択肢の1つとして挙がることはRubyistとして大変喜ばしいことです。Kompo gem、同じRubyが好きな者として、機会があればぜひ利用させていただこうと思います。

(@rhiroe)

Let's use LLMs from Ruby 〜 Refine RBS types using LLM 〜

rubykaigi.org

Leaner Technologies に所属する黒曜さん(kokuyouwind) の発表です。

Rubyの型定義であるRBSを大規模言語モデル(Large Language Models: LLM)を用いて推測し、アウトプットの質やスピードをLLMのプラットフォームやモデル間で比較検証した内容でした。

RubyにおけるLLMを用いた型推測については、昨年のRubyKaigi 2023においてMatzのKeynoteでも触れられており、個人的に関心があるテーマでした。今回は現実的な活用性がどれほどあるか気になって視聴しました。

結論から述べると、まだ業務レベルでLLMの推測一本では期待した型定義が生成可能ではありませんでした。LLMのプラットフォームやモデル間でも成績に大幅な差がある状態となっております(詳しくは発表スライドをご覧ください)

一方でOpenAIのGPT-4 Omniモデルは比較した他モデルに比べても圧倒的な精度とスピードを誇っていました。

GPT-4 Omniは偶然にもRubyKaigi 2024のDay0(開催前日)に発表されていたのですが、流石に日程的に反映は難しいだろうと思っていたところ、黒曜さんが急ピッチで実行結果を取ったらしくDay1の発表に間に合っていて心の中で称賛の拍手を送りました笑。

発表中にはRubyコードから型推測を行うgemとして本人が作成された rbs_goose やRubyでLLMを活用するためのgemである Langchain.rb などが紹介されました。いずれも私自身の知見が乏しかったので実例を通してライブラリを知ることが出来たのは有益でした。RubyのLangchainはPythonやJavaScript版のそれと比較してGitHub上のスター数などが見劣りしてはいますが、今後Rubyへの型システムの浸透が進むと関連して活用も増えていくのではないかと考えています。

(江田)

slides.com

最後に

RubyKaigiでは毎年多くの学びがありますが、今年もたくさんの知見を得ることができました。今から来年のRubyKaigiが楽しみです。

さて、RubyKaigi参加メンバーによる残りのセッションまとめも発信予定。次回パート2の更新もぜひお楽しみに!

Written by:@euglena1215, @rhiroe, 江田

TSKaigi 2024に参加しました

タイミーの林です。

TSKaigi 2024が5/11に開催されました。タイミーはゴールドスポンサーとして参加させていただきました。

また、タイミーには世界中で開催されている全ての技術カンファレンスに無制限で参加できる「Kaigi Pass」という制度があります。詳しくは以下をご覧ください。

productpr.timee.co.jp

私は今回この制度を使ってTSKaigiに参加しました。印象に残ったセッションをいくつかご紹介します。

TypeScript ASTを利用したコードジェネレーターの実装入門

セッションの詳細ページ

セッションの資料

このセッションでは、AST(抽象構文木)について丁寧に解説され、ASTを活用したコードジェネレータの実装方法やそのメリット・難しさについて説明がありました。

この後の様々なセッションでキーワードになるASTについての詳細な説明を早い段階で聞けたことは非常に有益でした。後のセッションでの理解度が非常に上がったと思います。タイミーでもESLintの独自ルールを作る際にASTに触れている箇所もあるので、そこの実装を思い出しながら説明を聞いていました。

TypeScriptの型システムを使ってコードジェネレーターを作成するところについては、実際にやってみないと分からない具体的な課題や実践的な知識も紹介され、コードジェネレータの作成にとても興味が湧きました。

ハードウェアを動かす TypeScript の世界

セッションの詳細ページ

セッションの資料

このセッションでは、ハードウェア開発の面白さに触れつつ、TypeScriptでハードを動かす際に考慮すべきことについて説明がありました。

普段Web開発ばかりしているので、日頃聞くことのないハードウェアの話が非常に興味深かったです。特に「考えることが多すぎる」と繰り返し言及されていましたが、やりたいことや予算に合わせたデバイスの選定、デバイスに応じた言語の選択や実行環境の選定、そして一度デバイスを選定して調達すると後から修正がしづらいといったハードウェア特有の難しさについての話が印象に残りました。ハードウェア開発の難しさと面白さの一端を垣間見ることができたかと思います。

この難しさを乗り越えることで、より多くのことが可能になると感じ、自分たちの仕事にもハードウェアを活用できる場面があるのではないかと想像しました。また、普段は無意識にソフトウェアの手段に制限していることを再認識し、TypeScriptでハードウェアのコードが書けることに驚きました。

実務でハードウェアを使うこと、実装することはまだ少しハードルが高く感じられますが、Webやソフトウェアに捉われない視点を持つという点では非常に刺激を受けたセッションでした。

Exploring type informed lint rules in Rust based linters

セッションの詳細ページ

セッションの資料

このセッションは、最近流行しているRust製のlinterが直面している問題と、Biomeのコミッターとして考えられている解決策についての発表でした。

具体的には、Oxcやdeno_lintなど他のRust製ツールとBiomeを比較しつつ、これらのRust製ツールがTypeScriptの型情報を用いたLintを行えないという問題に焦点が当てられていました。この問題について聞いたことはありましたが、その背景については知らなかったため、非常に勉強になりました。Linterの内部での仕組みについての話から、形情報を元にLintルールを作ることがなぜ難しいのか、それを解決する方法について理解できたように感じています。今のところタイミーの開発ではESLintが主流ですが、Biome・Oxc・deno_lintの比較は今後乗り換えを検討する時には参考にしたいと思いました。

結論としては、—isolatedDeclarationsを活用しつつ、Type Inferenceの実装を進めることになるとのことでした。簡単な道のりではないように感じられましたが、これからの進展に期待しながら注視したいと思います。

Prettier の未来を考える

セッションの詳細ページ

セッションの資料

このセッションでは、Prettierが今に至るまでの歴史的な経緯や、これからのPrettierの方向性について話がありました。

具体的には、ESLintがTypeScriptをサポートしていないため、追加のツールを入れる必要があることや、CIで全体に対してPrettierを適用するとフォーマットに時間がかかるといった問題が挙げられました。私も、過去にhuskyを使ってpushするたびにPrettierでformatをかける設定にしていたことがあったので、pushするたびにかかるformatが非常に重くストレスを感じた記憶が蘇りました。ESLint+Prettierの設定の複雑さの話についても、過去の苦い経験を思い出しながら話を聞いていました。

また、誰もPrettierを早くしようと思ったことがないという話には驚きました。BiomeやDenoのような高速に動作する競合ツールの台頭がPrettierの方針に影響を与えているところを見ると、やはり競合の出現が成長を促すこともあると実感しました。

タイミーでは今メインで開発を進めているプロジェクトでPrettier + ESLintを活用しています。Biomeへの全面的な移行という可能性もありますが、ESLintのルールを独自で作っているところもあるので、Prettierの今後の行く先を見守りたいなと思いました。

まとめ

今回はTSKaigiのセッションの内容をいくつか抜粋して紹介させていただきました。どのセッションも非常に興味深く、学びになるものでした。最後の懇親会では多くのエンジニアの方と交流させていただき、とても楽しかったです!

また来年もTSKaigiが開催されるとのことでしたので、来年もお会いしましょう!

統計検定準1級に不合格を乗り越え、合格した話

こんにちは、タイミーのデータアナリティクス部でデータアナリストをしている山本です。普段は主にマーケティング部の向き合いとして、分析業務に従事しています。

先日、社内の資格支援制度も活用しながら統計検定準1級(CBT)を受験し合格しました。不合格を経て合格に至ったため、実際の学習の流れやデータアナリストに統計検定準1級がおすすめできるポイントなどをご紹介したいと思います!

試験について

  • 準1級のレベル感
    • 「実社会の課題に対する適切な手法の活用力」というレベルで具体的には2級までの基礎知識をもとに、実社会の様々な問題に対して適切な統計学の諸手法を応用できる能力を問うものとされています。(統計検定公式HP
  • 試験範囲
    • 試験結果レポートでは「確率と確率分布」「統計的推測」「多変量解析法」「種々の応用」と分けられていますが、非常に広範囲をカバーしています。(公式の範囲はこちら
  • 受験形式
    • CBT形式により、都合の良い試験日時や会場で受験が可能です。

受験の動機

  • 統計知識を体系的に整理し幅広く基礎的な理解を身につけたかったため。
  • 実務で活用できる分析アプローチの幅を広げたかったため。
  • 弊社での資格支援制度が活用できたため。
    • 合否に関わらず、受験費用を支援してくれるため積極的に挑戦できました。

学習開始時の状況

  • 新卒から4年間データアナリストとして働いており、本試験の範囲内に理論の理解や実践経験がある箇所が含まれている。
  • 2年前に統計検定2級を取得済み。
  • 数学力は文系大学卒レベルだが、経済学部卒で数式に比較的抵抗はない。

受験結果

1回目は「3.多変量解析法」「4.種々の応用」の後半範囲の理解が如実に甘く、不合格に終わりました。

約10ヶ月後に再受験をして見事合格🌸優秀成績賞をいただきました。

4つのセクション全てで合格基準の60%を超えることができていたのが嬉しかったです!

教材について

  • メイン教材
    • 日本統計学会公式認定 統計検定準1級対応 統計学実践ワークブック
    • 日本統計学会公式認定 統計検定 準1級 公式問題集
  • サブ教材
    • Youtube動画やWeb上の公開記事
  • 社内勉強会
    • 統計学入門や時系列分析、ベイズ統計に関わる輪読会などがあり、間接的に理解の習熟やモチベーション維持の助けになりました。(勉強会の詳細はこちら)

学習方法について

不合格時、合格時の学習方法と習熟のレベル感を振り返っているのでこれから受験される方の参考になれば嬉しいです。

  • 学習期間
    • 合格時、不合格時の双方で受験前約2ヶ月間で短期集中で学習しました。自分としては、これ以上の長期の学習期間を取ることがモチベーション維持観点で厳しかったです。
  • 学習方法と習熟レベルの振り返り
    • 1度目の受験(不合格)まで
      • 上記の統計学実践ワークブックが試験範囲を網羅している参考書なので、各章を読み込んで理解→章末の演習問題を解くという流れで学習しました。分からないところは詳しい解説を探しつつ、全32章に及ぶため疑問点が解消されない場合はマークだけつけて飛ばして先の章に取り組み、まずは範囲を一周することを優先しました。
      • 2周目として1周目でマークをつけている理解が浅い箇所の再学習し、公式問題集の過去問を3年分ほど解き受験に挑みました。
    • 1度目の受験結果をうけて
      • 点数的には52点で、不合格でした。あと8点で合格点という点差以上に自分の理解度合いが足りていない感覚を受けました。特に統計学実践ワークブックの演習問題が解けるだけのレベルでは試験問題には対応できず、より本質的な理解や数式での理解ができているレベルが求められていると感じました。
    • 2度目の受験(合格)まで
      • 約半年開けて再度学習するモチベーションが湧いてきたので、再挑戦することを決めました。教材としては引き続き統計学実践ワークブックを用いて1度目の受験で点数が取れていなかった領域を中心に学習し直しました。各章を自分の言葉で説明できる理解度を目標に取り組み、特に回帰分析、多変量解析、時系列解析、分散分析などの範囲は数式や導出を丁寧に追いかけて暗記に頼らない理解を心がけました。

学習時間について

平日は終業後に1~1.5時間、休日は土日合計で4~5時間ぐらいを目安に時間を確保していました。1ヶ月で50時間弱ぐらいになるボリューム感です。

予定があったり、業務が忙しいタイミングがあったりするのできっちり時間を確保するというより、週間単位で全然時間を確保できなかったとはならないように帳尻を合わせていました。

また机に向かうモチベーションが湧かない時でもテキストを流し読むとか関連動画を見るとかしながら、学習から離れたからモチベーションが下がってきたという状態にならないように気をつけていました。

データアナリストに統計検定準1級がおすすめできるポイント

  • 幅広い範囲を体系的に理解できるため、分析業務をする上での引き出しの幅が広がり業務に活かせるところ。教科書通りの分析手法を業務でそのまま使えることは稀ですが、多くの選択肢の中からより良い手法の選択をできるようになったと感じます。
  • 統計モデリングや因果推論、機械学習などさらに発展的な内容を身につける際の基礎になるためキャッチアップがスムーズになるように感じるところ。
  • 回帰分析などPythonのパッケージを使ってアウトプットを出している分析手法の導出方法や考え方の理解を深められ、活用できるタイミングや注意点に気づけるようになるところ。

最後に

今回は統計検定準1級の受験体験記として、学習の流れやデータアナリストにおすすめできるポイントなどを紹介させていただきました。

弊社のデータアナリストは分析手法の選定が基本的にメンバーに権限が委譲されており、弊社のデータアナリストには、分析方法を自分で選ぶ自由が与えられています。そのため、さまざまな分析の引き出しを持っていることが、ビジネスに貢献するために非常に重要です。資格取得を通じて得た学びをどんどん実務において活かしていけるように努めたいと思います!

We’re Hiring!

私たちは、ともに働くメンバーを募集しています!!

カジュアル面談も行っています。 統計知識を活用した業務できるので、少しでも興味がありましたら、気軽にご連絡ください。

【Front-End Ops/イベントレポート】「コミュニケーションでフロントエンドの 「広さ」に立ち向かう」

イベント概要

2024年2月21日に「GENBA #2 〜Front-End Opsの現場〜」と題してタイミー、Sansan、ココナラ、X Mileの4社でFront-End Opsに関する合同勉強会を開催しました。 今回はそちらの勉強会からタイミーフロントエンドエンジニアのyama_sitterさんの発表をイベントレポートでお伝えします。

2023年9月にタイミーにジョインしたやましたです。よろしくお願いいたします。前職ではスクラムマスターやEMを担っており、タイミーで久々にエンジニア復帰しています。

1. どんな状況で何が起きたか

今回はフロントエンド特有の問題に対し、あらゆる施策を実施してきた結果、「結局、コミュニケーション大事!」という話をします。まずはフロントエンド特有の課題やタイミーでの状況を整理します。

浅く広くフロントエンドに向き合っている

フロントエンドは1機能・1画面に幅広いドメインが集約されることが多く、その特性上「浅く広く」になりがちな印象があります。さらに新たな技術やフレームワークの導入が頻繁にあり、この点でも大変です。もちろんバックエンドも新しい技術やパターンが導入されることはありますが、フロントエンドほどの頻度や速度ではないことが多いと思います。

タイミー独自の環境

タイミーでは、多様な機能を開発するfeatureチームがあり、フロントエンドエンジニアもこれらのチームに参加しています。一応「chapter」と呼ばれる職能別の横断組織はあるのですが、あくまで主戦場はfeatureチームのため、横断課題の優先順位がすごく上がりづらい状態です。各チームが自分のタスクに専念するあまり、組織全体の課題に目を向けることが難しいことがあります。さらに、フロントエンドの担当範囲は一つのサービスやリポジトリに限られがちで、その結果、誰がどの部分を担当しているのかが不明瞭になることがあります。また直近は、フロントエンドエンジニアの数が増え、リモートワークが常態化することで、コミュニケーションの複雑さはさらに増しています。

この状況下で何が起きたか

チームメンバー個々では、全ての領域を網羅することが困難です。特定の外部サービスの運用などは、有志の自発的な取り組みに依存しています。知識の共有が限定的なグループ内でしか行われず、組織全体への伝搬が不十分になるため、一部の課題に対して担当者が固定され、柔軟な対応が困難になっています。横断的な課題に対する担当者の割り当てが難しく、解決に至らないことが多いです。多くの重大な横断的課題が放置されたままです。「一旦起票します」と起票はするものの、それ以上の進展が見られないケースも多くありました。

広さに立ち向かうための運用や体制が別の課題を生む

タイミーでフロントエンドの広範な業務に対応するために構築した体制や運用が、意図せず別の課題を引き起こしていると考えました。

  • 積み重なる横断課題
  • 業務の属人化
  • 地層化
  • 伝搬されない知識

解決策が新たな問題を生んでしまう、一種のジレンマと言えるでしょう。

2. 何をしてどうなったか

横断課題の整理とリファインメントの実施

私が最初に着手した施策です。チームメンバーの課題認識を一致させるために、まず横断的な課題の洗い出しと詳細化を行いまし た。これは具体的な問題解決だけでなく、今後の方向性や現状認識の共有にも役立ちました。

「改善デー」の導入

フェデックスデーや20%ルールのようなイメージで、これまで2回「改善デー」を開催しています。この日は、メンバーが一堂に会し、解決したい横断課題を自由に選んで取り組みます。活発なプルリクエストのやり取りがあり、「一旦、起票します」という言葉で終わらせることなく、実際に成果を出すようになりました。

業務知識の共有

知識の属人化を防ぐため、不定期に知識共有会を開催しています。もちろん即座に「知識」となるわけではありませんが、「知らない」ことを減らすことに成功しています。※私が主導する前から不定期で実施されていました。

アーキテクチャの定例の開催

私が最も注力している取り組みです。フロントエンドのアーキテクチャが地層化することへの懸念から、どのようなアーキテクチャが望ましいかを話し合う場を設けています。私が1人で考えていても解決できない課題に対し、多様な意見が出されることで、改善への一歩となっています。

テックトークの導入

技術的な話題にフォーカスした「テックトーク」を導入しました。これは任意のメンバーが集まり、フロントエンド開発に関連する技術的な話題について議論する場です。

3. 重要なことは何だったか

これまで紹介してきたことをまとめると、要するに「コミュニケーションが大切だよね」ということです。日常的な共有や議論、意見の交換を通じて、チーム全体が同じ方向を向いて進めるようになりました。

選ばれたのはコミュニケーションでした

フロントエンドの広さゆえのメンバー間の思考や課題感の違いを理解するために、コミュニケーションが中心的な役割を果たしていることが分かりました。フロントエンドの領域が拡大し続ける中、コミュニケーションによって多くの問題に対処できていると感じています。チームやドメインが拡大する中でも、そのスピードに遅れを取っていないと思います。

ただし、リモートワークには固有の課題があります。チャットだけではコミュニケーションの限界があると感じています。私はリモートワークが好きなので継続するためにも、リモートでも効果的なコミュニケーションを図る方法を模索しています。

注:コミュニケーション = 雑談ではない

コミュニケーションについて多く語りましたが、目的は単なる雑談を促すことではありません。雑談も重要ですが、重要なのは課題を特定し、それに対するコミュニケーションの方法を模索することです。

人に依存しない仕組み化が重要

コミュニケーションはもちろん、人に依存しない仕組みを構築することも非常に重要です。コミュニケーションは問題解決のトリガーに過ぎません。根本的な解決には仕組みが必要です。チームが拡大し、単純なコミュニケーションだけでは対応できなくなった現在、仕組み化を進めることの重要性を強く感じています。

4. これから考えていきたいこと

あらゆる施策を実施するなかで、改善の兆しは見えつつありますが、課題もあります。

課題を整理し「旗」を立て直す

多岐にわたる取り組みが散発的になってしまい焦点がぼやけがちです。線ではなく点の施策をたくさん実施してきましたが、これではいくら各コミュニケーションが良くても、離散してしまいます。今後は、課題を明確にし目標を再設定する必要があると考えています。

例えば、リファインメントのセッションが「しーん」と静かになる瞬間があることや、限られたメンバーのみが参加する状況は、チームの一体感を損ないます。また、課題の認識に齟齬が生じたり、優先順位が不明確になることも問題です。

これらの問題に対処するためには、共通の目標を示す「旗」を立て直し、チーム全体が同じ方向を向いて進めるようにすることが重要だと考えています。

まとめ

  • フロントエンドは浅く「広く」なりやすい
  • この「広さ」に立ち向かうためには「コミュニケーション」が重要
  • 課題を捉え、そのために必要なコミュニケーションの形を模索する
  • 但しコミュニケーションそのものは解決「策」ではないので注意

その他の方の発表も気になる方はこちら!

www.youtube.com

少しでも興味を持っていただいた方は是非こちらからカジュアルにお話しましょう!

devenable.timee.co.jp