2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
koic氏:こんばんは。今回は「Breaking Change」というタイトルで発表します。Twitterは「@koic」というハンドルネームでやっています。永和システムマネジメントという会社から来ました。
(Rubyの静的コードアナライザーモジュールの)RuboCopは、今日も含めて何度か話に出ていると思うのですが、私はそこのコミッターをしていたり、RailsのActive RecordのOracleを使っている部分のコミッターをしていたり、そして先ほど紹介した永和システムマネジメントで働いていたり、そのようなことをやっています。
オープンソースでは、だいたい毎日なにかやっています。jQuery開発者のJohn Resigは「Write Code Every Day」と言っていましたが、僕は最近、毎日コードを書いているわけではありません。というのは、レビューがとても多くてPull Requestで時間がかかったり、マージのコミットもけっこう入ったりしているからです。それでもなるべく毎日なんらかのかたちでコードに関わろうと心懸けています。
僕が一応リリース権を持っているgemは1億6,800万ぐらいです。日本人人口が1億2,000なんぼだから、1人1個使っていたら一応日本人全員使っているはず……なわけないですけど、そんなようなことをやっています。
(会場笑)
先ほど話したRuboCopモジュールですが、ドリコムさんのブースによれば、今年(2019年)のRubyKaigiで一応4位。BundlerがRuby標準に組み込まれたので、繰り上がると3番目に入ります。このモジュールを僕が今のところ一番gemのメンテナンスをやっているわけですね。
会社もこうしたOSS活動を支援しています。コミュニティーには顧問の松田明さんとかもいて、この日本にいるRailsコミッター全員(だと思う)がわりと参加していて、(多いほうが)いろいろと捗ると思うので、よければご参加ください。
といったところで、RailsとかOSSとかそういったところを通じて成長したいプログラマー・エンジニアのみなさま、あとは(スライドを見れば)わかると思うので、このスライド1枚で終わりです。
(会場笑)
平成Ruby会議なんですけど、今回オープニングのキーノートで一緒にしゃべっていた金子さんとは、ちょうどRubyKaigi 2016の京都の前日に一緒に飲んでいました。そのころから金子さんは、けっこうRailsにパッチとかを送っていて、すごいと思っていました。そんな人と、3年経ったこのイベントでキーノートというかたちで一緒に参加できて、非常に光栄です。ありがとうございます。
では「Breaking Change」の内容に入ります。今回の話で得られることは、テストやbundle updateの重要性の再認識という基本的なところです。僕はRuboCopのちょっと斜め上の使い方をしているので、そのあたりも話します。
あと、先ほどの武者さんの話でもあったのですが、OSSの世界、僕が見ているOSSの世界観とか、そのあたりも、もしかしたら伝えられるかもしれません。そして破壊的変更に対してあなたができるかもしれないようなことについてもお話しします。
アジェンダとしては、スライドのような流れで話そうと思っています。
まずは「破壊的変更とはなにか?」といったところからはじめますね。Ruby開発のbugsのところでディスカッションされている「キーワード引数を通常の引数から分離」を例にしますが、ruby-lang.orgでも、このあたりのmameさんの記事でも書かれています。Ruby 2.7では図のように非推奨の動きになって、警告で終わるのですが、バージョン3ではそのあたりを正式にしたい気持ちがある、計画があるというお話です。
このあたりについて、とくにオープンソースを中心に僕はやっているわけですが、いろいろと「このケースもか」というところもありまして。
このスライドを見てください。これはあんまりやったことある人がいるかわからないんですが、Rubyって、すでに今日何度か話があがっていると思うんですけど、難しいんですよ。これオープンソースで見るまで、こんな書き方あるって、僕は知りませんでした。
これは何かというと、この「ary =」の配列のところはブレースが省略されたハッシュなんですね。要素1個のハッシュ。このeachのdoブロックにある「foo:, bar:」の部分です。これでキーを引っ張った値がこのformatに入るんですけど、こんな書き方知らなくて……。でもこういうのがあるんですよ。
でもこう書くと警告が出るんですね。ハッシュのところで。このformatはRuby標準で、キーワード引数を期待していて、噛み合わないかららしく。このへんについてはアプリケーション側が書き直せばいいんですけれども……。こうしたところが、今後ちょっと書き直していかない箇所だと思っています。
あとは最近だと、正規表現のmatchにnilを渡すとfalseになるところ。これって今の安定版の2.6だと問題ないんですけど。このあたりはShugoさんの話にもあったんですが、2.7.0のpreview2だとエラーになってしまうんです。nilって書いてるのですが、これが変数で渡されたときにいきなり落ちるんです。preview3だとエラーではなく警告になったんですが、「いや、でも将来的に変わっても、ちょっとな」というところで、先ほどのパッチ会でもRailsコミッターを含めていろいろ話題になっていました。
そこでちょっと「nil避けを書かないといけないとかマジか」とツイートしたところ、@kamipoというRailsコミッターの人が引用してくれて。
「2.4で、高速化のために登場したものに書き換えることを推奨したのに、それがまた2.7で覆ることになった」って返信してくれて、「えー」みたいな話だったんですけど、今度はそれをRubyコミッターの成瀬さんと松田さんが拾って、プッシュしたりトス上げたりとかしてくれました。
そういう経緯があり、これが開発者のまつもとさんに届いて「戻しましょう」となって。声を挙げるとそうしたこともたまにはあるんです。
というわけで今紹介した破壊的変更に関してですが、結局、破壊的変更とは何かというと、例えばbundle updateしたあとや、Rubyのバージョンを上げたあとといった、何かによってミドルウェアを上げたあとに、以前と異なる結果を引き起こしうるような変更のことです。
破壊的変更には、例えば公開APIの名前が変わるとか、公開APIの引数が変わるとか、公開APIの戻り値が変わるとか、公開APIの振る舞いが変わるとかがあります。「振る舞いが変わる」というのはまた難しいんですが、バグfixは本来期待してた動きに直すものなので、そこは破壊的変更とは扱いが変わるんでちょっと違います。
こうした公開APIのなにかしらが変化することが破壊的変更になるわけです。ここで「公開API」と「非公開API」についてもう1回考えてみましょう。
公開APIとは何かというと、Martin Fowlerという人が、公布済みインターフェースについて、パブリック/プライベートよりもパブリッシュとかパブリックかのほうがより重要という話をしていて。2003年だから、すごいですね、平成の何年? 16年前? マジか、という感じなんですけど。
いわゆる言語として、パブリックで外から呼び出しができるより、公開されてほかのユーザーから使えるパブリッシュなAPIであるほうが、より重要だよといったところがあって。オブジェクト指向のプログラミング設計でも、パブリックなAPIは安定しているわけですよ。その安定したAPIを使っていきましょうというところです。
ただ、安定なものがよくて不安定が悪いというわけではありません。ソフトウェアは変化し続けるので不安定な部分はどうしても残ります。そうしたものに依存するのではなく、安定したものに依存していきましょうということです。
RubyやRailsで言うと、内部的なAPIが明示されていないAPIは使わないことです。Railsだとメソッドコメントがあるdocが公開APIなので、書かれていないやつは使わない。そういうことです。
非公開APIって、図のような世界なんですよ。大いなる力には、大いなる責任が伴うんです。
非公開APIに依存することでなにが起きるかというと、例えばYARDというドキュメントの生成モジュールがあるんですが、ここで最近ちょっと事件が起きました。RubyのirbにあるslexというAPIがゴロっと削除されて、これに対してrequireしているため、それがなくてエラーになるというもの。
これについては、irbをメンテしてくれているAsakusa.rbの糸柳さんに相談したんですが、そこにコメントを残していて、内部APIはやめましょうという話になりました。もともと内部APIですと明示されているので、それは依存しているほうが責任をもって修正しなければいけないという話ですとか。
Railsですと、このへんの内部APIって、メソッドコメントが記されてない非公開APIなんですよ。kamipoさんから、この非公開APIをちょっと削除してという要望があって、そのへんのところをウォッチして手元のローカルリポジトリで、軽くgrepしたんですよ。
すると、いくつかヒットしました。自分の会社のオープンソースのやつがまず引っかかって、そこにパッチを出しました。あと、会場にいる松田さんのdatabase_rewinderもヒットしていました。
内部APIは、ライブラリ提供者が実装に応じて変更しているので、いきなりAPIがなくなるとNoMethodErrorが起きて死んだりします。例えばRailsをアップデートしたときに、非対応の何かに依存しているgemだと、エラーが起きたりします。
これがですね、Railsのこの図のような場合ーー今回はプライベートAPIなので少し特殊な例ですがーーラファエルというコミッターが「“バックリンクのここを変更したことで、ウチのがちょっと破壊された”というようなレポートがいくつか上がっているので、まず非推奨警告を出しませんか?」といった話です。
こうした流れで、このへんの非推奨警告を追加したパッチをkamipoさんが出してくれました。非推奨警告が入ると、エラーというよりは、警告のところに「こういう警告が出るようになるから直しましょう」みたいな説明が出て、か結局他にも影響するんです。内部APIは、使わないのがベストですが、使うのであれば、なるべく必要最小限にということを考えましょう。
公開APIでは警告をまず出すようにしていますから、アプリケーション開発者としては、そのへんのところをこまめにbundle updateして、テスト実行して、警告が出たら潰していくようにします。もう警告とか消されたあとで変更された世界にいきなりいくと、ハイジャンプとなり、けっこう面倒くさかったりするので、こまめにbundle updateしてテストを実行することをやっていくといいと思います。普通の話ではあるのですが……。
このあたりが破壊的変更の話です。だいたいどんなものかイメージができてるといいなと思います。
それなら公開APIを使えば問題は起きないかというと、そうではありません。ソフトウェア開発って、メチャクチャ難しいんですよ。人類にはまだ早いぐらい難しいです。
(会場笑)
まぁ、それでもがんばってやっていくしかありません。
最初からよい設計できればいいですが、もっと使いやすい設計が出てきたとき、あとからでもそう変えられたらいいなと、葛藤します。その葛藤の末に破壊されたりしたりすることがあります。実際そうした破壊事例として、Faker 2というgemがあります。
Faker 2は、こうしたダミーデータを作るgemです。ある日、Railsアプリケーションをbundle updateしてテストを実行したら、突然エラーが起きました。何が起きたかというと、Faker 1のころは、こういうふうに引数を渡したらなにかデータが返ってきていました。しかしFaker 2では、実行したらいきなりエラーになる。
インターフェースがキーワード引数を使うように変わっていたのが理由なのですが、それに辿りつくまでに、最新のものと現在のものの差分を見て確認しました。僕の場合は、bundle updateする際に、gemdiffというツールを使っています。GitHubソースコードの差分のURLが表示されるので、それを見て確認しました。その中のCHANGELOGというところを最初に見ると全体像がつかめるので、そこらへんを確認したわけです。
そのときのものがこれです。見たことがある人もいると思うんですが、ものすごく変更があった。
このFaker 2でImportant Noteが書かれてるAPI全部が変わったんですけど、これが全部じゃなくて、全部というのがこれなんですよ。
(会場笑)
こんななかで、新しいキーワードが何になるかとか、ただのエラーだと何にもわからなくて、いや、もう……125+引数分あるわけですよ。
ちょっとこれ、自分が踏んで非常に不便だと思いました。さっき武者さんも話されてましたけど、たぶんこの部分ってほかの人にとっても面倒かもしれなくて、実際そうなんですよ。
というわけで、自分が踏んで面倒なところはほかの人にとっても面倒かもしれないですし、それを直せもするんです。だいたいgemは、Rubyで書かれているんですよ。パッチを送る場合は、オープンソースだと、ライセンスがやはり重要なんですが、パッチを送るのに支障のあるライセンスに、今のところ出会ったことがありません。まぁつまり、直せるんですよ。
解決策として考えたことは、アップグレードの実行でいきなりエラーにするのではなく、どういったインターフェースに変わるのかという警告を出すというもの。
これがそのPull Requestなんですが、これも……。Pull Requestって、とても説明が重要なんです。レビュアーとしても、やり取りを何度もせずに、即Mergeボタンを押したいわけですよ。Mergeボタンを押すには、実装もそうなんですが、なぜそれが必要かというところのMergeボタンをサッと押せるような説明を一応書いておくのが、非常に重要です。
そうしないと、興味をもたれなくなると、わりともうPull Requestをずっと放置されてMergeされなくなるので、そこは初手が重要だと思います。ここらへんのところはなんか……。僕は、たぶんこれからいい話をします。
(会場笑)
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05