株式会社はてなに入社しました
4年目ですね。 さすがにそろそろ知らないことがあると恥ずかしい時期なので、だいたい手の中にはあると思います。 前提整える必要が無い=加速できるので、出力にご期待ください。
今年もよろしくお願いします。
株式会社はてなに入社しました
4年目ですね。 さすがにそろそろ知らないことがあると恥ずかしい時期なので、だいたい手の中にはあると思います。 前提整える必要が無い=加速できるので、出力にご期待ください。
今年もよろしくお願いします。
エゴサが趣味なので、社内の Slack のキーワード通知をめちゃくちゃ便利に使っている。
何か見ておくと良いことがありそうなものを片っ端から通知するようにしているんだけど、100 個が上限なの知ってた?
僕はこんなキーワードを入れています。適当に分類しながら見てみよう。
onk
,o/nk
,on/k
,おんく
,大仲
,onaka
,眼科
自分の名前やハンドルネームを入れておくと、どこかで自分が呼ばれたときに気づけるようになる。
定時外だと親切でキーワード通知避けのために /
を入れて発言する人もいるので、それも通知させるためにこういうキーワードになっています。戸籍ネームはほっっとんど呼ばれることは無いんだけど、念のため。
「眼科」は中心性漿液性網脈絡膜症になってるっぽいけど放置してたら T シャツが作られたので、戒めのためにずっと通知しています。
suzuri.jp
自分が所属しているチーム名だったり、プロダクトのコードネームだったり、サブ会 名だったり。
他のチームから言及されたときにすぐに気づける用。
小説
,ノベル
,カクヨム
,kakuyomu
,魔法
,maho
,らんど
,ランド
カクヨムや魔法のiらんどを運営しているチームに居るので、サービスに関連しそうな話題が出たときに気づけるように。
CRITICAL
,障害
,不具合
,負荷
,脆弱性
,重い
,重く
,Incident
,申し送り
障害っぽかったら通知が来るようにしてある。
「申し送り」は障害対応後とかに使われることが多いワードですね。「重い」は月初に勤怠管理システムに対しての発言をよく見る。
infra
,インフラ
,SRE
,SLA
,SLO
,SLI
,監視
,PWG
インフラっぽい話題が出たら通知が来るようにしてある。
「PWG」は Performance Working Group の略で、パフォーマンス等が悪くなっていないかを定期的に (主に月次開催) チェックする会です。サービスのレスポンス速度やエラー率、発報されたアラートや障害などを3ヶ月ぐらいの目線で確認し、キャパシティプランニングを行ったり、監視設定や根本対策に思いを馳せたりします。
はてなにおける日々の仕事の中にあらわれるMackerelの活用 - Mackerel ブログ #mackerelio でも紹介されていますね。当時とは組織体制はかなり変わっていますが、目的はあまり変わっていません。
(グループウェアのドメイン)
,議事録
bot の発言ではなく、人間が URL を貼ったなら、何かしら人に伝えたい意図が含まれた面白い記事なんだろうってところから。実際、キャッチアップしておくと便利な記事がよく流れてきます。
「議事録」は割と興味本意かな。社内のミーティングでは「議事録」ってワードはあまり出ないので、他社さんとの会話が見えることが多い。
cost
,コスト
,予実
,予算
,実績
,費用
,数字
,稟議
,申請
,release
,リリース
,キックオフ
はい。
他部署のものでも数字に敏感になっておくと色んな場面で役に立つし、キックオフやリリース時点で話題をキャッチできていると、これも会話の種になる。「デプロイ」はさすがに流速がヤバかったのでキーワードから外した。
全社
,ミッション
,ビジョン
,バリュー
,MVV
,目標
,評価
,グレード
,昇格
,昇給
,1on1
,面接
,面談
,異動
,採用
,新卒
,インターン
,CTO
,チーフ
,シニア
,リーダー
,メンター
,メンティー
,マネージャ
,方針
,オンボーディング
1on1 した感想とか、目標設定や評価に対しての感想とかを拾っておきたい。
ふり返り
,振り返り
,振りかえり
,ふりかえり
,KPT
,YWT
ふりかえりだけでも見ておくとチームの現状が分かるので、覗きに行ってます。
MySQL
,RDS
,Aurora
,redis
,Elasticache
,Elasticsearch
,ruby
,rb
,rails
,レイルズ
,レールズ
,アジャイル
,scrum
,スクラム
この辺のワードが出たらいっちょかみしたい技術ワード。
かろうじてなんとかなってるんじゃないかな……。
集中したいときはガン無視しているので、呼ばれても返事してないし、何ならときどきミーティングすっぽかしてる orz
こういう ENV
で切り替えるやつとか、eval_gemfile
を使うやつとか。
https://github.com/discourse/discourse/blob/v2.6.2/Gemfile#L9-L16
def rails_master? ENV["RAILS_MASTER"] == '1' end if rails_master? gem 'arel', git: 'https://github.com/rails/arel.git' gem 'rails', git: 'https://github.com/rails/rails.git' else # NOTE: Until rubygems gives us optional dependencies we are stuck with this needing to be explicit # this allows us to include the bits of rails we use without pieces we do not. # # To issue a rails update bump the version number here gem 'actionmailer', '6.0.3.3' gem 'actionpack', '6.0.3.3' gem 'actionview', '6.0.3.3' gem 'activemodel', '6.0.3.3' gem 'activerecord', '6.0.3.3' gem 'activesupport', '6.0.3.3' gem 'railties', '6.0.3.3' gem 'sprockets-rails' end
Gemfile.lock に差分が出るので、アプリケーション (Gemfile.lock をリポジトリに含める) の場合はイマイチだと思う。
ライブラリの場合は Gemfile.lock は含めないことの方が多いので、大いにやると良さそう。マトリックステストも ENV を置くだけなので簡単。
eval_gemfile
と言えば dry-rb や thredded 等で、開発用の gem を別ファイルに追い出している文化も面白いよね。(余談です)
これも余談だけど、一時期、Gemfile.local を読み込ませるために
eval_gemfile(__FILE__ + ".local") if File.exist?(__FILE__ + ".local")
と書くのが流行っていた時期もあって、これも Gemfile.lock に差分が出るので僕は苦手だったなって記憶が蘇ってきた。
各環境用の Gemfile を用意して、 BUNDLE_GEMFILE
環境変数を設定する。これも gem でよく見る。
# gemfiles/rails_5_2.gemfile source "https://rubygems.org" gem "rails", "~> 5.2.0" gemspec path: '../'
# .github/workflows/main.yml strategy: matrix: gemfile: - rails_5_2 - rails_6_0 - rails_6_1 env: BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
gem は基本的に gemspec に依存が書かれていて、一部の指定が厳しい部分だけ *.gemfile で上書きすれば良いので、この形が自然に取れる。
アプリケーションの場合は eval_gemfile
を利用して、共通部分は Gemfile.common とか Gemfile.global とかに抽出して同じことをやる。
3 ファイル (current 用, next 用, common) 必要なことと、common に何を追い出すかを考えるのがめんどくさいことがイマイチ。
RailsConf 2018 で発表されていた方法。
僕は Getting Ready for Rails 6.0: How to Dual Boot - FastRuby.io | Rails Upgrade Service に書いてあるので知った。
Gemfile に next?
を定義して、symlink 経由で呼ばれたかどうかで切り替える。
def next? File.basename(__FILE__) == "Gemfile.next" end if next? gem 'rails', git: 'https://github.com/rails/rails.git', branch: 'main' else gem 'rails', '~> 6.1.0' end
という、上であげた 2 つの方法のデメリットをそれぞれ潰すことができている。
id:takkan_m が教えてくれた。
これ知ってます?https://t.co/ecxlsPWkKh
— えむ。 (@takkanm) February 28, 2021
https://github.com/Shopify/bootboot
symlink を使わず、Bundler の plugin として実装したもの。
if ENV['DEPENDENCIES_NEXT'] ... end
の内容が Gemfile_next.lock に書き出される。
例えば日記を書くときに、午前 2 時に書いたものは前日分としたいことがある。またユーザがメチャクチャ多いサービスでは、0:00 を回ったら翌日のログインボーナスを配る、としていると、まだユーザが多い時間にサーバの処理が要求されて大変なので、28:00 を日付変更線にしたいことがある。
こういうときには
module AppTime def self.beginning_of_day(time) t = time.change(hour: 4) t <= time ? t : t - 1.day end end
を作って、
AppTime.beginning_of_day(Time.current)
を使うと「アプリ内の日付変更線では何日なのか」が取れる。
# 02:00 は前日扱い time = Time.zone.parse("2021-01-31 02:00") AppTime.beginning_of_day(time) # => Sat, 30 Jan 2021 04:00:00.000000000 JST +09:00
僕は Date 苦手なので何でも Time で処理したい派だけど、こういうメソッドがあっても便利だと思う。
module AppTime def self.today to_date(Time.current) end def self.to_date(time) beginning_of_day(time).to_date end end
# 02:00 は前日扱い time = Time.zone.parse("2021-01-31 02:00") AppTime.to_date(time) => Sat, 30 Jan 2021
また、「今日日記を書いたか?」や「今日ログインボーナスを受け取ったか?」を以下のようなメソッドを用意することで表現できる。
module AppTime # AppTime.all_day(Time.current) は以下の Range を返す # => Sun, 31 Jan 2021 04:00:00.000000000 JST +09:00..Mon, 01 Feb 2021 03:59:59.999999999 JST +09:00 def self.all_day(time) beginning_of_day(time)..end_of_day(time) end def self.end_of_day(time) (beginning_of_day(time) + 1.day - 1.second).change(usec: Rational(999999999, 1000)) end end
class User < ApplicationRecord has_many :diaries end class Diary < ApplicationRecord belongs_to :user scope :of_day, ->(time) { where(published_at: AppTime.all_day(time)) } end
user.diaries.of_day(Time.current).exists? # Dairy Exists? (2.2ms) SELECT 1 AS one FROM `diaries` WHERE `diaries`.`user_id` = 1 AND `diaries`.`published_at` BETWEEN '2021-01-30 19:00:00' AND '2021-01-31 18:59:59' LIMIT 1
肝は「DB には UTC で保存して、アプリ内では JST で扱う、というのは変えない」「日付変更線に沿った Time や Range を返すモジュールを用意することで、保存時に 04:00 を入れるし、検索時には 04:00〜04:00 (UTC では 19:00〜19:00) で検索する」です。
アプリケーション側で変換するのだと限界もあって、日記だと Habit Tracker っぽい (いわゆる「草」) 見せ方をしたいし、その実装に groupdate gem を使うことが多いと思うけど、そういうのはアプリ内日付変更線に基づいた日付カラムを DB に入れてしまうと楽だと思います。
ここから始めてリファクタリングして育てていきましょう、です。 この記事ではモジュールにしたけど、クラスにしてアプリ内日付変更線を持ったインスタンスを作っていくこともあるだろう。
all_day
難しいActiveSupport の実装に寄せて end_of_day
や all_day
で 03:59:59.999999999
を返して書いたけど、時間を区切るというのは半開区間でないと困るんですよ。
↑↑でも
`diaries`.`published_at` BETWEEN '2021-01-30 19:00:00' AND '2021-01-31 18:59:59'
が SQL として見えてるけど、BETWEEN
では表現したくなくて、
WHERE '2021-01-30 19:00:00' <= published_at AND published_at < '2021-01-31 19:00:00'
であって欲しい。
時間は連続なので、切断点はどちらかのみに所属しなければならない=閉区間だと表現できないのだ。詳しくはデデキントカットを見てくれ。何故かニコニコ大百科が詳しい。
じゃあどう実装すれば良いかで言うと、終端を含まない ...
で作られた Range を渡すといい感じになります。
module AppTime def self.all_day(time) beginning_of_day(time)...beginning_of_day(time + 1.day) end end
user.diaries.of_day(Time.current).exists? # Diary Exists? (2.0ms) SELECT 1 AS one FROM `diaries` WHERE `diaries`.`user_id` = 1 AND `diaries`.`published_at` >= '2021-01-30 19:00:00' AND `diaries`.`published_at` < '2021-01-31 19:00:00' LIMIT 1
各部屋のグッズはこんなモン。
以上で
とそれぞれを操作するようになった。
特に照明とエアコンは、スマホ or 声で操作できない状態には絶対に戻りたくないぐらい便利で良い。
ルーティンで操作するのもピタゴラスイッチを眺めているかのような気持ち良さがある。発話の必要すらなく全自動になるともっと便利なんだが、例えばベッドに感圧センサー仕込むとか、スマートウォッチの睡眠をトリガーにするとかは独り暮らしじゃないと上手くいかない。。2 人以上の生活空間では人感センサーは無価値だと思う。
Nature Remo 3 には温度、湿度、人感、照度センサーが付いているので、せっかくだし有効活用したいよね。
ということで雑に Mackerel に投げている。Lambda を EventBridge でスケジュール実行。
値を取得しだしたら CO2 濃度も測りたくなったので Netatmo WeatherStation も購入した。
CO2 濃度も、気圧変化も、アラートだけは投げてるんだけど自分の体は鈍感なのでそもそも影響が分かっていないが、測ること自体が目的なのでそれでいいのだ。GARMIN の body battery をライフログとして投げているので、そのうち突き合わせて眺めてみよう。
去年 に引き続き、今年買ったものコーナー。
はてなに入社して明らかに変わったのが「日常をブログに残すようになった」ことで、その中でも「今年買ってよかったもの」はついタグを追ってしまうし追ったら買っちゃうし経済がどんどん回ってしまう。よくない。
だいたい買った順です。
またKoteraさんにデバイス教えてもらった。
— threetreeslight (@threetreeslight) January 6, 2020
Deep Sleepをboostできて睡眠品質向上できるらしい 🤔
毎日のtotal sleep timeが5.5hなので、めっちゃ期待したい。
SmartSleep ディープスリープ ヘッドバンド https://t.co/eNtkK2N6N6
ちょっと高いけど、だめだったら返品できるし買ってみるか。 pic.twitter.com/6pw4zusn54
IoT ミラーボール??? -> https://t.co/b9okZd1Y8y
— iz (@innocent_zero) September 8, 2020
といった感じで現在の机はこんな。
机周りが一通り揃った (モニタ、椅子、キーボード、マウス) ので、来年は IYH することは減るはず、きっと、多分。
って去年言ったけど、モニタも椅子もキーボードもマウスも買ったね。そしてスマートスピーカーを起点にリモコンが全部発話で動かせるように変わった一年だった。
GitHub で新規リポジトリを作ろうとすると、リポジトリ名をサジェストされる。
docker contianer の命名規則を思い出した。
せっかくなのでどんな名前が出てくるのか集めてみよう。HTML に含まれているので、スクレイピングの出番。
while :; do curl -H 'Cookie: user_session=xxxx' 'https://github.com/new' | ggrep -oP '(?<=<strong class="reponame-suggestion js-reponame-suggestion">).+(?=</strong>)' sleep 10 done
grep -oP
はワンライナーの頻出テクニック *1。Mac の grep は -P
に対応していないので brew install grep
して使う。
これを動かすと以下のような名前が取れる。
didactic-engine expert-potato solid-giggle furry-succotash supreme-doodle psychic-guacamole crispy-doodle probable-fiesta sturdy-journey stunning-octo-journey glowing-journey fuzzy-barnacle laughing-octo-funicular upgraded-parakeet jubilant-engine psychic-goggles sturdy-octo-couscous crispy-couscous psychic-potato congenial-sniffle
xxx(-yyy)*-zzz
で構成されそう。
xxx の部分は super
, upgraded
, solid
, shiny
, fuzzy
といった形容詞が並ぶ。
(-yyy)* の部分はほとんど octo
。時々 palm
, rotary
, computing
, duper
, free
。稀に super-octo-palm-tree
のように 2 個出てくる。
zzz の部分は tree
, phone
, umbrella
, machine
, enigma
等、名詞っぽい。 特に何かに関連する名詞かどうかは分かんなかった。
repo 名のサジェストして何か意味あるのかな (repo 名に悩んでサジェストに頼る人どれぐらい存在するの?) って思ったけど 100 repo ぐらいあるわ。 https://t.co/0PnC5W4syy
— Takafumi ONAKA (@onk) December 28, 2020
意外と使われている。
ところで何のためにリポジトリを作ろうと思ってたんだっけ……。
300 件ほど集めたのでもうちょっと取れたデータ眺めてみたけど、bug-free
は xxx-yyy ではなくこれで xxx のようだ。まぁ bug だけで接頭語にするとバグ量産してしまいそうだしね。また computing-machine
や palm-tree
、rotary-phone
もこの組み合わせしか無いので yyy-zzz
ではなく zzz 側っぽい。
すると yyy で octo
以外はあと duper
だけなんだけど、これも super
と super-duper
がそれぞれ xxx にありそうだ。
というわけで xxx(-octo)?-zzz
という生成ルールなのではないか。
いやそれが分かったから何だって話だけど。