bunty's blog

ググったこととか勉強したことのメモ

島田紳介の自己プロデュース力を読んだ

10年以上前の本だけど、知り合いがおすすめしていたので読んでみた。Amazon では中古でないと売ってなかったけど。 ちょっと前まで転職活動をしていたこともあり、自分をどう見せるかやどうなっていきたいのかを考えることが多くて興味を持った。

ざっくりと言っていることはここららん。

  • ターゲットを明確にする
  • たくさん漫才を見て聞いて真似る
  • 自分の能力と世の中の変化を知る

例え話だったり自分の言葉で話してるから面白いし、すごく納得感がある。

当時のお笑いは老若男女笑わせるのが良いみたいな雰囲気がある中、自分たちと同じ属性の若い男性に受けるネタを作るようにしてたらしい。
劇場に若い女の子が多くなっても、テレビで見ている兄ちゃんたちを笑わせるように意識していたと。
自分たちの本当の客は誰かを理解した上で、そこをブラさないようにするってことがすごい。

漫才を見て聞いて真似るみたいなのは、エンジニアの世界というか他の職種も一緒だなと。
劇場まで行ってダメだけど録音して全部書き起こしたり、何度も練習したりという話があって、最近そこまで本気でできてないとちょっと思った。。

あと、タレント向けの話の中で、1分野につき1箇所を掘り下げるって話が出てきて、これはすごく良い方法だなと思った。
あまり野球に詳しくなくて、有名すぎない選手についてすごく熱く語れると、それだけで野球について詳しい人みたいな印象を持たれる。
みんなが知っている知識を話しても意味ないし、マイナーすぎると伝わらない。

みんながあまり詳しくないブラウザの仕様とか話せる人がいたら、すごく詳しいなこいつ...!って思う。笑
苦手な分野も意識して少し詳しいポイントを作っておくと、同じ知識量でも満遍なく持っているより見せ方を変えられるな。
闇雲にやるってよりも、ここらへんの戦略を持ってやるのが自己プロディースだと思った。

Dockerfile のベストプラクティスを読んだまとめ

有給消化でまとまった時間ができたので、雰囲気でやってた Docker 周りを復習。 ベストプラクティスに書いてある内容をまとめているだけなので、正しい情報はベストプラクティスを読むことをお勧めします。

docs.docker.jp

ここら辺は理解しているつもりだけど、ちょいちょいあやしい。

  • Docker イメージは各コマンドごとにレイヤーになっている
  • コンテナを生成すると、その上に書き込み可能なレイヤーが追加される
  • レイヤーごとにキャッシュが使用されるか判断される

ビルド・キャッシュの活用

そもそも処理内容によって、キャッシュを使用されるかどうかの判定方法が変わってくる。

ADD 命令や COPY 命令では、イメージに含まれるファイルの内容が検査され、個々のファイルについてチェックサムが計算されます

ADD と COPY 以外のコマンドの場合、キャッシュのチェックは、コンテナ内のファイル内容を見ることはなく、それによってキャッシュと一致しているかどうかが決定されるわけでありません。 コマンド文字列そのものが、キャッシュの一致判断に用いられます。

キャッシュが無効になった場合

キャッシュが無効になると、次に続く Dockerfile コマンドは新たなイメージを生成し、以降ではキャッシュを使いません。

たとえば、複数のレイヤが入った構築をする時には、(ビルド・キャッシュを再利用可能にしている場合)頻繁に変更しないものから順番に、より頻繁に変更するものへと並べます。

レイヤーごとに判定は行うものの、その手前で無効になった場合はその後はキャッシュは使用されない。
そのためなるべく変更の少ないものから順番に記載して行って、頻繁に変更するものは最後の方に記載をした方がキャッシュをうまく使うことができる。
すでにある Docker file をベースにどうするかを考えることが多くて、言われてみればそうだけど、全然意識してなかった。

RUN コマンドのキャッシュ・バスティング

上の書き方は非推奨で、同一の RUN コマンドで同時実行させる方が良い。
確かに書く時には下の書き方をするけど、ちゃんと説明ができないなと思ったのでメモ。

# 非推奨
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y curl nginx

# 推奨
RUN apt-get update && apt-get install -y

RUN コマンドを分けると update と install が別のレイヤーになる。
RUN コマンドはコマンド文字列そのものが、キャッシュの一致判断に用いられるため、apt-get update は実行されなくなる。
そのため、curl や nginx はずっと古いものを使い続ける可能性が出てきてしまうので、同じ RUN コマンドで実行させることによって install する際に update も毎回実行させることができる。
そうすると、勝手に新しいバージョンになってしまい問題が発生することもある。その場合には、キャッシュにどんなイメージがあっても指定したバージョンを使用させる方法があり、これをバージョン・ピニングと呼ぶ。

RUN apt-get update && apt-get install -y \
    package-bar \
    package-baz \
    package-foo=1.3.*

ADD と COPY の違い

一方 ADD には特定の機能(ローカルでの tar 展開やリモート URL サポート)があり、これはすぐにわかるものではありません。結局 ADD の最も適切な利用場面は、ローカルの tar ファイルを自動的に展開してイメージに書き込むときです。

COPY は基本的なコピーをする処理だとして、ADD の使い所は記載されていた。

異なるファイルをコピーするときには、一度にすべてをコピーするのではなく、 COPY を使って個別にコピーしてください。

これもキャッシュに関わることで、全部まとめて COPY をする場合、1つでも変更がある場合には全てキャッシュが無効化されるが、個別にコピーしていれば無効化されるのは最低限になると。

Jest で audio をモックする

composition api の勉強がてら色々とコードを書いていて、Jest でテストを書く際にうまく mock できないことがあった。

そもそも Jest 自体詳しくないのでやってることがおかしいかもしれないが、こんな感じのコードを書いてエラーになった。

// sound 自体は new Audio() を実行した HTMLAudioElement
const { sound } = useErrorSound()

const playStub = jest.spyOn(sound, 'play');

// 処理を実行
// Error: Not implemented: HTMLMediaElement.prototype.play
expect(playStub).toHaveBeenCalled()

.mockImplementation() が必要だったと言う話で、これで動くようになった。

// sound 自体は new Audio() を実行した HTMLAudioElement
const { sound } = useErrorSound()

const playStub = jest.spyOn(sound, 'play').mockImplementation();

// 処理を実行
expect(playStub).toHaveBeenCalled()

調べてる途中でこの stack overflow みつけたが、HTMLMediaElement をそのまま spyOn に指定すれば良いらしい。

stackoverflow.com

const playStub = jest
  .spyOn(window.HTMLMediaElement.prototype, 'play')
  .mockImplementation(() => {})

Laravel の Model で配列に cast させる際に文字化けさせないようにする

日本語のエラーメッセージなどを扱う際に、PHPjson_encode を使用する場合には、第二引数に JSON_UNESCAPED_UNICODE を指定する必要があります。

<?php

php > echo json_encode(['あ', 'い']);
["\u3042","\u3044"]
php > echo json_encode(['あ', 'い'], JSON_UNESCAPED_UNICODE);
["あ","い"]

www.php.net

定義済み定数の詳細についてはこちら

www.php.net

Model の $cast で array を指定する場合

日本語をそのまま保存しようとする場合には同様の対応が必要になります。これも内部的には保存時に json_encode を実行していて、取得時に json_decode を実行するようになるからです。

User クラスは適当なのであしからず。

<?php

>>> factory(App\Models\User::class)->create(['some_list' => ['あ', 'い']])
=> App\Models\User {#4716
     some_list: "["\u3042","\u3044"]",
     updated_at: "2021-08-02 14:47:01",
     created_at: "2021-08-02 14:47:01",
     id: 191,
   }

これは Medel 内で asJson を指定して、下記のようにすることで保存できるようになる。

都度定義するのは手間なので、親クラス側で定義しても良いかと思う。

<?php

class User extends Model
{
    // 省略

    protected $casts = [
        'some_list' => 'array',
    ];

    // Model 内にこれを指定
    protected function asJson($value)
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

// 再度 tinker から検証
>>> factory(App\Models\User::class)->create(['some_list' => ['あ', 'い']])
=> App\Models\User {#3785
     some_list: "["", ""]",
     updated_at: "2021-08-02 14:47:38",
     created_at: "2021-08-02 14:47:38",
     id: 192,
   }

Collectionでも同様

ちなみに、collection の toJson も同様です。内部で json_encode を実行しているだけなので引数に JSON_UNESCAPED_UNICODE を指定する必要があります。

<?php

>>> User::first()->toJson()
=> "{"id":1,"name":"\u3042","created_at":"2021-07-21 10:09:53","updated_at":"2021-07-21 10:09:53"}"
>>> User::first()->toJson(JSON_UNESCAPED_UNICODE)
=> "{"id":1,"name":"","created_at":"2021-07-21 10:09:53","updated_at":"2021-07-21 10:09:53"}"

Google フォーム × Slack で daily の振り返りを行う

最近コーチングを受け初めて、コーチと一緒に目標やどう行動していくかについて話をしています。
月に 1 度受けており、weekly の振り返りだけだと改善できる回数が少ないと感じたため、それとは別に毎日簡単な振り返りを行うようにしました。
色々なものを参考にしたのですが、無料でできる良い仕組みができたなと思っています。

なんで Slack と Google これにしたのか

前に trello を使用してやろうと思ったことがあったのですが、結構習慣化されるまでは忘れてしまいがちです。
そのため必ず自分が気がつける仕組みにしたかったので、slack の reminder を使用して、通知を届けるようにしました。
Slack の通知がきてたら必ず見る習慣があったので、そのような人にはあっているかと思います。

リマインドの設定はこんな感じで。

/remind me URL at 21:00 every day

Google フォームにした理由は、記載した内容がすぐにスプレッドシートで確認できることと、質問もすぐに変更できて楽だからというそこまでこだわりがない理由です。

やってみてどうだったか

Slack の通知は思った通り確実に見るので、毎日通知が来てやらないとなと思うようになりました。
ただ、夜に自分宛の連絡が来ていると最初はどきっとします...笑

Google フォームに関していうと、特に問題はないかなという印象です。
何を自分に問いかけたいのか、どうタスクを管理したいのかによるかなと思います。
次の日に試したいことはメモとして物理的に残しているため、特にスプレッドシート を確認することもほとんどありませんでした。

自分の場合は最初に 10 段階評価の質問をして、その後どんなことができたのかできなかったのかを質問するようにしています。

f:id:dhate:20210802095130p:plain

10 段階の評価が低くても、意外とアクションは起こせているという日が何回もありました。
その時に、自分の中でこれはやって当たり前みたいなラインが上がっているという気づきがあったので、10 段階評価の質問は良かったなと思っています。

工夫していること

Google フォームの一番上に、自分が立てた目標を書くようにしています。
そもそも振り返る際に、どこと比較をして今の状況がどうなのかを振り返りやすくすることと、毎日目を通すことで、より目標を意識した行動をできるようにしたいからです。
目標に関してはここら辺も参考にさせてもらいました。

www.youtube.com

www.youtube.com

特にこの 20 文字ゴールは良いなと思っていて、振り返りの際に毎日見るとすぐに覚えられます。
また何度も目を通したり、目標を意識して振り返りを行うと、少しこれは違うかもと思うこともあり、表現の仕方が変わってきたりと変化がありました。

全部無料でできる仕組みなので、もし興味ある方は試してみてください。もっと良い方法とか改善点あれば教えて欲しい。

「アウトプット大全」を読んだ

前に一度気になって読んでなかったので、今更ながら読んでみた。

もともとアクションリーディングを読んでから、読書の前後でメモを行う習慣はあったが、今回これを読んでどうせなら公開した方が良いかなと思って記事にした。

書き方はアクションリーディングに書いてあった4つの項目です。

1. この本を読んだ目的狙い

  • なぜアウトプットするのか?について自分の中でもっと明確に説明できるようになりたかったから
  • これからまとまった時間が取れるので、前のように LT をやったり技術ブログを書き始めたいと思い、そのモチベを上げるため
  • 今までとは別の方法でもっと良いやり方があるのでは?という期待

2. 読んで良かったこと、感じたこと

  • 全体的に目から鱗みたいなことが書いてあるというよりは、前にどこかで聞いたことあることや、なんとなくそうだよねって思っていたことをちゃんと言語化してくれているという印象
    • さーっと読み進めて 1 時間かからないくらいで全部読んだ
    • アウトプットする目的が読む前後でより自分の学習のためという認識が強くなった
      • 今まではやっておくと評価されやすいからとか外向きの考え方をしていたが、そもそも評価されようがされまいが、自分のためになるんだぞという感じ
  • インプットとアウトプットの黄金比は 3:7
    • これは逆になっていると感じたのでアウトプットを増やす必要あり
  • 今日やることだけを考えるってところをみてこれができてないと思った
    • まずはやってみる
    • いきなり 100 点を目指さない、ここら辺はわかっているけど、余計なことを考え過ぎてしまう傾向がある
    • やることリストを変更すれば改善できそうな気がした
  • 話すこともアウトプットの一種で、どんな言葉を使うのか意識しないといけない
    • 自信のなさが言葉にも現れている
    • 結構口が悪くなる時があるので、細かい表現やポジティブな言葉を使う
  • 何をやってもアウトプットできるという前提で物事を考えるとできそう

3. この本を読んで、自分は今から何をするか

  • 本 (技術書とかビジネス書) を読んだ時は、ブログに読書用のラベルを用意してまとめる
    • 内容をようやくするのは無駄なので、今回の形式で OK
  • 週に 2 つはブログを書く
  • 英語で書いてた日記を見開き 1 ページを 1 日文とする
    • 大きくないノートなので、これくらいの量にした方が良い
  • ポリグロッツ読んだ後にコメント入れる
    • 前からあったのは気がついててスルーしてたけど、この本を読んでからここも良いアウトプットの場所だなと気がついた
  • タスク一覧っぽいのがカオスになってるので、どこまでが今日中にやるものかわかるように形式を変更する

4. 3ヶ月後には何をするか、どうなっていたいか

  • チャレンジシートをブログに書くことが習慣化されている
  • ブログ、ポリグロッツのコメント、見開き 1 ページの日記が継続されている
  • 今までやってこなかったアウトプットの方法を見つける

スプレッドシートの情報を web に公開して、一時的なストレージとして使用する

DB に保存するほどじゃないけど、一時的に保存したいデータがありました。そのデータを使用して処理を行う必要があったのですが、その際にスプレッドシートをそのまま web に公開するのが便利だったのでメモです。

support.google.com

やり方は記載されているとおりで、これだけです。

上部の [ファイル] 次に [ウェブに公開] をクリックします。

csv にするのかどうかなど形式も選べます。
公開すると URL が表示されていると思うので、それに対してリクエストを送ると、結果が返ってきます。

Gas で取得したデータやちょっとしたデータをスプレッドシートに保存して、それをそのまま web に公開しておくと便利です。
以前書いた記事ですが、スプレッドシートのデータを curl で取得して、標準入力に渡して Laravel のコマンドを実行するなど組み合わせます。

$ curl "webに公開した際に表示されるURL" | php artisan sample:test

dhate.hatenablog.com

注意点

外部に公開することになるので、個人情報等の扱いには気をつけてください。 また、組織に所属しているアカウントの場合には、「公開するコンテンツと設定」の箇所から組織に所属しているユーザーにのみ公開する設定ができるのでやっておくと良いかと思います。