これは「Happiness Chain Advent Calendar 2024」の2日目の記事です。
はじめに
みなさん、こんにちは。現在連続15連勤中、自称体力おばけのmatです
今回は、11月に実務で私が経験した、ruby, フロントエンド(useSWR)、そして最後にフロントのデプロイ+ ちょいポエムの4本仕立てにしようと思います
ruby (キーワード引数)
キーワード引数はrubyを勉強してチェリー本を読んだみなさんならご存知だと思います。
キーワード引数を使うメリットはそのメソッドが何しているかがわかりやすくなるという点だと思います。
def hello(name: "Guest", age: nil, country: "Unknown")
puts "Hello, #{name}!"
puts "You are #{age} years old." if age
puts "You're from #{country}."
end
こんなやつです。
def hello(name = "Guest", age = nil, country = "Unknown")
puts "Hello, #{name}!"
puts "You are #{age} years old." if age
puts "You're from #{country}."
end
これとは違います。後者は通常の引数にデフォルト値を渡しているだけです。
僕はこれの違いに一瞬で気づかなくてエラーの沼にハマってました。
デフォルト引数を使っていると思ったらよく見たらキーワード引数だった。っていうエラーです。(しょうもないですけど、3ヶ月も経験すると沼エラーの原因は大体こんな感じになります。多分。)
注意していただきたい点がありまして
引数名は必須になる
def hello(name: "you")
puts "hello#{name}"
end
# 出力
# これだとエラーになる
hello("you")
hello(name: "you")
キーワード引数を使うとメソッドの引数名が必須となります。
これに3時間もかかった理由は2つありまして、
- Rubyの文法の知識が浅い
- エラーログを基準に深く考察してなかった
1に関してはキーワード引数について知っていれば、なんてことなかったでしょう。
経験不足の部類なので、次回以降気をつければいい話です。
2に関しては
このエラーは
# エラー: wrong number of arguments (given 1, expected 0; ~~~~~)
このようなエラー文が出まして、引数あたりに目をつけたまではいいがもっと注意深く考えるべきだった。と今になって思います。(あれ〜引数入れてるよ〜、おっかしいなぁ)
エラー文を読んで一旦立ち止まって原因を考察することは、エラーを単なる障害としてではなく、学習の機会として捉えることで、継続的な成長につながりこれがプロフェッショナルな開発者への道へと続く,,,,,,,はずです。
反省とエラーログは大事!
キーワード引数の詳細に関しては下記に、勉強になる記事を記載したのでそちらを読んでください。
勝手に引用させていただきますが、こちらの記事が大変わかりやすかったです。
また、チェリー本の著者の記事も大変勉強になりました。
pythonもキーワード引数あるらしい。
フロントエンド(useSWR)
実務では、サービスを完成させるためにはもちろん期限というものがあります。
完全なサービス、100%盛りだくさんの機能を作るということは工数的に現実的ではないことも多いです。まして、バックエンドとフロントエンドが分担していれば、それぞれに優先順位というものがあります。
そうなると、フロントエンド側で欲しい情報が必ずしも取得できるわけではないです。
(期限に切羽詰まると特に)
仮に、例えば人 - パスポート - ビザ情報というデータ構造があったとしましょう。
カスタムhookにはuseSWRを使ってます。フックの内部処理は除きます。AIに聞いてください
//簡単に処理を説明するとページのクエリからuserIdを取得してそれを元にuserを取得し、さらにuserと1対1関係のpassportオベジェクトidからviza情報を取得する
const { id: userId } = router.query;
// 特定のuserを取得するSWRのhook
const { data: user } = useUser({
id: userId as string
});
// userが所持しているパスポポートに紐づいたビザ情報を取得するSWRのhook
const { data: vizas, isLoading } = useVizas({
// クエリ処理
passportId: {
eq: user?.passport?.id as string
}
});
このような処理を記述するとどうなるか。みなさんご存知だと思いますが,,,,,,,,簡単なこと記事にして申し訳ないですね。
useUser自体が非同期処理ですのですが、useUserとuseVizasの処理に依存関係はないためuseUserの結果が返ってくる前にuseVizasが実行されます。
故に初期段階ではuseUserはundefindedであり、useVizasのリクエスト適切に実行されません。
ではどうするか、useSWRには条件付きフェッチというものがありkeyにnullやfalseを与えるとそれまでSWRはリクエストしません。
// 条件付きでフェッチする
const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher)
つまり
const { data: user } = useUser({
id: userId as string
});
// userが所持しているパスポポートに紐づいたビザ情報を取得するSWRのhook
const { data: vizas, isLoading } = useVizas({
// クエリ処理
passportId: {
eq: user?.passport?.id as string
},
// キーをnullやfalseにする要素
disable: user
});
undefinedもfalsyな値なため、userが取得できていない状態でuseVizasは実行されません
まあ、バックエンドの方でシリアライズしてくれるまでの応急処置ですかね。
他にも使えるなと思ったSWRのオプションとして
- dedupingInterval
かな?
変更頻度の低いデータに対し毎度api叩くのは無駄なので、パフォーマンス向上のため??に必要かもなと感じてます。
まだまだ、SWRは使いこなすのが難しいです。
いっぱいオプションあります.....
フロントのデプロイ
サーバーサイドのデプロイと違ってフロントのデプロイは複雑な条件とか無視するなら楽勝です。Next.jsに限って。
右にドロップダウンがあるので,Add NewのProjectですね
そこから次のページに行ってリポジトリを選択or検索して、import 押すと設定画面にいきます。
設定画面ではあなたのpackage.jsonを見てここに記述!
環境変数、主にサーバーサイドのURLを記入します!
環境変数は後でも記入できますが、入れたら再ビルドが必要になります
デプロイ!
恐ろしく簡単ですね!
現状、調べたところ一つのリポジトリに複数の本番環境を持つことはできないそうです。
つまり、mainに相当するgithubのbranchのみデプロイ可能。
最後にポエム
EMP等が起こって原始的な世の中にならない限りはLLMの精度は上がっていくはずだし、それに伴ってコードを書けるだけの人材の価値はごく一部の天才を除いて低くなると実務を経験して思いました。
AIだけで解決できる課題は少ないため決してプログラマの職が完全にすぐなくなるとかではないですけど、実務3ヶ月程度でまぁまぁ動かせているのはLLMのおかげには変わりはないです。AIがなかった世界線での経験年数1.5年 ≒ 実務3ヶ月+LLMくらいかな?
人とのコミュニケーション(情報伝達等の社会人としての報連相)や仕様に対する理解度、ChatGpt等が生成するものに対してユーザーにもっとも価値を与えられるものを選択できる判断力と決断力などのソフトスキルと言われる領域がこれからのプログラマーは必須だと感じましたし、持っている人が強いと思います。(あくまで個人的感想)
私自身もそれに対してまだまだですし、しっかりできていれば工数削減できていたなぁと感じております。
(バックエンドのカラム変更だったり、フロントのデータの使い方をstakeholdersや各リーダーと綿密に都度詰めることの重要さを学びました)
こんなふうに思っているプログラマーもいるんだなくらいに思ってください。
ここまで稚拙な文を読んでいただきありがとうございました!
2024年関わってくれた皆様ありがとうございました。元気にひぃひぃ言いながら働いています。エンジニア転職目指している人は2025年ITエンジニアになって会いましょう!
2025年も最高の年にしましょう!良い年を。