コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

相談するやり方を言語化したいときに見返したいスライド『こじれる相談とはサヨナラバイバイ! なめらかに協力する組織を生み出す基礎にして奥義「相談」で人を助けることを追求するぞ!』

「相談してね」とは言うけど、相談ってどうやるとすんなり行くんだっけというときに。

資料スライド

speakerdeck.com

みどころ

「相談」に焦点をあて、更に相談の質の話を踏まえ、最終的にはどこに焦点をあてて相談の内容をつくりあげていくとスムーズに相談ができるのかというのを紹介している。考え方を説明し、具体のケースを添えて書いてあるのでかなり頭に入りやすい資料となっている。

また、「相談する側」と「相談される側」でこじれてしまうアンチパターンを紹介している。「確かにこれやるとこじれるしどちらかの話をダメにしてしまう場合があるな…」みたいなものも紹介されているので頭の中でぼんやりと理解していたものを明文化されて糧になる資料でもある。

また自分が一番感銘を受けたのは『信頼』が言語化されていたところで

信頼とは誠実さの期待、能力の期待

という記載があり、自分の中でこの考え方がしっくり来たので今後使って行きたいと思えるフレーズだった。

関連リンク

JavaScriptの変数宣言がletがなぜ良いのかをざっくりまとめる

varはやめろ、という背景にあるものをしっかり説明できないのでざっくり書く

TL;DR

スコープの管理がletのほうがより区切られているのでそちらを使うべき

letのスコープとvarのスコープ

varはブロック({})で囲んだ中でも作用する

例えば以下のようなコードがあるとする

var a = 2
console.log("---start---")
for(i=1;i<2;i++){
  var a = i + 10
  console.log(a)
}

console.log("---result--")
console.log(a)

こうした場合にconsoleに表示されるのは以下のようになる

---start---
11
---result--
11

forスコープの中で変数の再宣言をしているから別枠で扱ってくれそうだが、varは関数全体に変数のスコープが及ぶため、for文の中のvar a が単なる変数の再宣言になっているだけになってしまっている。

letはブロック内で宣言すればブロック外に影響を及ぼさない

letで行うと、ブロック内で同名の変数を宣言するとブロック外には作用しない

let a = 2
console.log("---start---")
for(i=1;i<2;i++){
  let a = i + 10
  console.log(a)
}
console.log("---result--")
console.log(a)

このようにすると以下のような結果になる

---start---
11
---result--
2

なお、以下のように内部の宣言をvarにすると…

let a = 2
console.log("---start---")
for(i=1;i<2;i++){
  var a = i + 10
  console.log(a)
}
console.log("---result--")
console.log(a)

エラーになる。

Identifier 'a' has already been declared

これはletとしてaが宣言されているのに、ブロックスコープ内で再びvarで宣言すると競合するからだと思われる。

関連リンク

符号化文字集合と文字符号化方式の関係性に関してざっくりまとめる

UnicodeUTF-8と何が違うのか、という問いに答えられるようにざっくりまとめる

文字集合(符号化文字集合)とは

英語で表現するところの Coded Caracter Set。「文字」と「一意に振られた番号」のペアの集合体。「一意に振られた番号」のことを符号位置(code point/コードポイント)という。代表的なものはASCIIやUnicode

符号化方式(文字符号化方式)とは

文字集合の振られたコードポイントをバイト表現に変換するときの方式のこと。コードポイントは文字に対しての番号の情報だが、それを実際のバイト表現で使う場合にどのように扱うかの考え方が符号化方式。

たとえば JIS X 0208の形式の文字集合の場合、7ビットで扱うやり方で考え出されたのが ISO-2022-JP 、8ビットで平易に扱う考え方が EUC-JP 、同じ8ビットでも計算式を用いてビット数を割り出すのが Shift-JIS(この部分は関連リンクのサイト参照のこと)。

Unicode に関してはもっとシンプルで、16ビットで表現されたコードポイントをまま16ビットで扱うのが UTF-16 、8ビットで扱えるようにビット列を工夫するのが UTF-8

このように一意で決められたコードポイントをどう扱うかのルールが符号化方式と考えるとわかりやすい。

関連リンク

Kaigi on Rails 2021 で『before_actionとのつらくならない付き合い方』という内容で登壇してきました。

Kaigi on Rails 2021 の2日目にリモート登壇してきました。

発表したスライド

speakerdeck.com

伝えたかったこと

  • before_actionインスタンス変数のセットは本当にいいことがないのでやめよう
  • before_action の使い方がわからなくなったら横断的関心事かどうかで考えよう

補遺編

今回プロポーザルを作ろうと思った動機

今回出してみようかなーと思ったのは、大きく2つの動機があった

1つ目は過去の投稿「Railsのbefore_actionで通常のインスタンス変数をセットするのは、本当にそれが最適解か考えてからやってほしい - コード日進月歩」。こちらはもともとコードレビュー時にbefore_actionでインスタンス変数をセットするコードが出てきたときに自分が返した言葉を改めて言語化したものだった。

2つ目はjokerさんの以下のツイート

このようにみんな思うことが多いが、存外に語られていることが少ないので、もし発表できればbefore_actionのセットを盲信的にする人を減らせるのではなかろうかと思いプロポーザルを送った。

before_actionとscaffold

今回発表するにあたり、そもそもなぜscaffoldはbefore_actionインスタンス変数をセットするのかという謎を追いかけた。

ただこちらに関してはbefore_actionの前身であるbefore_filterの内容を漁ってみたが、糸口になる記述がつかめなかった。またscaffoldという概念自体はRails1.x系のときからある機能なので、GitHubのログからもなかなか辿れるものがなく、調査としてはそこで断念しました。。

before_actionと横断的関心事

もともとbefore_actionのサンプルとしてインスタンス変数が位置している側面があったので、もしそれを推奨しない話をするのであれば何に使うのがいいのか、自分なりの考えもセットで喋らないとただの「before_action禁止したいだけの話」にも聞こえかねないので、セットでオススメの思考法を合わせて届けたい思いがあった。

個々人の感覚として、before_actionを使う部分の話は多く合ったがそれを拾いあわせていくとAOPの考えである「横断的関心事」がハマるなと思い資料としてまとめました。

なお、自分が横断的関心事というフレーズにであったのはBEAR.Sundayの設計思想の説明のときで、その説明が自分の思考のパラダイムシフトだったので資料内にも参考資料として盛り込んだ。ご興味のある方はPHPer Kaigi 2018の動画があるのでそちらをご参考のこと。

登壇後記 & Kaigi on Rails2日目感想

  • 実は登場するコードの最終修正版までのコミットをしたリポジトリがひっそりとある(ただ途中で仕様を変えたのでちょっと違うので発表内ではカット)
    • 話の途中でも紹介したんですが、ベースコードはパーフェクト Ruby on Railsを参考にしながら組みました
    • 本当はdiffへのリンクをみてより初学者向けにしたかったんですが仕様を変えてしまった兼ね合いで断念
  • 2日目の登壇直前まで地味に微調整をしていた結果、他の方の発表を気合い入れて見れなかったのでそこがかなり残念。
  • 発表中に割と盛り上がった感じの反応を頂けてよかった
    • 横断的関心事というフレーズ、あんまり知らない人いたみたいで盛り込んでよかった
    • コード的にそもそも…みたいな話もあり、培養されたツラいコードなのでそこらへんは許してほしいというお気持ち
  • 登壇後のQAブースでbefore_actionやコールバック辛いよね談義をしたりしてました。
  • QA終了後READYFORさんのブースで色々とお話をさせてもらった。
    • 最近の仕事はRailsをつかってうまく新規開発させやすく、捨てやすくするかが課題なので色々とお話聞けてよかったです。
    • そのため割と後半の発表も見逃しがちになってしまった…配信に期待。
  • reBakoやSpatialChatの体験はすごくよかったです。懇親会でスタッフの皆様の大変だった話も色々聞くことで感謝の念が強くなりました、本当にお疲れさまでした。
  • 懇親会で「そもそもscaffoldが微妙であればPRを出してみれば?」という話を頂いたので、ちょっとSNSとしてのGitHubに慣れて出してみようかなというのがプチ課題としてできたので無理ない程度にやってみようと思っている。
  • チームの課題系ネタもあるが、日々のコードレビューで出てくるノウハウ的なネタもあるので、来年も何か集積していればCFP出したいなーと思いました。もしくはスタッフ的なお手手伝い。

関連リンク

『Kaigi on Rails 2021』の一日目みたよメモ

Kaigi on Rails 2021 の一日目見たよメモです。

各発表の感想

部分的に見れていないパートがあったので見れたものだけ ※資料スライドは見つけたら貼ります。


Q&A kamipo

トークについて

a_matsudaさんがモデレータという形式で話が進められていった。 以下話があったメモです。

kamipoさんについて

日本人のRailsコミッターは3人いるがのそのうちの1人という紹介。

バッチ作っているのってどのぐらいの時間帯か?

主に平日の昼から夕方ぐらい。土日が忙しいので、ある程度まとまった時間をとれるのがその時間であるからというお話だった。

仕事とRailsのフルタイムコミッターに関して

現在はDeNARailsのフルタイムコミッターとして活動している。DeNAに限らずだが、カジュアルに相談されることが原動力になっており、誰かが困っていることやこの仕様はRails側でどうにかしてもらえませんか?というようなことがあると実際に直す事自体も進めやすいとのことでした。

Rails7の仕事自慢

Rails7については長い期間取り掛かっていたので、思い出せる範囲だとenumのoptionに関する変更に関して言及があった。(たぶん このPR)

enumは指定する引数の関係でoptionの値に _ を先頭につける必要があったが、そこが気になったので修正をした。本来はenumのオプションを付け足したいことが発端だったが、optionの指定が気になったので先にそこから直したとのこと

RailsAPIでつらいもの

invert_whereの話題からRailsに不要ではないかと思われる機能の話題になった。Railsにも直感に反する機能、public apiでもなくていいいだろうと思う機能はあるということ。

kamipoさん自身はscopingの機能に関して長年苦しめられており、グローバルに影響する機能なので直しづらい状況であり、非互換性の機能を作って修正しやすいように持っていているが、そうするたびに反応がくるのでなかなか一筋縄では行かないとのことだった。

Railsに対するモチベーションと向き合う

kamipoさんは現在DeNAでフルタイムコミッターとして活動されている。それまで色々なことがあったという。

コロナ禍以前はOSSパッチ会などのmeetupがあったので、1ヶ月単位で自身のやってきたことに対してのフィードバックや意見をもらえることがあったが、それがなくなってしまい、無に対して活動しているような心境になり、そこからモチベーションが揺らいだと語る。

そこで前職を退職され(当時のブログ)、しばらくの間無職で過ごしていた、自分を危機に晒すことで生きるチカラが湧いてきて、生きるために何かしなきゃ行けない状況になったら違う景色が見えてくるのかも、という旨の話をされていた。

そうしてフルタイムコミッターとして働くことになった今の心境としては「他の人には真似できないぐらい積み上げたものが誰かのためになっているのであれば、このままでいればいいのかな」という旨の発言をされていた。

最後にkamipoさんから一言があり「Railsのコミュニティが盛り上がると、やっている活動の価値があがる、みんながRailsに興味を持ってくれると良いな」とのことでした。

感想

  • メモではざっくり書きましたが、実際はもっと実装の細かい話までされていて色々濃いめのトークでした。
  • 自分自身はプロダクトを作り上げる手段としてRailsを使っていることが多いほうなので、OSSに貢献しないとと思う部分もあるのですが、困っているユースケースを伝えていくことや、それを使えるようにしてくれたことに感謝をすることだけでも意義のあることなのかなと改めて思いました。
  • 個人的にはカレー情報も有益な情報です。

関連リンク


監視を通じたサービスの逐次的進化

感想

  • 不確実性に対して、監視を用いることで挑んでいく話。
  • 定時確認でしきい値の設定しづらいものを「形」で覚えるのは、なんとなくやり方としてはおぼろげに感じてはいたが名言されたことはなかったのですごい視点として定まった話だった。
  • ベータテストがあるとそのベータで「想定内の異常処理」と「想定外の異常処理」を洗っていくことができるので実地検証をしながら異常処理の潰しをしていく際にはとても参考になりそうな発表だった

関連リンク


medpeer.jp開発を加速させるエンジニアリング施策

speakerdeck.com

感想

  • medpeerさんが開発するにあたってどういうことをしているかというスポンサーセッション
  • docker-composeとdip、コメント駆動のプレビュー環境、フィーチャートグル、POROの処理分離、ネームスペースの取り扱い、RailsUpgradeなどいろいろな実践の話をしていた
  • ブランチ単位でプレビュー環境を立ち上げる機能が素直にすごいと思った、DBどうしているんだろう…

関連リンク


銀河スクラムマスター・ガイド

感想

  • スクラムをやるにあたり困ったらスクラムガイドをあたると良いというお話。
  • 実録スクラムチームができあがるまで、というお話だった
  • プロダクトオーナーが捕まらないからスプリントプランニングを2系統用意する話だった

関連リンク


ジュニアエンジニアが開発チームに貢献するためのTIPS

感想

  • 実際のコードという概念ではなく、メンタルの面でどう取り扱っていくべきかみたいなアプローチ
  • ここらへんそれなりにできちゃう人だとスッとやれちゃうんだけど、そういう人ばかりではないので、こういう情報を見てもらうことでアハ体験のようなものがあるかもしれないなと思った。
  • チームで仕事をする経験は抽象化すればどこでも転用可能なので、誰しもが経験しておくと良いのだろうなと思いました。

関連リンク


Railsシステムテスト解剖学

感想

  • 申し訳ないレベルかつ雰囲気でcapybaraを使っていたので、構造の説明の説明もさることながら順を追って踏み込んだ説明をしてくれたので「探り方」という点でも大変参考になった
  • Selenium一択だと思ってたので、Playwrightはすごい新しい情報だった

関連リンク


JSON Schema で複雑な仕様の入力フォームの実装に立ち向かった話

感想

  • ビタッとハマると全員が幸せになるJSONSchema管理の世界の話。
  • 各種gemが整備されているので、それに乗るだけでもかなりハッピーだし、仮にそれがなくても共通認識が取りやすいのでゼロイチでやるなら参考にしたいなと思いました。

関連リンク


Perfomance as Product Feature

感想

  • パフォーマンスと向き合う時にどういう部分で向き合えば良いのか、という話
  • 後半ではどういう切り口でキャパシティプランニングをするべきかという話を含めてあったのでインフラ知見を習慣的に貯めにくい私としてはとても参考になりました。
  • 人件費よりもサーバーのスペックを上げるほうがいいケースなど、割と技術一辺倒で挑む話でもなく、あらゆる方策を尽くして挑む系統のお話でした。

関連リンク


GraphQL SchemaからTypeScriptの型定義を継続的に生成する

感想

  • マネーフォワードさんのスポンサーLTだけど駆け抜けるようなGraphQLに関してのLT
  • GraphQLのschema定義を作ってTypeScript側と足並み揃えるだけにとどまらず、自動PR生成の仕組みまでできているのが仕組みで解決している感が凄まじくてすごかった(そしてちゃんとRailsの話だった)

関連リンク


Polishing on "Polished Ruby Programming"

感想

  • 研鑽Rubyプログラミング(仮)とそれに関する思いのお話。
  • 「XPの成功は、信頼できるソフトウェアのすばやい見積もり、実装、デプロイができる優秀なプログラマンーの増加にかかっている」からこそ「優秀なプログラマー」を増やしたいという話はすごい刺さった
  • 発表のあとに右下の角谷さんコメント見ながら見ると違う発見があった。

関連リンク


Build and Learn Rails Authentication

感想

  • 認証技術の理解を深める、認証ライブラリの選択を手助けするというテーマのお話
  • 序盤で基礎的な認証の話から入り、最終的にDeviceなどのgemの話に落ち着く構成で、ログイン周りを考えるときにスッと出したい資料でした。
  • いまの環境がsorcery一辺倒なので、ちゃんと考えないとなと思うのでした…。

関連リンク


FactoryBotのbuild strategiesをいい感じに直してくれるgemを作った話

感想

  • FactoryBotのcreateをbuildにしたい!というgemの話。
  • やってみよう!と思いはするけれど自分の場合は途中で力尽きちゃう感じなのでこういう技術的なモチベーションはただただすごいなと思いました。完成すれば自動テストプロセスに入れてみたい感じのやつ

関連リンク


STORES へのID基盤の導入と、ユーザーアカウントの移行を振り返って

感想

  • アカウントの統合とその際に苦労した事に関してのお話
  • さきほどの話と合わせて、独自実装をしてはいけないという話をちゃんと忠実にやっていて地続きな感じになっていてよかった。加えてエバンジェリスト派遣という取り組みがあるのは知らなかった
  • 認証基盤に関わるものがみんなOAuthのRFC読むのはとてもいい取り組みだなと思いました。

関連リンク


RailsエンジニアのためのNext.js入門

感想

  • Next.jsに関して、Railsエンジニアにもわかりやすく解説された話。
  • Next.jsがどういうものであるかという話もわかりやすく、各種レンダリング手法の解説もとてもわかりやすいものでした。
  • ActiveRecord使わないならNext.jsで組むっていうのがいいのかなと最近思っていたので今のタイミングで見れてとても良かったです。

関連リンク


クローズしたはずのサービスが知らぬ間に蘇っていたのでクローズしきった話

感想

  • どこのWebサービスでもありうる怪談
  • 一度取得してサービスを運用したのであれば、一旦は保持するのが無難なのだろうなと思った

関連リンク


1日目全体を通しての感想

  • 2日目は発表する都合上わたわたするのでとりあえず1日目は発表を中心に見てました。
  • Railsを中心としてWebサービスのお話も多く、日々の仕事にも生きる内容が多かったです。
  • 加えてRubyというものをどう考えるかという話に関してもあり、バラエティに富んだ話でした。

GitHubが管理する.gitignoreのテンプレート集リポジトリが存在する

小ネタ。

該当ページ

github/gitignore: A collection of useful .gitignore templates

何があるのか

メインはプログラミング言語やプログラミングフレームワークに向けたgitignoreのファイルとなるが、JetBrainやMonoDevelopなどIDE向けのgitignoreに関しても置いてある。

READMEに詳しく書いてあるが公式情報などをPRで提示してマージしていくような運用になっている様子

関連ページ

RubyのCSVクラスを使ってTSVを読み込む場合にダブルコーテーションの入っているものがあるときの対策

パースエラーになる、のでワークアラウンド的な対策

環境

$ ruby -v
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-darwin19]

やりたいこと

正常に変換できるケース

例えば以下のような test1.tsv があるとする(タブはHTMLの表現上うまく出ないので雰囲気だけ)

id    name    text
1   taro    sample text
2   ziro    hello!
3   saburo  cry

この場合に以下のようにすれば読み取れる

require "csv"
result1 = CSV.read("test1.tsv", col_sep: "\t", headers: true)
result1[1]["text"]
# => "hello!"

異常がおきるケース

例えば以下のような test2.tsv の場合は、ダブルコーテーションが入っている要素があるのでパースできない。

id    name    text
1   taro    sample text
2   ziro    say "hello"
3   saburo  cry

この場合、パースエラーが出てデータが取れない

require "csv"
result2 = CSV.read("test2.tsv", col_sep: "\t", headers: true)
# /Users/hogehoge/.anyenv/envs/rbenv/versions/3.0.1/lib/ruby/3.0.0/csv/parser.rb:925:in `parse_quotable_robust': Illegal quoting in line 3. (CSV::MalformedCSVError)

回避策

エラーとしてはもともとのCSVとしての仕様として " で各要素を囲むことに対する仕様があるため、そちらとの兼ね合いで正確にパースができず失敗してしまう。

そのため、この厳密さを回避するオプションである liberal_parsing: true とパース自体はすることができる。

result2_ex = CSV.read("test2.tsv", col_sep: "\t", headers: true,liberal_parsing: true )
result2_ex[1]["text"]
# => "say \"hello\""

関連リンク