ティレログ

プログラミング学習中の専業主夫です。

変数名とメソッドの責務が難しい

Discordを使ってのログイン機能の作成

現在自作サービス作成中。 RailsでDiscordログインを実装する方法 #OmniAuth - Qiita

この記事を見ながらログイン機能を実装している。

その中で

models/user.rb

class User < ApplicationRecord
  def self.find_or_create_from_discord_info(discord_info)
    User.find_or_create_by(uid: discord_info.uid) do |user|
      user.update!(
        uid: discord_info.uid,
        name: discord_info.info.name,
        image: discord_info.info.image
      )
    end
  end
...

のようにDiscord側から得た情報からユーザー情報を検索、該当なければ新規作成(find_or_create)している。

ただDiscord側のユーザー名やアバター画像は更新されることがある。

ログイン処理と更新処理は併せて処理したい。

find_or_create~upateの処理を入れる?

models/users

def self.find_or_create_from_discord(auth_info)
  user = User.find_or_initialize_by(discord_user_id: auth_info.uid)

  user.update!(
    name: auth_info.info.name,
    avatar_url: auth_info.info.image
  )
end
...

find_or_create~内部処理を - findで見つからないときはinitialize - find_or_createで作成されたインスタンスのnameとavatar_urlを追加してupdate

で対応してみたが、なんとなくメソッド名と処理内容が合ってる気がしない。

updateが副作用っぽくなってしまう。

分けて定義する?

models/user.rb

def self.find_or_initialize_from_discord(auth_info)
  User.find_or_initialize_by(discord_user_id: auth_info.uid)
end

def update_from_discord(auth_info)
  update!(
    name: auth_info.info.name,
    avatar_url: auth_info.info.image
  )
end

責務は分離できているが、各処理を呼び出す際に

users/sessions_controller.rb

...
def callback
  auth_info = request.env["omniauth.auth"]
  user = User.find_or_initialize_from_discord(auth_info)
  user.update_from_discord(auth_info)
  log_in user
  redirect_to root_path, notice: "ログインしました"
end

のようにcontroller側で2つの処理を分けて書かないといけない。 これは1つにまとめたい。

呼び出しををまとめてみる

models/user.rb

class << self
  def sync_with_discord(auth_info)
    user = find_or_initialize_from_discord(auth_info)
    user.update_from_discord(auth_info)
  end

  private

  def find_or_initialize_from_discord(auth_info)
    find_or_initialize_by(discord_user_id: auth_info.uid) 
  end
end

private

def update_from_discord(auth_info)
  update!(
    name: auth_info.info.name,
    avatar_url: auth_info.info.image
  )
end

みたいにする。

呼び出しはsync_with_discordでまとめられたが、privateメソッドを複雑に作り過ぎている気もする。

最終的に

models/user.rb

def self.sync_with_discord(auth_info)
  user = User.find_or_initialize_by(discord_user_id: auth_info.uid) 
  user.update!(
    name: auth_info.info.name,
    avatar_url: auth_info.info.image
  )
end

この形にまとめたが、sync_with_discordDiscordと同期という訳になり、処理の内容がメソッド名から推測できるかちょっと不安である。

メソッド名がしっくり来ないときは、 「責務が大きすぎるのでは?」 と疑いたくなる。

ただ今回のように、

  • ユーザー検索
  • 新規作成
  • 更新処理

を「ログイン時同期」という1ユースケースとして扱うなら、 ある程度まとめた方が使いやすいと判断した。

設計難しい。

コメントを返す際に気をつけていること

この記事は

フィヨルドブートキャンプ Advent Calendar 2025 | Fjord Calendarの6日目の記事です。

前日の記事はmouseさんの

なぜ、あなたの仕事は終わらないのか スピードは最強の武器である を読んで - BUNBUNdiary

です。

mousufbc.hatenablog.com

 

記事自体のスピード感が半端なかったです・・

 

自己紹介

はじめましてtyrrellです。

前職公務員で現在専業主夫です。

 

コードレビューのやり取りを後から振り返ると・・

フィヨルドブートキャンプでは提出物に対しコードレビューを受ける機会がありますが、レビュー時のやり取りを振り返ってみると

 

「あれ、なんでこの修正にしたんだっけ?」

 

とか

 

「メンターさんのコメントの意図を、このときの自分は理解できていたのか?」

 

など思うことがあったので、なるべく後から振り返ってもその時の思考過程がわかるようなコメントを返すように心がけています。

 

今回はそのことについてアドベントカレンダー用のブログにしてみました。

 

どんなことをコメントに残したら良いか?

レビュアーとのコメントのやり取りの中で、その時の

  • 現在のコードの問題点に対する認識
  • 問題に対する改善案
  • 改善案の根拠・思考過程

を振り返ることができる状態が望ましいと思っています。

 

「修正のコミットの内容を見れば、その思考過程も大体想像できるのでは〜」

 

と言われればその通りですが、「結果的に修正のコードは合ってるけど内容をちゃんと理解をしていなかった」ということもあり得るかと思うので、学習中の立場である限りはできるだけ思考過程をコメントとして残しておきたいという気持ちです。

 

ただtypoのような指摘にいちいち「typoした原因は〜」とかを残したりはしないので、

  • 自分の知らないことを教えてもらった時
  • 後からこのやり取りを振り返って思い出したいと感じた時

の場合だけ詳細を残す感じです。

 

例えばこんな感じ

このようなレビューに対して

  • 現在のコードの問題点に対する認識
  • 問題に対する改善案
  • 改善案の根拠・思考過程

をできるだけ詳細に残しておくと、その時の思考過程が振り返りやすいです。

 

具体的な解決策の提示を受けた場合でも自分の考え付け加える

「〜のように修正してください」というように、

  • 問題点
  • 具体的な改善例

がレビューコメントにて示されている場合、「指摘された内容からその時の思考過程が再現できる」ので「修正しました〜」だけでコメントを返すことも多いかと思います。

 

ただ、このような場合でも

 

「◯◯の修正は、××の意図だと解釈しました」

 

という自分の理解を付け加えておくことで「レビュー内容に対する自分の理解度」を振り返りやすいです。

 

またメンターさんから追加の情報をもらえたりしてお得な時もあります。

 

自信がないという最後の一言は余計でした
補足;教えてもらった参考記事等は必ず目を通す・検証する

参考記事を紹介してもらった際には、確認したことをコメントに残します。

 

理由としては、紹介してもらった参考記事が現在においても有効な記事かは検証しないとわからないからです。

 

役に立ったなら「役に立ちました!」とメンターさんに伝えることも有効なフィードバックになるかもしれません。

 

 

最後に

書き終わってみると「当たり前のことしか書いていないのでは・・」と思いましたが、当たり前のことを続けていくことが自分の成長につながるのではと思っています。

 

今後も日々試行錯誤していきたいです。

 

唐突に本の紹介

伝わるコードレビュー 開発チームの生産性を高める「上手な伝え方」の教科書(鳥井 雪 久保 優子 諸永 彩夏 島田 浩二)|翔泳社の本

www.shoeisha.co.jp

コードレビューしたりされたりするとき「どういう言い回しにしようかな?」と悩むことも多いかと思いますが、いろんな例が載っているのでとても参考になると思います。

 

 

金柑を甘く煮てみました

表題のとおり、金柑を甘く煮ました。

何故金柑を購入したのか

子供達とスーパーに買い物に行ったところ袋いっぱい(500gくらい)の金柑が売ってました。

袋に「そのまま食べれる」と書いていたので、「金柑って生で食べれるの?皮ごと?」と訝しんでいると

長男が「買いたいよー!!」と言い出したので、物は試しと購入しました。

生で食べてみて

食べれませんでした。普通にみかんを皮ごと齧っているのとあんまり変わりませんでした。

私の様子を見て、長男は金柑に対する興味を失っていました。

金柑を甘く煮る

金柑の扱いに困ったのでクックパッドでレシピ調べた結果、甘露煮にすることにしました。

まず水洗い

洗った金柑、何個か頑張って齧った結果数が減ってます

一回茹でてアクを抜きます。

アクを抜く作業があるということはエグ味があるのでそのまま食べてないのでは。。?

パッケージの「そのまま食べれる」は「生で食べれる」ではなく「(調理すれば)皮ごと食べれる」の意味だったと思われます。

そのあと、金柑の横っ腹に切り込みを何箇所か入れて、箸を突っ込んでタネを取ります。

この作業が結構大変でタネを取り終えるのに2時間くらいかかりました。

タネの場所を勘で探り当てるのに中々慣れなかったのと、手が荒れていて金柑の汁で手が痛いのでかなり辛い作業でした。

タネは結構ほじくらないと取れない
1つの金柑に3〜6個のタネ

最後に甘く煮ます

何通りかレシピがあり、金柑の重量の50%くらいの砂糖で何時間か煮込むものとかもありましたが、今回は金柑の重量の20%くらいの砂糖で1時間くらい煮込むやり方にしました。

水、砂糖、みりんで煮込む

出来上がり

出来上がりは結構甘そうな印象

食べた感想

一見結構甘そうですが、割とさっぱりしてます。

一回に何個も食べれそうになかったので、お湯に入れて砕いて飲みながら消費することにしました。

なんとなく喉の調子も良くなった気がしました。

フィヨルドブートキャンプに入会してよかったこと

この記事は「フィヨルドブートキャンプ Part 2 Advent Calendar 2024」21日目の記事です。
フィヨルドブートキャンプ Part 2 Advent Calendar 2024 - Adventar

adventar.org

昨日記事はyokomaruさんの輪読会で出会ったGit Bisectを理解したい~輪読会の良さみを添えて~ - returnえんじにゃーでした。

また、Part 1 もあります。 フィヨルドブートキャンプ Part 1 Advent Calendar 2024 - Adventar

adventar.org

Part 1の昨日の記事はKazuma.Nさんのフィヨルドブートキャンプのフロントエンジニアコースで学び始めて6か月たった。 - AndroidDev1721’s blogでした。

はじめに

 私は2023年5月からフィヨルドブートキャンプに参加しています。
簡単に自己紹介すると

  • 奥さんと子供2人(長男6歳、長女4歳)の4人家族
  • 年齢は30代後半
  • フィヨルドブートキャンプ入会前まで公務員として働いていて、現在専業主夫
  • プログラミングはほぼ未経験

みたいな感じです。

フィヨルドブートキャンプ入会に至った経緯

 家庭内の諸般の事情から育児の方により多くの時間をかける必要が生じたため、約15年くらい勤めた職場を退職しました。

 仕事を辞めた当初は再就職できる時期の目処が立っておらず、「子供が2人とも小学生になるまでは専業主夫かな」と考えていましたが、将来の再就職に向けて少しでも何かしておきたかったので、資格試験もしくはプログラミングのどちらかで今の自分でもやれそうなことを探していました。

 そんなとき見つけたのがフィヨルドブートキャンプで

  • 30代未経験からでも転職できた実績がある
  • 月の費用が30,000円程度で、自分の手元に残っているお金からでも払えそう

の2点で入会を決めました。

フィヨルドブートキャンプに参加してよかったこと

家庭以外の居場所ができた

 入会する前のフィヨルドブートキャンプのイメージは

  • 学習の進捗管理が厳しそう
  • 20代の方が中心で30代の方は少数
  • プログラミングの学習が自分に合わなくて、すぐ退会してしまったらどうしよう

と考えていましたが、実際に入会してみると

  • 学習の進捗管理はほぼなく基本的に自分のペースで学習
  • 20代と30代の方の人数は同程度。10代の方や40代、50代も在籍している(していた)
  • 休会・退会は自由で、そこからの復会・再入会も自由

といった感じでした。

 プログラミングを学習したい気持ちの反面、自分の経歴(年齢、専業主夫やってること等)の点で「なんでこんなところにいるの?」と思われて居心地悪かったらどうしよう・・とか考えていましたが、全くそんなことは気にする必要ありませんでした。

 受講生の年齢も幅広いですが、働きながら参加している方、学生の方、専業主婦の方、仕事辞めて参加している方等の様々な経歴の方がいました。
そもそも他の人の経歴を気にしている人はほとんどいないような気がします。

仕事を辞めてから社会との繋がりが途絶えてしまった感があったので、

「自分がそこに居ても変ではないコミュニティ」

に出会えたことはとてもよかったことでした。

相手に伝わりやすい文章を考える練習ができた

 フィヨルドブートキャンプは完全オンラインのスクールなので、メンターや他の受講生とのやり取りはオンラインでのテキストのやり取りが主になります、
 例えばスクールで用意されている各プラクティスの課題の提出については、

  1. GItHub上で課題を提出
  2. 課題をレビューしてもらう
  3. それに対しコメントを返す・内容の修正をする

というやり取りになり、チャットのようなリアルタイムでのテキストのやり取りとまた勝手が違います。

そのやり取りの中で、例えば「何かエラーが発生し、それを解決するために相談したい」という状況が発生した場合には

  • どんなエラーが発生したか
  • どんな資料を提示すれば相手にそのエラーを確認してもらえるか
  • エラーが発生するまでの手順
  • エラーを解決するために調べたこと
  • エラーを解決するために試したこととその結果
  • 自分の使用している環境の詳細
  • etc

等を適時組み合わせながら相手に伝わるように説明する必要があり、自分の考えを伝える能力に自信がなかった私にとっては良い学習の機会になりました。

 対面コミュニケーションの場合だと、困っていることを質問する際に曖昧な言い回しをしても「相手が内容を推測してくれて解決できてしまう」こともあるので、その辺の言葉によらないコミュニケーションに今まで頼りすぎていたのかもしれません。

 また公務員だった頃は「相手に伝わる文章か?」より「公用文に沿った書き方か?」を優先していた節があるので、改めて相手に伝わる文章を書く練習ができたことはとても有意義でした。

「調べる学習」の習慣がついた

 フィヨルドブートキャンプでは、新しい知識を習得する際にはまず公式のリファレンスマニュアルを参照するように指導されています。
 単にプログラムが動作すれば良いのであれば、QiitaやZenn等に掲載されているプログラミング関連の記事からコードをコピペしても良いかと思いますが、

コードを書くこと==自分の書いたコードに責任を持つこと(なぜ動くのか説明できること)

という姿勢がフィヨルドブートキャンプでは求められているため、使ったことのないメソッド・ライブラリ等を使用する際には公式のリファレンスマニュアルを一読する習慣が付きました。
(リファレンスマニュアルが英語だったり、言い回しが難しくて先にQiita等の記事で概要を把握してからリファレンスマニュアルを読むことも多いですが。。)

 公務員として働いた頃は事務のマニュアルを読み込むことはあってもその基となる法律・通達までは日々の仕事で忙しくて確認できないこともあったので、信頼できる資料を基にして学習する習慣を身に付けることができたのはとても良かったことでした。

 また、現在の私の力量では、例えばプログラミング言語 Ruby リファレンスマニュアル等は一次情報になるのですが、もっと勉強を進めて例えばRubyソースコードを読めるようになると自分が一次情報とするものの深度が増して自分にできることも増えてくると思うので、そういうところもこれからの学習の楽しみになっています。

最後に

 フィヨルドブートキャンプでの学習の楽しさ・居心地の良さを感じた反面、他の受講生の方との交流に一歩足を踏み出せなかったところがあるので、来年はRubyKaigi(松山はちょっと無理かも・・)などの技術イベント、地域.rb、フィヨルドブートキャンプ内の輪読会への参加へ積極的に参加できるような一年にしたいです!!

VSCodeでcodeコマンドが効かなくなる原因を調べる

初めまして、ティレルと申します。現在プログラミングスクールでプログラミングの学習中です。
今回はVSCodecodeコマンドが、PCのシャットダウン、再起動をした後にcommand not foundとなってしまいコマンドが効かなくなる原因について調べてみました。

環境:macOS Ventura13.4

codeの所在を確認

まずcodeコマンドのファイルの場所を調べます。

which code

/usr/local/bin/code

次にls -lでファイルの概要を確認します。

ls -l /usr/local/bin/code

lrwxr-xr-x  1 root  wheel  167  6 12 18:07 /usr/local/bin/code -> /private/var/folders/7k/m_lf2w4159bdxjz2y5tlwtl40000gn/T/AppTranslocation/95D363FC-571A-4C40-8B31-261EC1F3ACAA/d/Visual Studio Code.app/Contents/Resources/app/bin/code

ここでcodeコマンドがシンボリックリンクであり、元のファイルは別の場所にあることがわかりました。

次にPCを再起動して再度codeのパスを確認してみます。

which code

code not found

この段階でcodeコマンドが効かなくなりました。 次に先ほどのシンボリックリンクを確認してみます。

ls -l /usr/local/bin/code

lrwxr-xr-x  1 root  wheel  167  6 12 18:07 /usr/local/bin/code -> /private/var/folders/7k/m_lf2w4159bdxjz2y5tlwtl40000gn/T/AppTranslocation/95D363FC-571A-4C40-8B31-261EC1F3ACAA/d/Visual Studio Code.app/Contents/Resources/app/bin/code

シンボリックリンクは残ったままです。パスが通っていないだけでしょうか? リンク先のファイルを調べようとした結果以下のことがわかります。

ls -l /private/var/folders/7k/m_lf2w4159bdxjz2y5tlwtl40000gn/T/AppTranslocation

total 0
dr-xr-xr-x  3 username  admin  0  1 10 10:19 E14EA***-****-****-****-************

AppTranslocationというディレクトリの中にあるはずの95D363FC-571A-4C40-8B31-261EC1F3ACAAというディレクトリがPCの再起動によってなくなってしまいました。シンボリックリンクの参照先ファイルがなくなってしまったので、codeコマンドが効かなくなってしまったと考えられます。

解決方法

このような現象が発生する原因は、私がVSCodeApplicationsディレクトリへ移動させずDownloadsディレクトリへ残したまま起動させていることが原因でした。 なので、VSCodeDownloadsディレクトリからApplicationsディレクトリへ移動させれば問題は解決します。

解決方法実行時の動作確認

  • まずVSCodeApplicationsディレクトリへ移動させます。
    ここでいうApplicationsディレクトリはルートディレクトリ直下のApplicationsディレクトリのことであり、各ユーザーのホームディレクトリにあるApplicationsディレクトリのことではありません。

  • 次にcodeコマンドをアンインストールした後、再インストールします。(VSCodeのコマンドパレット上の操作になります)

  • 最後にcodeコマンドの場所を確認し、ls -lで内容を確認します。

which code

/usr/local/bin/code
ls -l /usr/local/bin/code

lrwxr-xr-x  1 root  wheel  68  6 12 23:14 /usr/local/bin/code -> /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code

このようにシンボリックリンクの参照先が変更になりました。 これ以降はシャットダウン、再起動を行なってもcodeコマンドを実行できます。

原因

MacにはGatekeeperというセキュリティ機能があり、それが原因でした。

  • Gatekeeperはダウンロード後に自動展開した場所からアプリケーションを起動した場合にパスのランダム化を行う。
  • パスのランダム化は、読み取り専用に設定されたファイルシステム中の不特定の場所からアプリケーションを起動することで、アプリケーションが相対パスを使ってコードやコンテンツにアクセスすることを防ぐ。

とのことでしたが、仕組みについては理解が追いついていないのでもう少し学習が必要だと思いました。
出典:macOSのセキュリティ

総括

今回の件については私の知識の不足が原因でしたが、色々調べることで勉強になりました。


参考