よもやま話β版

よもやま話を書きます。内容はぺらぺら。自由に書く。

RubyKaigi 2024 感想メモ

2024/05/15〜17 の3日間開催された RubyKaigi 2024 に参加した記録をつけます。

初のヘルパー参加

ヘルパー募集に応募し、今年はスタッフTシャツを着用しての参加となりました。ずっとトランシーバーをつけて、参加者のみなさんに「運営側」として声掛けしたり・されたり……、昨年までの RubyKaigi とは見える世界が全然違いました。これまでの参加ではスタッフのみなさんの大変な努力の上で楽しい体験をさせてもらっていたんだな、ということに改めて感謝すると共に、今年は自分がその楽しい RubyKaigi に微力ながら貢献できたということにとても満足感を覚えています。

メインの対応としては、自分はひたすら「かりゆしT持ってってください!」「島ぞうり持ってってください!」を言う & 在庫管理する係をさせてもらいました。公式ノベルティを持ち帰ってくださったみなさん、ありがとうございました!

また、自分の担当エリアの主采配は co_bachie さんが主導してくださいました。慌ただしさからしっかりとしたお礼はお伝えしそびれており…。困った時に的確に対処いただき、本当にありがとうございました!

これは通りすがりの emorima さんに撮っていただいた自分↑ ヘイ ラッシャイ

セッションメモ

ヘルパーのため、運営お手伝い > セッション聴講 という優先順位がどうしてもありましたが、スキマ時間でいくつか拝見できました。采配・調整してくださったスタッフのみなさま、ありがとうございました!

  • day2, 11:30- Finding Memory Leaks in the Ruby Ecosystem
    • Ruby 3.3から RUBY_FREE_AT_EXIT=1 が使えるようになる。ruby_memcheck によって色んなgemのメモリリークも発見されている。メモリリークでの問題は今のところ自分の利用範囲だとそんなに踏んだことは無いのですが、いざ出会ったときにはにっちもさっちも行かなくなる問題ですね。RUBY_FREE_AT_EXIT=1 、覚えておこうと思います。
  • day2, 17:20- Lightning Talks
    • 自分がアートの領域にすごく興味津々なこともあり、小芝さんの取り組みに憧れています! Processing そのものを学生の時分に触ったときも楽しかったですが、 Ruby で動かせるとさらに楽しさ倍増なのは間違いないですね。ライフゲームとか作ってみたいな。
      • (アート的な意味ではQuineもとても興味深いです…Day1の tompng さんのkeynoteを終盤だけチラッと拝見できましたが、正直なところ凄すぎて何もわかってないです。まずは小さいやつを読めるようになるところから始めなきゃ…。)
    • 金子さんのLTは3倍濃縮だったので、録画を1/3のスピードで改めて聴きたいです! 溢れる parse.y 愛を浴びさせていただきました…!
  • day3, 10:10- Ruby Committers and the World
    • やっぱりCommiterのみなさんが壇上に集まる様子は壮観ですね!
    • #frozen_string_literal: true 、長年書いている印象がありましたが、いよいよデフォルトになる日も近いですね…覚悟はしております。よっしゃ頑張るぞ。
    • 型について「(コメントとして書く分には)黙認する」という話題が出たり、どんな表記が良いかの会場アンケートがあったり、Ruby と型との関わりの今後の動きをより具体・身近に感じました。

たとえ一般参加だったとしても、どう足掻いても身体が3つないとセッション全制覇はできないですからね…。気になってたけど見れなかった分は、録画が公開されたら拝見しようと思います!

謝辞・お宿

女性の RubyKaigi 参加者たちが共同で宿泊する企画 emorihouse( https://emori.house/ )に今年も参加させていただきました! 今回は2棟のうちの「ヤダハウス」にお邪魔しました。自分はフィヨルドブートキャンプ(略してFBChttps://bootcamp.fjord.jp/ )のメンターとしても現在活動させていただいておりますが、FBCの女性受講生の方も同じ宿泊所だったので、ご一緒してお話しする機会がありました。Day1の夜更け、『エンジニアとして実際に働いている体験談・苦労話・面白話・etc』を複数人でつらつらとリビングソファ周りで駄弁るシーンがなんともエモい思い出になりました。FBCで実施しているPullRequest経由のコードレビューの場ではお伝えする機会が少ないウェットな話ができたし、FBCメンター以外のエンジニアと交流を持ってもらう機会としても、大変貴重なワンシーンだったように思います。

宿泊企画を主導いただいている emorima さん、ヤダハウス家主 yadaita さん、今回もお世話になりました! 出来るだけ新規参加の方に枠をお譲りしたいなという気持ち vs 自分が参加すると最高にたーのしー! という気持ちがせめぎ合っており、なかなか難しい心境ではありますが、うまく空き枠あればまたお邪魔したいです 🏠 引き続きよろしくお願いします!

謝辞・予算

今年は弊社(株式会社ARROWS https://arrowsinc.com/ )に交通費・宿泊費を負担してもらいました。弊社メンバーのみなさんも、こころよく自分を沖縄に送り出してくれ、とても感謝でした!会社で自分は Rails で動くサービスを運用保守しています。Ruby は年々進化しているので、自社サービスもそれにちゃんと追いついていけるようにしていきます。

直前のGWに、既に沖縄でちんすこうを買ってきてくれたメンバーがいたので、自分のお土産はシーサークッキーにしました。社内で議論が発生した結果、このお土産について「結局のところ、ちんすこうを形を変えて焼いたやつである」という結論に達しました。うーん、美味しいからオッケーってことで!

KaigiEffect

RubyKaigi 2023でも「英語がんばるぞ」と思い、この1年ほどアプリ「Duolingo」に取り組みました。しかし、今年ヘルパーとして参加してみて、英語での質疑応答が必要になるシーンでうまく聞き取れない、答えられない……というシーンがあり、今の取り組みでは全然足りんなぁ、と痛感しました。聞けたセッションでも、どうしてもスライドの文字情報に頼った理解に偏りがちで、勿体無かったなぁという気持ちがあります。最近は「スピーク」というAI相手の会話アプリも始めましたが、2〜3分の簡単なアクティビティだけで満足しがちです。そんな自分の学習の方針としては無理にでも長めの対話をする体験を1年の中にたくさんねじ込まねば、という結論に達しました。なので、脊髄反射的にDMM英会話に登録してみました。

2025年に松山に行くまでにどれくらい効果がでるのか、とりあえずやっていこうと思います 💪

BFSの勉強メモ

これの続き: DFSの勉強メモ - よもやま話β版

BFSとは

幅優先探索( Breadth-First Search )のこと。

BFSの例

BFSは A → B → C → D → E → F → G → H → I → J → K → L の順で探索する。 BFSは キューを利用し、最短経路を解くケースで使う。

BFSを使って問題を解く

まずはこれをやるといいよ、とオススメしていただいた問題を解いてみる。 https://atcoder.jp/contests/abc007/tasks/abc007_3

ものすごく丁寧に問題内に解き方が載っているので、ありがたく参考にしつつ書いたらACになった。 https://atcoder.jp/contests/abc007/submissions/49629732

今回の学び

  • キューの中身全部吐くまで回さないと意味がない
  • 先に埋まった手数より短い手数が後から探索されることがあるので、その時は上書きする

おまけ

abc007_3 をやる前と後に、abc317_e にトライしてみていたが、修正したことでACの数が増えた。

もっとカンタンなやつをたくさん解かないとどうしようもなさそうなのでこれくらいで…。

DFSの勉強メモ

競技プログラミングの勉強会にて、DFS について教えていただいたのでメモ。( Thanks for あのぶるさん( @thatblue_plus! お世話になっております🙏 )

グラフとは

そも、DFS というのは「グラフ」についての用語である。グラフというのは、ノード(点)とエッジ(線)で構成されている、よく見るこういうやつである。時々「木」のことを考えることがあるが、「木」とは「"連結"で"閉路"を持たないグラフ」のことを指す。

グラフの例

DFSとは

深さ優先探索( Depth-First Search )のこと。自分は木のほうがわかりやすいので、まず木で把握する。

DFSの例

DFSは A → B → E → F → J → K → G → C → D → H → L → I の順で探索する。 DFSは「大回りをしてどうなるか」等を見たい時に使い、再帰を利用するのが特徴。

DFSを使って問題を解く

改めて、以前参加して自力ではまったく歯が立たなかった https://atcoder.jp/contests/abc317/tasks/abc317_c がDFSで解けるとのことで、実装をやってみる。

好きな街からスタートして同じ街を二度以上通らずに別の街へ移動するときの、通る道路の長さの和としてありえる最大値を求めてください。

上記の説明より、まさに「大回りをしてどうなるか」を調べるということに該当するので、DFSが適当だと判断できる。再帰利用と「探索済み(seen)」を保持しておくのが肝要な様子、というのを念頭においてコードを書いたが、結果として全然ダメだった。

ACを出したものも、結局のところ過去にあのぶるさんにペアプロしてもらって書いたコード( https://atcoder.jp/contests/abc317/submissions/46458009 )をほぼ参考にしながら、なんとか書けたという状況となった。結果としてDFSを知っただけではダメだなということを痛感した…。DFSの再帰の中で何をするかというのが肝要。それはそう。

今回の学び

失敗した場合、どのように失敗しているのか、結果をちゃんとみた方がいい。 TLE が出てるということは仕組みはあってて速度の問題かなと思いこんでいたケースがあったが、改めて詳細をみたら「回答が出ない」というバグを抱えていた状態になっていたようだということに後から気づいた。AC7割、TLE3割という感じで、TLEは遅かったのではなく変なループにハマって答えに辿り着かなかったと考えたほうがよさそうだった。仕組みは合ってると思い込んでしまうと永久にTLEから逃れられないので、ちゃんと実行結果の一覧を見にいくようにする。

続き: BFSの勉強メモ - よもやま話β版

Sudoのアイコンは何故サンドイッチなのか

これは「フィヨルドブートキャンプ Part 2 Advent Calendar 2023」の2日目の記事です。 https://adventar.org/calendars/9309

Sudoのアイコンはサンドイッチのキャラクターである。やや某スポンジのキャラ を彷彿とさせるが、食物・非食物という点で明確に別物と言えるだろう。

https://www.sudo.ws/images/sudo-sandwich-logo.png

The current sudo logo, © 2019 by Mark Stillman and licensed under CCBY 4.0.

https://www.sudo.ws/about/logo/

ある日、フィヨルドブートキャンプの日報*1で「何故Sudoのアイコンはサンドイッチなのか」という疑問を見かけた。Sudoのロゴは、昔は青色の盾をイメージしたものだったが、2019/05/08 からサンドイッチのものに変更されているようだ。

ref: https://news.ycombinator.com/item?id=27569648

From 2019-05-08, the logo is some kind of sandwich

パッと調べた限り由来がよく分からず、Wayback Machine とかも漁ったが、よくよく見ると公式の /about/logo のページにハッキリと書いてあった。灯台下暗し。すべては公式にある。

ref: https://www.sudo.ws/about/logo/

It was inspired by xkcd 149.

xkcdというのは人気のあるウェブコミック(※参考:wikipedia)であり、これの149というのは以下である。

https://imgs.xkcd.com/comics/sandwich.png

ref: https://xkcd.com/149/

「サンドイッチを作って」と友人に要求したところ、拒否されるが、Sudoをつけて再要求したところ受諾された、というストーリーである。コマンドを叩いて通らなかったので、権限問題に気付いて改めてSudoをつける…というのは普段でもありがちな1コマ。xkcdの作者さん自身がエンジニアのため、こういうネタがあるらしい。

webサイト側には制作年月日の表記はなかったが、解説wikiによると2006/08/28に公開された作品のようだ。

ref: https://www.explainxkcd.com/wiki/index.php/149:_Sandwich

そも、 "make me a sandwich" というフレーズについては、1995/12/16に放映されたサタデー・ナイト・ライブというアメリカのコメディ番組が元でインターネットミームになったものとのこと。下記リンク先が詳しいので、具体内容はそちらに委ねる。

ref: https://amp.knowyourmeme.com/memes/make-me-a-sandwich

1995年のコントが、2006年にwebコミックのネタになり、2019年にロゴと化し、それを見た2023年の学習者のふとした疑問に紐づくというのは、まさしくバタフライ・エフェクトといえるのではないか。なかなかに感慨深かった。

とりあえず、改めて「なんでSudoのアイコンはサンドイッチなんですか?」と聞かれたら、これで問題なく回答できそうだ。

*1:フィヨルドブートキャンプでは、受講生のみなさんが学習したこと・考えたこと・困っていることなどを日報として書くことができる機能があります。日報はメンターがチェックしています。

Kaigi on Rails 2023 感想メモ

kaigionrails.org

Kaigi on Rails 2023 参加してきました! ありがとうございました! 2020年の開始以降、ご時世柄ずっとオンライン開催だった会ですが、満を持してのオフラインでしたね。大変楽しくセッションを拝聴させていただきました。

RoomAの様子

今回はRoomA・Bがあり、人間は分裂できないのでどちらか片方しか聴講できないという問題が発生していたのですが、聞けなかった分は後日オンライン配信のアーカイブが公開されるようなので、ぜひ拝見したいな〜と思っております。

CFP通過の倍率が今回約3倍だったとのことで「来場者の4人に1人はCFP出してるかもね」という会話があったりもしました。自分は今年出せていなかったのですが、スピーカーの皆さんの熱量を浴びて「発表っていいな〜」という状態になっているので、来年は採択の有無はさておき「CFP出したぞ!」と言えるようにしたいです。

通知アプリ

今回は以下のような機能のあるブラウザアプリが配布されており、とても便利に活用させてもらいました。

  • 運営からのアナウンス(Wi-Fi情報書いてあるの大変助かる〜)
  • 気になっているセッションのブックマーク、からのリマインドPush通知
  • QRコード読み取りで「知り合った人」を増やす

これ自体もRailsで作成されているところがドッグフーディングな感じがして最高ですね。特に「知り合った人」は話をするキッカケになったりしてとても助かりました。タグもつけられたりして面白かったです 👍

以下、つらつらと自分用のセッションメモです。

セッションメモ(Day1)

  • スポンサーLT1(mybestさん): レビュー記事をよく拝見するけどバックエンドはRailsなの実は知らなかった…!
  • スポンサーLT2(Techouseさん): かなりガッツリ、スポンサーLTとは思えないレベルのSidekiq & AWS Fargate のお話を聞けて面白かった。
  • スポンサーLT3(gifteeさん): giftee Port リリースおめでとうございます!企画からリリースまでの流れがすごく丁寧で素敵。
  • 基調講演「準備中」: @zzak さんがこれまでどのようにRubyRailsと関わってきたのかを、CI関係のTIPSを濃いめに語ってくださった。物事を開始されるときに凄まじい量・質の情報収集をされているご様子が印象的だった。「知らなければ改善できない」という言葉は金言だなと感じた。
  • Rails アプリの 5,000 件の N+1 問題と戦っている話」: 1件のN+1を解決するために、人間は予想以上に色んなところを無意識に見てるんだなということに改めて気づいた。向き合いにくい時にも、目の前のものをサッと気軽に拾えるようにしてくれるというのが素敵。『目の前にごみが落ちたら拾うじゃないですか』確かに。
  • Async Gem で始める ruby 非同期プログラミング」: Async、Fiber、FiberScheduler のあたりの基礎知識があまりなかったので、検索しつつ拝見。大事そうな説明が時間の都合でスキップされていたご様子だったので、改めて資料をじっくり読みたい。
  • Exceptional Rails」: 正常系/準正常系/異常系のエラーの取り扱い方法についての丁寧な解説。Rails wayに沿ってうまく乗りこなしたい。初学者の方でもこのあたり悩まれるケース多いと思うので、説明の時の参考として紹介したい。
  • 初めてのパフォーマンス改善〜君たちはどう計測す(はか)るか〜」: 徹底して計測に基づいて一歩一歩改善していく過程が素晴らしい。また、PullRequestに "コードにしなかったこと" も合わせて全てまとめるという点もかなり重要。自分はちょっと徹底できていないところがあるので見習っていかねば。
  • Simplicity on Rails - RDB, REST and Ruby」: RESTful と DB の違いについて初学者の方に質問された時にうまく言語化できなくて詰まる場合があるが今後はこの発表見てね、とお伝えするのが良いかも。ログイン/ログアウトを sessions#new, #create, #destroy とするのがcoolというのは言われて気付いたが確かに素晴らしい。
  • Turbolinksアレルギー患者に捧げるTurbo & Stimulusでの時短実装術」: 自分もTurbolinksに振り落とされてやや苦手意識はあったが、怖くないよ〜〜〜とのことで上手くHotwireと付き合っていきたいなという気持ちになった。ココだけ使いたい、というレベル感でVueやReactを入れるのはやっぱりちょっとツラいので…。
  • 定数参照のトラップとそれを回避するために行う2つのこと」: 定数が心配なときは先頭 :: で回避しがちだったので、改めてどういう仕組みかのおさらいとさせてもらった。自分で定義するときは役割明確にと思い重複を避けるが、gemで利用されている定数をうっかり参照してしまう、はありそうなのでもし似たような問題を踏んだらこの発表を思い出して回避!
  • Active Record クエリクイズ」: Rubyコミッターでもあるpockeさんからのクイズということで、自分もかなり身構えて裏読みを試みましたが、シンプルに負荷高そうな方が正解な4問だった。ActiveRecordがデザインしてくれているカタチに素直に乗っかって使っていきたい。to_sql はいいぞ。

セッションメモ(Day2)

  • 事業の試行錯誤を支える、コードを捨てやすくしてシステムをシンプルに保つ設計と工夫」: ほぼ似てるからいいか、でテーブルを共通化して機能を捨てづらくすると後々ツラい。やはり機能を持ったままにするとメンテコストもあるので、素早く捨てられる状態を維持するのは大切。閲覧側にifを書きたくなったらテーブルごと分ける機運の兆し、というのは覚えておきたい。
  • Fat Modelを解消するためのCQRSアーキテクチャ」: CQRSアーキテクチャは未体験なので大変勉強になった。具体の実装としてUseCase/Query/Commandをうまく責務を分けて使うのはややコツが必要そうに感じた。でもうまくやればテストも分かれるしスッキリするな。Userモデル周りとかFatになりがちなのでそこだけ適用するとかアリかな?
  • E2E testing on Rails 2023」: ずっとCapybaraさんにお世話になってぬくぬくしていたので、Playwrightがそんなにシェアを伸ばしていたのは知らなかった。グラフで具体的に見ると衝撃。かなり速くなる様子なので、どこかのタイミングで触る機会を模索したい…。さっと入れたら動くかな?
  • 自分の道具を自作してつくる喜びを体感しよう、Railsで。〜 4年続いたPodcastを実例に〜」ゆるふわPodcastのいちリスナーとして興味深かったし、聴講者へ「自作サービスって良いなぁ」という気持ちを植えつける、侵蝕性の高いエモ発表だった。趣味と実益を兼ねたサーバを自由に運用…いいなぁ…なんか自分もやりたいなぁ。なんかすっごく眩しかったです。
  • ペアプロしようぜ 〜 3人で登壇!? 楽しくて速いペアプロ/モブプロ開発 〜」お揃いTシャツの3人、アクの強いAI挿絵、気合の入ったマイクパフォーマンスと見所が特盛。インパクトだけでなく、ペアプロの重要性をちゃんとデータで示してデモをきっちりやり遂げるのが流石。デモ中の何気ないやりとりの中に沢山のペアプロのコツが溶け込んでいて、百聞は一見に如かずの通り、大変参考になった。
  • Railsアプリにパスワードレス認証を導入した知見」: パスワードレス認証は、自分がいちインターネット民として生活しているなかで時々出会いますが、そういえば調べたことなかったのでwebauthn(gem)があると言うこと自体を知れたのが収穫。mac+firefoxで問題があるなどは自分で試して後で泣くより事前に知っておくと大変助かるので、有益情報だった。
  • コードカバレッジ計測ツールを導入したらテストを書くのが楽しくなった話」: テストコードを書く、という行動の促しのために、可視化(SimpleCov導入)だけではダメで、「ついでに書こう」という啓蒙でカバレッジ率が上がったとのこと。物事を進捗させるには導入するだけではなくアプローチの工夫もセットで必要なんだな〜ということがよくわかるエピソード。あと恥ずかしながら C0 などの概念を知らなかったので今後使っていきたい。
  • スポンサーLT4(pixivさん): Railsでお持ちの関連サービスについて、igaigaさん主治医のプロダクト健康診断を受けているとのこと。最新で偉い!!!
  • スポンサーLT5(スタメンさん): mainブランチに追従しているとのこと。こまめにやればそれは確かに日常ではあるが、言うは易し行うは難し…すごい。
  • スポンサーLT6(スマートバンクさん): B/43 は自分も活用していて大変お世話になってます! 規制準拠に応じてRails・Goの環境で切り分けられているとのこと。
  • 基調講演「A Decade of Rails Bug Fixes」: @byroot さんによるRailsのバグ解決に関するエピソード。なぜバグが発生したのかを徹底的に深掘り調査されていく過程にとても感銘を受けた。また、最終的にmergeを目指すにあたって、他者への丁寧な説明の大切だという点も盛り込まれていた。「コミュニケーションは大事。ナイスで愛想がいい。正しいよりも重要。」

Kaigi Effect

良い発表を浴びると色々やってみたいことが増えますね! 自分の元気度と相談しながらですが、色々とトライしていきたいです。

  • 来年スタッフ業やってみたい旨をお伝えする(済)
  • conference-app の機能で気になってる点があるのでPullRequest出してみようかな(考え中)
  • ブログ再始動 ※隔週くらい?
  • 来年のCFP提出を目指す

大江戸Ruby会議10で「生活発表」聴いてきた

「大江戸Ruby会議10」に参加しました。良き体験の記録。 https://regional.rubykaigi.org/oedo10/

予備知識

上記の通り、「大江戸Ruby会議」とは Asakusa.rb による "生活発表会" である。"技術"という制約が外れた(?) Rubyist たちの"生活"が覗けるユニークな会となっている。会場は浅草にある「雷5656会館」。確かコロナ禍前(第9回)に1度参加したことがあって、うろ覚えだったがスムーズに到着できた。ちなみに、会場名にかけて「3000円」の参加チケットとは別に「5656円」が準備されていたりする。

全体の感想

生活発表会なので、Rubyの話題は薄めに出たり出なかったりというレベルの存在感なのだが、全体的にテーマ選びや言葉尻の端々に「プログラマーっぽさ」が滲み出ているのがユニークだ。

みなさんが、発表が成立するくらい打ち込んできたものを持っている、ということ自体が眩しかった。個人的なここ数年の悩みのタネが「趣味の類を継続できない」ことなので、会から新しい刺激をもらって帰ってきた今、何かちょっとずつでもいいから取り組んでみたいと思っている。この気持ちの可用性を保っていきたい。

発表聞いたメモ

  • Days of struggle as a Cop : copをやったことがある、という言葉の解釈に一瞬戸惑う会場はおそらくふーがさんの狙い通りだったのだろう。オフラインのみだからこそのお話ありがとうございました!
  • 造って学んだ発酵食の世界 : パンと酒の共通点、確かに「発酵」ですね…。将来はエンジニアになるんですけど、という前置きに快諾をくれる世界に素敵な空気を感じました。酒造りの時期にRuby造りというのは浪漫がありますね〜。
  • 観る将、指す将、TyP 〜時を越えた将棋指しの魅力〜 : TyPって何だろう🤔 と思っていたら豊島将之(とよぴー)さんのことでした。自分は将棋の指し方は全然分からんのですが、棋士の方のエピソードは惹かれるものが多いですね。チラッとwikipediaをたぐったら幻の△4二角の話*1とか載っていてうっかり読み込んでしまいました。ドラマだなぁ…。
  • 朝会 : 「おはようございます」「テンション低いですね」から始まり「今日も一日がんばりましょう」で〆、まさしく朝会フォーマットを覗き込んでいるようで大変面白かったです。podcastの公開収録かな…?
  • YouTubeチャンネルを支える技術 : 日付だけで笑える回路、自分にも入ってました。後から10/15の回*2を拝見したら、まだ会の受付開始を10時だと思っているやんちゃさんが残っていて、vlogってすごいなと思いました。そしてやっぱり毎日これを続けられているということがすごい。可用性(1)。
  • 継続的 #RubyMuscleMixin 実践入門 : トレーニングに MTBFMTTR を適用するの納得感がすごかったです。自分もいま1年くらいランニング*3をしていますが、週1・やむを得ない用事とかの日は無理にしない・連続で出来なくても気にしない、出来る時は必ずやる…で続いているように思います。「"連続"ログインを考えない」のは実感として超大事。可用性(2)。
  • Hanamiを支える技術 2023 : 火気厳禁な "川" でいかに 🍶(熱燗) を楽しみ続けるか、という話。背負われていたデカい登山用?カバンから、電源 と 🍶 と あっためるマシン が出てきて、本気度と🍶にかける情熱を感じました。さすがです。可用性(3)。
  • IRB Committers and The World : 仕事のデバッグからプライベートのカンタンな四則演算まで、あらゆるシーンでIRBにはお世話になっております。さらにサジェスト機能が強力になっていくとのことで大変ありがたいです。引き続き何卒よろしくお願いします…!!!
  • その昔島根で起きたこと : Rubyの聖地・島根県松江市 のNaClさんの立場から観測されたRuby昔話、面白かったです。Ruby Association 発祥の図など、これまでにつながるRubyの歴史を垣間見れました。Rubyの試験ちょっと興味あるんだよな…受けてみようかな…。
  • 『Rubyメソッドかるた』王者への道 〜万葉チームのガチな取り組みを大公開〜 : 万葉さんがかるたに縁深いということは初めて知りました。Rubyメソッドかるた、手元にありますが、決まり字の観点から整理すると「ひきすう〜」で始まるのが多いのですね。「挑戦者はいますか? :)」から王者の風格 👑 を感じました…絶対勝てない…w
  • Yet Another Red Gem : 猫廼舎オーナーogijunさんによる「赤い宝石」= コーヒーの実 のお話。コーヒーの実が赤いということをそもそも知らず、液面のリングのお話など、コーヒーの世界の浪漫を垣間見ました。いつも作業用にインスタントばかりなので、たまには良い珈琲をお店で飲みたいなぁ。猫廼舎さん、現在は不定期営業とのことで、配信情報*4を要チェックですね。
  • WEB+DB PRESSと私 : 2023年夏に隔月誌としては休刊となった「WEB+DB PRESS」編集長の稲尾さんによるお話。最初はApacheRubyの読み方もままならなかったとのことですが、GitHubでPullRequestやissueをフル活用してエンジニアに執筆させる方式にされていたり、イベント懇親会("著者の狩場"…)にぷらぷらされるなど、現場に常に在ることを徹底されているのがすごかったです。エンジニアのすぐそばにいてくださった稲尾さんの姿勢が「WEB+DB PRESS」にも反映されたからこそ、愛される雑誌になったのだなぁと感じました。そしてすごく気になったので「日本語の作文技術」*5文庫をポチ。

花やしき

なんと懇親会は花やしきを貸切とのことで、人生初 && 豪華なUserExperienceをさせていただいてしまいました。

花やしき貸切
うわーーーほんとに貸切ってなってる すごい

誰も利用していない花やしきアトラクション
誰もいない…! ※このあとRubyistたちとかお子さんが乗って遊ぶ

8個のアトラクションが稼働していたのですが、お子さん連れご家族とご一緒させていただき、全部制覇できました。 ステージで大人たちが真剣にけん玉に取り組む姿が印象的でした。

良きエネルギーを充電させていただきました。来週10/27-28は Kaigi on Rails 2023、楽しみです!

*1: https://ja.wikipedia.org/wiki/真部一男#幻の妙手△4二角

*2: やんちゃクラブ 2023/10/15 「もっと早く始めていたとてこうなっていた」 https://youtu.be/eNT6P6RZ068?si=aqrCVhsqzJOgqsn6

*3: 3〜4kgくらい痩せました✌ たぶん走るの止めたらまたすぐに太る

*4:猫廼舎さん https://twitter.com/cafenekonoya

*5:https://www.amazon.co.jp/dp/4022618450 【新版】日本語の作文技術 (朝日文庫) 著:本多 勝一

SwitchBotAPI を使う・再(v1.1)

よくAPIを見ていたらv1.1とあったので、v1.1でちゃんとやりたいなと思ってリトライ。 最新は公式を読んでください。 https://github.com/OpenWonderLabs/SwitchBotAPI

アプリを更新

SwitchBotのアプリがまず古すぎたので(V4.5.0だった…すみませんズボラで…)、ちゃんと更新。2023年10月時点でiOSアプリはV7.7。更新したら登録してた設定が全部消えたと思って一瞬絶望したが、ログアウトしてただけだった。ログインしたらちゃんと復活した。

リクエストに必要な値を準備する

APIがv1.1になったことにより、リクエストのために必要な値が追加で増えたので、準備していく。

tokenとsecret

アプリの 設定 > 開発者向けオプション を10回連打で出てくる「開発者向けオプション」に、「トークン」と「クライアントシークレット」の2種類の文字列が表示されるようになった。トークンはアプリ更新前後で変更がなかったが、クライアントシークレットを今回新しくゲットした。

timestamp(t)

13桁のタイムスタンプが必要とのこと。これはUNIX時間(ミリ秒)のこと。
GitHubのサンプルにある t = 1661927531000 は、UNIX時間の解釈でいうと 2022/08/31 15:32:11(JST) となる。
参考: https://ja.wikipedia.org/wiki/UNIX時間

nonce

nonceとは何かをちょっとよくわかってない状態から開始。ランダムに生成するワンタイムの暗号トークンのことを指し、自由に決めてよいものと解釈した。

signを生成

公式APIを参考にsignを生成する。自分はRubyが好きなのでRubyで試みる。以下たくさん参考。無事取れた!

require 'securerandom'
require 'base64'
require 'httpclient'

TOKEN = 'xxxxx...'
SECRET = 'xxxxx...'

t = (Time.now.to_i * 1000).to_s
nonce = SecureRandom.uuid
sign = OpenSSL::HMAC.digest('sha256', SECRET, TOKEN + t + nonce)

header = {
  'Authorization' => TOKEN,
  'sign' => Base64.strict_encode64(sign),
  't' => t,
  'nonce' => nonce,
}

client = HTTPClient.new
res = client.get('https://api.switch-bot.com/v1.1/devices', header: header)
puts res.body

#=> {"statusCode":100,"body":{"deviceList":[{"deviceId":"D7B...","deviceName":"ハブミニ AD","deviceType":"Hub Mini","hubDeviceId":"...."},...] }, "message": "success"}

余談: SwitchBotサーバ側、Headerのパラメータが先頭大文字だと受け入れてくれなかった件

当初、Rubyの標準ライブラリ net/http で実装していたが、うまく返事を得られなかった。

uri = URI.parse('https://api.switch-bot.com/v1.1/devices')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

req = Net::HTTP::Get.new(uri)
req['Authorization'] = token
req['sign'] = Base64.strict_encode64(sign)
req['t'] = t
req['nonce'] = nonce

res = http.request(req)
puts res.body
#=> {"message":"Unauthorized"}

Rubyで生成したsignを、サンプルにあるJavaScriptのコードに適用すると使える…という状況だったためかなり頭を抱えていたが、調べた結果、次のようなことがわかった。

  • net/http では、ヘッダーフィールド名の先頭を大文字に変換する。
  • SwitchBot API では、ヘッダーフィールド名を先頭大文字にしたもの ( Sign, T, Nonce ) は受け付けていない(らしい)。
    • ゆえに、net/http を使って SwitchBot API を叩いても受け付けてくれない。
  • おまけの気付き: 1度認証すると数十秒くらいは Authorization (token) しか見ずに返事をくれている気がする。
    • jsサンプルコードで 200 を得てから Rubyの動かないコードを動かすと 同じ200 をしばらく返してくれる。

今回は問題解決のために net/http の利用を諦めて、httpclient を使ったところ、無事リクエストを成功させることができた。

参考:

デバッグの様子(net/http)

# net/httpの様子をチェック

uri = URI.parse('https://api.switch-bot.com/v1.1/devices')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.set_debug_output $stderr # 標準出力に出す

req = Net::HTTP::Get.new(uri)
# …略…

opening connection to api.switch-bot.com:443...
opened
starting SSL for api.switch-bot.com:443...
SSL established, protocol: TLSv1.2, cipher: ECDHE-RSA-AES128-GCM-SHA256
<- "GET /v1.1/devices HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: api.switch-bot.com\r\nAuthorization: xxxxx...\r\nSign: xxxxx...\r\nT: 1696770306000\r\nNonce: 34523524-e0a1-406d-bb20-f2dfcc2f0155\r\nConnection: close\r\n\r\n"
-> "HTTP/1.1 401 Unauthorized\r\n"
-> "Date: Sun, 08 Oct 2023 13:05:07 GMT\r\n"
-> "Content-Type: application/json\r\n"
-> "Content-Length: 26\r\n"
-> "Connection: close\r\n"
-> "x-amzn-RequestId: ae44ece8-bd88-41fd-8842-2c12caafa200\r\n"
-> "x-amzn-ErrorType: UnauthorizedException\r\n"
-> "x-amz-apigw-id: Me9YoEy3oAMEeIg=\r\n"
-> "\r\n"
reading 26 bytes...
-> "{\"message\":\"Unauthorized\"}"
read 26 bytes
Conn close

デバッグの様子(httpclient)

# httpclientの様子をチェック
client = HTTPClient.new
client.debug_dev = STDOUT # 標準出力に出す
res = client.get('https://api.switch-bot.com/v1.1/devices', header: header)
puts res.body

= Request

! CONNECT TO api.switch-bot.com:443
! CONNECTION ESTABLISHED
GET /v1.1/devices HTTP/1.1
Authorization: xxxxx...
sign: xxxxx...
t: 1696770516000
nonce: 90c09bc6-08b1-4078-b560-241a4c428e87
User-Agent: HTTPClient/1.0 (2.8.3, ruby 3.2.1 (2023-02-08))
Accept: */*
Date: Sun, 08 Oct 2023 13:08:36 GMT
Host: api.switch-bot.com



= Response

HTTP/1.1 200 OK
Date: Sun, 08 Oct 2023 13:08:37 GMT
Content-Type: application/json
Content-Length: 543
Connection: keep-alive
x-amzn-RequestId: 32b88a02-9b34-4a76-a4d4-73916e2ca52b
x-amz-apigw-id: Me95VGk7IAMEh5Q=
X-Amzn-Trace-Id: Root=1-6522a9d5-491163743186f65919874a15;Sampled=0;lineage=c8c2b0f2:0|bf95bacf:0