
2025.08.01
災害大国・日本に求められる“命しか守れない防災”からの脱却 最長2週間先の気象災害予測による対応策
リンクをコピー
記事をブックマーク
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されなくなるので、そこは初手が重要だと思います。ここらへんのところはなんか……。僕は、たぶんこれからいい話をします。
(会場笑)
続きを読むには会員登録
(無料)が必要です。
会員登録していただくと、すべての記事が制限なく閲覧でき、
スピーカーフォローや記事のブックマークなど、便利な機能がご利用いただけます。
すでに会員の方はこちらからログイン
名刺アプリ「Eight」をご利用中の方は
こちらを読み込むだけで、すぐに記事が読めます!
スマホで読み込んで
ログインまたは登録作業をスキップ
2025.09.08
部下が不幸になる上司のNG行動5選 マネジメントは「自律と統制」のバランスでうまくいく
2025.09.10
人生の差は20代で決まる “指示待ち人間”で終わらないために積むべき4つの経験
2025.09.16
日本人が英語学習で苦戦する根本的原因 「言いたいことの順番」が真逆になる英語と日本語
2025.09.10
「やりたいこと」はないが「課題解決」自体を楽しめる人 Googleの「優秀なエンジニア」の定義
2025.09.04
「管理職になりたくない問題」の原因は上司にもある 部下の昇進意欲を削ぐ行動
2025.09.16
“できる仕事のキャパが10倍になった” 東証上場社長を変えた習慣「ピッパの法則」の効果
2025.09.11
自分の得意・不得意がわかるワーク 人生を再設計する「ライフキャリア」の見つけ方
2025.09.17
英語ネイティブは「would」をどう使っているか? 「Do you like〜」と「Would you like〜」の違い
2025.09.12
“起業が向いている人”と”経営が向いている人”は違う DMM亀山会長が語る、新規事業の生み出し方
2025.09.09
“指示待ち社員”から「自分で考え、動く社員」に育てる方法 セルフリーダーシップの発揮に重要な3つのアプローチ
管理職は罰ゲームではなかった!マネジメントスキル、リーダーシップは財産に!
2025.07.31 - 2025.07.31
後回しを断ち切り“すぐやる人”になる最速メソッド|東証上場社長実践の後回し撲滅法
2025.06.24 - 2025.06.24
「因数分解! 売れない理由は、“売り方”じゃなく “見方”にある」 ~マーケティング×ビジネス数学で、売上を動かす本質をつかむ~
2025.08.06 - 2025.08.06
【板挟みに苦しむ管理職へ】忙しさから“本当に抜け出す”唯一の方法
2025.07.09 - 2025.07.09
「英語OS」を身につけよ! −思考プロセスをアップデートし、英語学習の遠回りを終わらせよう!
2025.07.05 - 2025.07.05