yashiganiの英傑になるまで死ねない日記

週末はマスターバイクでハイラルを走り回ります

狩猟日記 #1

同僚が続々と購入するのに釣られてモンスターハンターライズを買った。モンハンは初めてなので何もわからない。大学生の時に同期が夢中で遊んでたイメージしかない。

とりあえず何もわからないながら武器をデフォルトの太刀から変えてみる。槍はかっこいいのでとりあえずランスを選んだ。ガンランスというやつの方がカッコ良さそうだけどなんか難しそうなので避ける。チュートリアルのクエストを終え、最初のクエストを受注した。イメージではモンスターを狩るわけだけど、予想に反してキノコを集めろというクエストだった。

気を取り直してクエストを開始すると、第一モンスターを発見。いざ、と攻撃をしかけてみるも、当たらねぇ…全く攻撃が当たらねぇ…

ランスすげえ重いし、攻撃が直線的なのですぐ回り込まれる…あとXとAしか攻撃のバリエーションも無いしどないして戦うねんとボヤきながら、何度か繰り返すと慣れてきてほどほどに当たるようにはなった。しかし、キノコは全然見つからない。なんやこれ、と思いながら捜索を続ける。いつの間にかスタミナの最大値が下がってて全然行動できねえ、そしてとにかくキノコが見つからねえと戸惑いつつ45分かけてキノコを探し当てた。先が思いやられる…

これはなんかおかしい、最新ゲームがそんな不親切にできているはずはないので、なにかを見落としてるのではないかと里を彷徨いてみると訓練場みたいなところを見つけた。そこでZRでガードができることや、必殺技みたいなのがあることを学べた。けど、ランスはたぶん上級者向けやしアカンと思って他の武器を試すことにする。狩猟笛というのが目に入り、笛ってなんやねん武器ちゃうやんけとか思いながら試してみる。狩猟笛というのはどデカい鈍器をぶんまわすスタイルだった。ランスに比べると攻撃が当たりやすいし、何故かバフがかかる。ガードはできないけど、次に押したらいいボタンも表示されるのでこりゃいいやと思って笛を使うことにした。チュートリアルのクエストが他にあったことにも気がついて、モンスターに乗る方法と罠にかけて捕まえる方法を学んだ。めっちゃめんどくさいけどまあなんとかなるだろう。

なんかいけそうな気がしてきたので次のクエストへ。

 

モンスターハンター ライズ|オンラインコード版

モンスターハンター ライズ|オンラインコード版

  • 発売日: 2021/03/25
  • メディア: Software Download
 

 

 

シンクが詰まると日常生活が困難になる

この間、シンクが詰まったんですよ。シンクというのはいわゆる台所の流しのことです。一般にシンクが詰まると日常生活が困難になると言われています。

今の家に住み始めて5年程度、振り返るとシンクの排水口より向こう側を掃除したことがありません。ですから詰まっても仕方ないものなのでしょう。知らんけど。トイレの詰まりにはスッポンと相場は決まっています。ちなみに、筆者にはトイレが詰まった時にスッポンで事なきを得るという体験があり、スッポンに対する異様な信頼があります。この時は間を開けずに続けてトイレが詰まるということがありましたが、スッポンを手にする筆者には全能感がありました。そんなスッポンですが、引越に際して使用済みを運ぶのが憚られ廃棄しました。

閑話休題。シンクの詰まりに話を戻します。

兎にも角にもスッポンがあれば解決しそうなものですが、生憎我が家にはシンク用のスッポンがありません。仕方ないのでインターネットで少し調べてみると、シンクの排水口は径が小さいからかペットボトルなどで代用できるようです。ペットボトルならば手元にあるので早速試してみると、ほとんど流れないという状態から少し流れにくいかな?くらいの状態まで改善できました。所詮ペットボトルなのでパワーが足りなかったのでしょう。スッポンさえあれば…ひとまずは日常生活困難な状態からは脱することができ、胸を撫で下ろすことができました。

しかし、依然として流れがスムーズとは言えないため、日常生活困難と背中合わせの生活を送ること強いられています。そこで、根本解決できないか自分のインターネット力を駆使して調べてみると、パイプ洗浄系の洗剤に行き当たりました。パイプユニッシュみたいなやつを耳にしたことがあると思います。これらの洗剤はパイプの詰まり対策として有効なようですが、シンクの金属部分やパイプを痛めることがあるそうです。設備を痛めるのはできれば避けたいと思い、もう少し調査してみるとリクシルのページに辿り着きました。

www.lixil.co.jp

なんと、シンク下のパイプには点検用の穴があり、そこを使ってパイプ内部の掃除ができるそうです。これだ!と早速シンクの下を覗いてみると、あるではないですか、点検用の穴が。そこで早速この穴を使って清掃することにしました。注意点は先ほどのページにもあるように、臭気止めの水が溜まっているので開けるときにバケツなどで受けるようにしておくことくらいです。コルクくらいのさぞかしすごい塊が取れるのだろうと思っていたのですが、実際には期待したほどのものは取れませんでした。ですが、シンクの流れは格段にスムーズになり日常生活困難の恐れからは解放されました。めでたしめでたし。みなさまにおかれましてもシンク下を覗き、点検用の穴があるか確認をしておくことおすすめします。もしなければいますぐホームセンターでラバーカップ*1をお求めください。以上、現場のキッチンよりお届けしました。

まとめ

  • シンクが詰まると日常生活が困難になる
  • スッポンは最強だが、非常時はペットボトルなどで代用できる
  • シンク下のパイプには点検用の穴がついていることがある

*1:スッポンは通称でラバーカップというのが正しいそうです

Cloud FunctionsのNode.jsランタイムを使うときに毎回設定していること

Cloud Function使ってますか?簡単なサービスをシュッと作って公開するにはとても便利ですよね。筆者もよく使っています。今やGCPの中では一番手に馴染んだサービスのひとつです。 最近Cloud Functionsを使っていくつかサービスを作っていて、最初にすることが決まってきたのでご紹介します。

TypeScriptの導入

初手はTypeScriptの導入です。みなさんはTSを導入するときどうしていますか?入れるだけなら簡単なんですが、ESLintだとかPrettierだとか考え始めるとゾッとしますよね。これから楽しくプログラミングを始めるのにゾッとはしたくないので、で頭をカラッポにしてgtsを使います。gtsというのはgoogleが作っているいい感じにTypeScriptを使えるやつで、入れておくだけでそれはそれはいい感じになります。詳しくはこのエントリーを見てくれ。npx gts initしたらだいたいいい感じになりますが、ちょっとだけいじります。

テストを書きたいのでgtsが作ってくれたtsconfig.jsonexcludeを追加します。

{
  "extends": "./node_modules/gts/tsconfig-google.json",
  "compilerOptions": {
    "rootDir": ".",
    "outDir": "build"
  },
  "include": [
    "src/**/*.ts",
    "test/**/*.ts"
  ],
  "exclude": [
    "src/**/*.test.ts",
    "test/**/*.test.ts"
  ],
}

セミコロンは死んでも書きたくないので.prettierrc.jsにはsemi: falseを追加します。

module.exports = {
  ...require('gts/.prettierrc.json'),
  semi: false,
};

これでTypeScriptの準備はできました。npm scriptsでやたらとコンパイルしたりlintしたりされるけど別に害はないのでこの段階では放っておきます。時間かかってうざいなと思ったらチューニングするか消すかしましょう。 ちなみに、yarnでmonorepoしている場合にはtsconfigやESLint、Prettierの設定ファイルからgtsの設定ファイルをうまく読み込めません。親packageのnode_modulesにgtsがインストールされてしまうからなんですが、このissueで紹介されているようにworkspaceの設定にnohoistを指定して子packageにインストールするように設定すると良いです。

github.com

エントリーポイント

今回は試しにCloud Functionsで簡単なechoサーバーを作ってみます。index.tsの他にecho.tsを作ってこんな感じにしました。

// echo.ts
import {HttpFunction} from '@google-cloud/functions-framework/build/src/functions'

type Logger = Console
export const echo: (logger?: Logger) => HttpFunction = logger => {
  return (req, res) => {
    logger?.info(req.query)
    res.status(200)
    res.send(`Hello, ${req.query.user ?? 'Cloud Functions'}`)
  }
}

// index.ts
import {echo as _echo} from './echo'

export const hello = _echo(console)

関数の処理をindex.tsにベタ書きしてもいいんですが、関数の本体とCloud Functionsのエントリーポイントを分けるようにしています。Cloud FunctionsのNode.jsランタイムでは、複数の呼び出しで同じインスタンスが使いまわされることがあります。その際、グローバルスコープの変数は実行ごとに評価されませんのでキャッシュやもろもろのクライアントの初期化などに使えます。関数本体をエントリーポイントから分離しておくと、テストを気にせずグローバルスコープを使えるようになるので便利だからです。ここでは、type Logger = ConsoleとしてconsoleをDIしているので、テストを気にせずログの書き出しができますね。 それと、関数本体の型にHttpFunctionを使っているのもポイントです。これは同僚のid:pokutunaに教わったんですが、@google-cloud/functions-frameworkにはhttpトリガーやpubsubトリガーの関数の型が定義されているのでありがたく使わせてもらいましょう。

github.com

ローカル実行

JavaScriptなら簡単なんですが、TypeScriptではちょっと面倒です。公式のドキュメントで良い例が紹介されているので真似してnpm scriptsにstartwatchを設定します。

"scripts": {
  "start": "functions-framework --target=echo --source=build/src/ --port=8000",
  "watch": "concurrently \"tsc -w\" \"nodemon --watch ./build/ --exec yarn start\""
},

ドキュメントではnpmですが、yarnを使いたいのでyarnに書き換えます。デプロイするのが簡単なので未リリースのサービスならデプロイしてしまっても良いんですが、ローカルで動かせるようにしておくと何かと便利なので設定しておくと吉です。デプロイは数分くらいかかるし。他のGCPサービスと連携したければ、開発用のSAを用意してGOOGLE_APPLICATION_CREDENTIALS=... yarn watchみたいな感じで実行してください。いつも通りですね。

テスト

もちろんテストは書きたいですよね。なるべくCloud Functionsの環境を再現してユニットテストを書くと実際のリクエストに近くなります。そこで、ここではsupertestを使ってテストしたいと思います。

import {
  getServer,
  SignatureType,
} from '@google-cloud/functions-framework/build/src/invoker'
import supertest from 'supertest'
import {echo} from './echo'

describe('cloud function', () => {
  // テストなのでechoにloggerは差し込まない
  const app = getServer(echo(), SignatureType.HTTP)

  it('should return 200', async done => {
    supertest(app)
      .get('/echo')
      .expect(200)
      .expect('Hello, Cloud Functions', done)

    supertest(app)
      .post('/echo')
      .send({user: 'John'})
      .expect(200)
      .expect('Hello, John', done)
  })
})

実は、Cloud Functionsのexpressはなんか色々良きにはからってくれます。その挙動についてはここに記載されていますが、詳細には書かれていません。そこで、functions-frameworkの実装を見てみましょう。こんな感じbodyParserが差し込まれていたり、オリジナルのリクエストボディがrequest.rawBodyに退避されていることがわかりますね。この辺りのCloud Functionsの挙動はよくわかんないなあと思っていたんですが、同僚のid:pokutunaがfunctions-frameworkの実装を見るといいよと教えてくれました。そりゃそうだろという感じなんですが、その手があったか!って思いますよね。ちょうど今眺めていたgetServerを使えば簡単にsupertestでテストが書けます。

また、ユニットテストではログが表示されても邪魔なだけなのでloggerはDIしないでおきます。こんな感じでDIするポイントを作っておくと、後で依存を増やしたくなった時に楽ができていいですね。例えばGoogle Cloud Storageと連携した関数を作りたい場合、同様にGCSServiceみたいなインターフェースを書いてDIすればよろしい。Cloud Functionsで作りたい程度の関数の規模なら素朴なDIで事足ります。ユニットテストではみんな大好きjest.fn()を使ってモックしましょう。よかったですね。

Enjoy Cloud Functions!

そんなこんなで雛形ができたので、必要に応じてecho.tsを改造していけばいい感じに関数が作れます。あとは楽しくプログラミングするだけです。めでたしめでたし。

まとめ

Cloud Functionsでサービスを作るときに毎回やってることを紹介しました。Cloud Functionsを使うとシュッと作れていいんですが、ローカル開発の環境をきちんと整えようとかユニットテストをちゃんと書こうとか思うとちょっと考えることが多いので普段からよくやるやつをまとめてみました。ぼくのかんがえたさいきょうのシリーズなんですが、少しばかりでも皆様のお役に立つことがあると幸いです。

ここまでに紹介した知見をまとめたリポジトリを公開しました。テンプレートリポジトリというやつにしてみたので、これを使ったらすぐに楽しくプログラミングできると思います。もしよければ使ってみて下さい。

github.com

PR

筆者の所属する株式会社はてなでは、現在Webアプリケーションエンジニアを絶賛募集しています。

hatenacorp.jp

もし興味があれば応募してみてください。一緒にGCPを使ったプロダクトを開発しましょう。

また、恒例のはてなインターンシップは今年も元気に開催されます。

developer.hatenastaff.com

応募お待ちしています。一緒に東京オリンピックより熱い夏を過ごしましょう。

新しい音楽との出会い

いつの間にか良く聴くようになっている音楽ってあると思います。自分が最近良く聴くようになった音楽とその出会いについてふりかえってみるとおもしろかったのでブログに残しておくことにしました。

ラジオで発見その1

滋賀県のローカルラジオにe-radioというのがあって、Hot stuffという月替わりであるアーティストのある曲を取り上げる企画があります。 ちょうど1年前の今頃、取り上げられていたのがLucky Kilimanjaroの「初恋」でした。

ちょっと聴いた瞬間にこれはいいぞとなってShazamしてそこから2019年はずっと聴いてました。“世界中の毎日をおどらせる”をテーマにしているだけあってどれも踊りたくなるような曲ばかりで朝とかとにかくパッと元気を出したいときとかによく聴いています。

特にオススメなのは「HOUSE」。

HOUSEはインドア志向なことを少し居直ったような曲なんですが、いつの間にかひきこもって過ごすのがスタンダードな時代になってしまったので今聴くと少しニュアンスが変わるかも。ちなみに、この曲は桑田佳祐やさしい夜遊びで2019年のベストシングルTOP10にも選出されています。

2019年の年末くらいは「これは売れちゃうな〜、スゲェのをdigりあてちまったな〜」と思ってたけど、意外とブレイクしている感がなくてさみしいので応援よろしくお願いします。

Lucky Kilimanjaro on Spotify

ラジオで発見その2

CreepyNutsのオールナイトニッポン0の日本語ラップ紹介コーナーで紹介されていたのが神戸の「夫婦」です。

「夫婦」は彼の夫婦生活をそのまま歌った曲です。アイラビューのひとことでは片付けられない複雑な感情が綴られていて、なんか自分ごとのように感じられて胸にひっかかる不思議な曲です。 夫婦が気に入ったら是非この曲が収録されているアルバムの「エール」を通して聴いてみて欲しい。

open.spotify.com

コーナーでR-指定が「自分の生き様をそのまま歌っている」と評していたんですが、まさにという感じの曲が続きます。古くからの友人がひとり増えたような、そんな不思議な気持ちになれるアルバムです。聴いた後、ちょっと兵庫訛りの関西弁がうつるのもおもしろくてオススメ。 よければ最近出たアルバムも聴いてね。

open.spotify.com

こっちは「神門、子ども産まれたん?おめでとう!」って気持ちになれます。

神門 on Spotify

ライブ配信で発見

THE FIRST TAKEというYouTubeチャンネルがあって、それの企画でTHE FIRST TAKE FESというのをやってたんです。OKAMOTO'S目当てで視聴していたら最初に出てきたのがALIでした。

まったく期待していなかったのに、いきなりめちゃめちゃかっこいいバンドが現れてびっくり仰天してしまった。フェスに行くとこういう体験ができるのかなあと思う。行ったことないから知らんけど、行ったこともないのに行った気になれていてお得ですね。いわゆるミクスチャーバンドでFunk/Soul/Jazzっぽい音楽にHipHopを掛け合わせているという感じで、なんでもまぜりゃあいいってもんじゃないぜって思うんですが、実際やってみたらめっちゃハマっていてブチ上がります。 この配信から気に入ってしまってよく聴いてました。どの曲もMVもカッコいいです。Vimmerが喜びそうな曲もあります。

YouTubeにあるやつ全部かっこいいので全部聴いてくれ。 最近は呪術廻戦のアニメ版のEDを担当してます。ちなみに、呪術廻戦はあの週刊少年ジャンプで連載されている大人気作品です。

これはアニメのノンクレ版ED。

本家はフル尺で聴けるのでこっちも見てね。 https://www.youtube.com/watch?v=KnakQRoQRzk

こないだ急にライブ配信やっててたまたま観れたんですがこれもめっちゃ良かったので紹介したかったけど、アーカイブの公開期間が終わってた…

11/25には新譜が出るらしいので楽しみですね。

ALI on Spotify


いかがでしたか?ここ最近の良かった新しい音楽との出会いを紹介しました。皆さんのエピソードも聞かせてくださいね。もし良ければはてなスター&読者登録をお願いします

引っこ抜き日記 #1

探索4日目。ピクミンの扱いにも慣れ、手持ちのピクミンが100を超えてオニヨンに納めないといけないものもでてきた。

小川の向こうの瓦礫で橋を修復するため、両岸に分かれて作業する。この程度はお手の物だと赤ピクミンに修復を任せつつ岩ピクミンを連れてガラスの壁を破壊しに行く。「ピーッ!!!」あれ?なんか変じゃない?と思いつつ画面の端を見ると小川の向こうで待つはずのブリトニーがこちらに一目散に走り寄ってくる。もちろんピクミンはブリトニーを追いかけ、次々と小川へダイブする。何が起きたのか全く理解できず、「あっ、あぁ〜〜〜」と狼狽えるしかできない私、次々と昇天するピクミン、こちらへ駆け寄ろうとするブリトニー。どうやら全員集合の命令を発してしまったらしい。一瞬にして65匹のピクミンを失ってしまった。先が思いやられる…

体験版はここまでだったので、この続きは月末に。乞うご期待。