キャパがなくなったら頑張って余裕を作るのではなく、新しいことで上書きした方がいい
なんか心に余裕がないな、みたいな感じになったら見ようかな系の備忘録も兼ねて。
ストレスや悩みがあって心の余裕がなくなったとき、この歳になっても本当にしょうもないことにイライラしてしまうことがある。自分の場合、キャパシティがない状態で思案すると中断や漏れが多くなってもどかしさを感じ、自己防衛の気持ちからその原因を自身のコントロール外である外界に求め、理不尽な状況にあるんだと思い込んだり煩わしさそのものを感じたりする*1。
自己防衛の行動なのだから仕方ない*2と思うが、その理不尽や煩わしさから逃げるために取り返しのつかないタイプの決断をするべきではない。当たり前だけど、キャパがないということはその決断の結果を受け入れる覚悟をする余裕すら残っていないのだから、とても危険だ。ごく稀に人間関係をぶっちして逃げたくなることがあるだろうけど、昔やったときは普通に後悔したのでやらないほうがいい*3。
こういうときは無理に余剰を作って新しいことをできるようにするのではなく、いっそ新しいことだけで全てのリソースを埋め尽くすと大体解決する。このとき身体リソースと思考リソースのどちらもが上書きされる必要がある。
絶対にやっておくこと
- ひとが関わってる系の悩みならその人と一旦距離を置く
- それを理解してくれない人は自分にとって毒(要出典)なので、それこそ距離を置いた方がいい
- それを理解してくれて距離を置いてくれるひとは余裕ができたら感謝を伝えて大事にしましょう
- 仕事が関わってる系の悩みならとりあえず休みを取る
- 大丈夫、急に休んでもなんとかなる。というかいつも急に遊び目的で有給取ってるけどなんとかなってる(ありがとう同僚の皆さん)
- 部屋が汚いのならとりあえず家事代行を1.5h(or 1h)で呼ぶ
- 床掃除などは必要・不要の判断を聞かれたりするので、洗濯物とゴミ出しと水回りをやってもらうといい
- スポットで呼べばどうせその人ともう二度と会うことはない、または定期契約ならその人にだけ惨状を見せればいいと 普段から 割り切っておく
効果があったもの
身体を使うスポーツの中でも1つ1つのプレイを考えながらやるものやマルチスレッド系の完結作業などがよい。
- スノボやバスケみたいなスポーツやその反復練習
- ひたすら手を動かし続ける系のコーディング
- 5品目以上1時間半以内作り置きチャレンジ
- パーソナルトレーニングによるエッグい筋トレ*4
- 焼き肉*5
- 銭湯や温泉*6
あんまり効果がないもの
- スポーツでもランニングみたいな単一動作系
- 軽い負荷の筋トレ
- ぼっち飲みやサシ飲み
- 今持ってるタスクを頑張る
- 仕事*7
危険などの理由でやらない方がいいもの
普段は宿も移動手段(飛行機含む)も、というか行き先も当日決める突発旅行をしてリフレッシュしているが、ヤバいときはやってはいけなかった。
一度何も考えずに突発で札幌にいったことがある。そのときは飲んでる途中で宿を取ってないことを思い出したけど、ホテルに空きを聞くことすら面倒くさくなって朝まで飲もうとした。深夜まで飲んでいたのだけど、ふと早く帰らなきゃいけないのではないかという焦りが芽生えて新千歳空港を目指して歩き始め、結局糸が切れて新札幌駅近くのマックで朝まで過ごした。今思い返しても限界すぎたので、やめたほうがいい(自戒)。
おまけ
これを見る機会がないといいな(小並感)
*1:と言語化しているけど、本当にそうなのかは分からない。思い返すとそんな気がするって感じ
*2:他人を傷つけたり、人や物に当たる行為は無論NG
*3:こういったらあれだが、余裕がないときに切っても問題のない縁は余裕のある平常時に切っておけばいいように思う。もちろん切らないでも何も問題がないのなら切らなくていいんだけど
*4:考えたらしぬし、トレーナーが容赦ないので悩むどころか筋肉の動かし方としんどい以外の感情が消えてなんかよかった
*5:肉奉行っぽい性格もあるが、焼いている間だけは肉に全力で恋出来るので無敵
*6:温泉にたどり着くまでのハードルは高いので無理は禁物
*7:根本的に労働が向いてない勢なので・・・
*8:寝起きの罪悪感に襲われると次の行動が出来なくなって沼るので、どうしても寝たいなら寝起きにある程度緊張感を持てるスーパー銭湯で寝るといい
*9:何もしてないという罪悪感が中々ある、と感じることが多い
本や他人の言葉で主張を語られると意見の返しどころがない
文書を書くとき、「本や他人の言葉を引用して自分の主張に使うことはあっても、それらの言葉を自分の主張として語るべきではない」ということを肝に命じて記述している*1。
正直言うまでもないことだが、本や先達の言葉を引用しつつ自分の意見を主張することには良い効果が多分にある*2。
例えば他から言葉を借りてくることで自分の主張を補強できたり、複雑な背景や説明をあえて他のソースに委ねることで読み手・聞き手の前提を揃える助けになることもある。あるいは借りなかった場合、既存の語句を自分の言葉で再定義したが故に主張が伝わりづらくなってしまうこともあると思う。
一方で、本や他人の言葉を適切に借りるためにはテクニックと経験が必要になる。適切でない借用、例えば借りてきた言葉がそのまま自分の主張となってしまうような表現は誰にとっても良い効果がない。その主張に対して意見を返そうとしても、それは主張者(Aさん)ではなく他ソース(Bさん et.al)に対する意見になりがちだからだ。
A さんが「Bさんによると X という問題がある」「語句Yの定義をBさんのいうZとする」といった形で B さんという他ソースに丸投げした場合、問題 X があること自体・Zという定義に懐疑的な意見は一体「誰」に対する意見なのだろうか。多くの場合、B さんがその意見に直接答えることはできないため A さんが答えるしかない。しかし A さんは B さんの代理人ではないので、B さんの主張を勝手に広げる行為はできない*3。そもそも他人の主張を代弁すること自体、非常に難しいというか無理がある。もし意見のやり取りをする上でそのような状況に陥った場合、意見の向き先が迷子にならずとも孫引きや伝言ゲームのように情報が劣化・歪曲されてしまうことは想像に難くない。
ここで、特に本をソースとした場合は一定の(謎の)説得力を持ってしまう点も忘れてはいけない。さらにこの問題はその一定の説得力が効かないような踏み込んだ話であったり、ストーリー性に違和感が発生したときに表面化してしまう。最悪の場合だと、主張の根拠を失う結果になることもある。それでも指摘しないことは健全ではなく、指摘をすると空気が悪くなってしまう。誰も得をしない。全員が損をしている可能性すらある。
話は少し飛んで、ソフトウェア開発の中でもこのようなリスクが露出してしまった場面を時々見かけた。
- コードを理解することなく Stack Overflow などから借用してきたため、修正の根拠を聞いても「Stack Overflow に書いてあったので」「分からない」と返される
- 著名な設計に関する本で言及された設計思想やパターンを(言及されていることを以て)良い・正義とする
- 語句を「〜本に出てくる」という覚え方をしているため、その語句の意味を説明しようとしても答えられない
- J○ke が言ってた*4
勿論、一定の説得力の中で話が進めばそれはそれで問題がないのかもしれない。そんな場面が多いのか少ないのか、そして良いのか悪いのかは分からないが・・・。
なんにせよ、文書でもコードでも、「本や他人の言葉を引用して自分の主張に使うことはあっても、それらの言葉を自分の主張として語るべきではない」をこれからも意識していきたい。
とある文書を書いていたら下書きが全部吹き飛んでしまったので、正直いうと今は自分の主張を「この本(数冊)を読んでおいて」で済ませたくなっている。とてもつらい。
変な話ィ 2021
SHIROBAKO Advent Calendar 2021 - Adventar 4日目
変な話、君たち全部作りなおしだYo
事あるごとに「変な話ィ」という接頭辞でイライラさせてくれる茶沢信輔さん。TV版の四年後である劇場版での出番はRECAPのデフォルメ以外ありませんでしたが・・・2016年に引き続き今回はこの茶沢を取り上げたいと思います。
変な話ィ、やらかしが多すぎるんじゃないかなって思います!
TV版最終回では下っ端に降格されたのかカメラマン*1をやらされていることに胸がスッキリした方も多いでしょう。
さてそんな茶沢さんですが、テレビ版では原作者に話しを通さず「いいんじゃないですかね」「あーそれ良いと思いまっす」「それで進めちゃってください〜」などとのたまい制作を進めさせ、原作者が確認してNGを出すとすぐさま制作をやり直させようとする鬼畜を演じています。第三少女飛行隊の制作にあたって次が大きな手戻りでしょう。
- キャラクターデザインへの勝手なGoサイン及び原作者希望のリテイク伝達
- PV作製をギリギリになって言う
- 原作が追いついていないために放映版のラストを創作したところ、制作が進んでからの原作者要望のリテイク伝達
現実問題としてこんな人が指示側にいたら間違いなくその作品は終わりを迎えるでしょう。
変な話ィ、茶沢に守れるものもあると思いまっす!
締め切りも常識も守れていないのですが、そんな茶沢でも 原作者の気持ちを無視した放映が行われないこと だけは守れているという揺るぎない事実があります。
仕事量を増やしたくなくて原作者への確認を怠ったり、話し合いの場を設けないようにしたり、色々と仕事に粗は目立つ茶沢のワークスタイルですが、あのいわば自業自得の場面から「おたくらGODに楯突く気ですか!?」という勢いだけで制作側をリジェクト出来る胆力は目を瞠るものがあります*2。普通の人間には無理でしょう。
劇場版では三女2なるものが冒頭に出ており、中学生のようなエロ要素を適用したストーリーに変更されています。制作がヤバすぎたのか、新しい担当がエロさえやればいいと思ったのか制作の無理を断れなかったのか、真実はわかりませんが少なくとも茶沢がいれば原作者の意志に反することはなかったでしょう。まあ野亀先生がネタに詰まってエロに走った場合は茶沢でも無理なんですが、変な話。
まとめ
茶沢の印象として「変な話ィ」や「おたくらGODに楯突く気ですか!?」などと宮森たちの障害としての側面が目立ちますが、原作者の意志に沿わないことはキッチリと跳ね除け、要求をなあなあで通さないという点では一部職責を全うすることのできるスキルの持ち主です。そして劇場版に茶沢がいたら*3、三女2に「No」を伝えることができたかもしれません。
この記事を読んで茶沢のことが気になって胸焼けが止まらない方はNetflixでTV版を、それ以外の方はU-NEXTで劇場版を見ましょう。
おまけ
「Noを伝える技術」を学びたい方は pmconf 2021 のセッションをご覧ください。
「チームで育てるAndroidアプリ設計」を読んだ
ダイレクトマーケティングです。(PR) アフィじゃないリンクは一番下に置いておきます。
全体的な所感
アーキテクチャのモチベーションからアーキテクチャとチームの育成、将来を加味した運用方針について、非常に分かりやすく構成されています。新規プロジェクトへのアーキテクチャの導入、既存アーキテクチャの方向性の手直しや作り直し、既存アーキテクチャの思想読み込みといった よく必要とされる行為でありながら、あまり言語化されていないもの
をどういったモチベーションや理念を持って実行するのか、そして どうすれば独りよがりにならず、チーム・組織として運用することができるのか を学べる良い本だと思います。
本書は順番に読み進めるとテンポよく進んでいく章立てになっています。その一方で気をつけなければならないこととして、本中で利用されるアーキテクチャは チームのスコープで使用する汎用的な設計方針
と第一章で定義されるなど、その曖昧な語句の意味は本中で順を追って定義されます。前半で定義し終わるようにうまく構成されているとはいえ、頭から読み進めることで共通認識を得ることに変わりはなく、用語定義表などがあるわけではないので斜め読みをすることはあまり推奨しません。どうしても斜め読みをする場合、他開発者(著者)にとってアーキテクチャはどういう立ち位置であるかを理解するために第一章と第二章は確実に読んでおくことをおすすめします。
また少しエモみの溢れる内容から、想定読者(?)は以下のように感じました。
- ✅ 新たにアーキテクチャを導入したり、既存のアーキテクチャを補正・刷新するにあたって「アーキテクトとしての言語化の補助」「チームメンバー間でのアーキテクトに対する意識の統一」をするときに読むといい
- ✅ アーキテクチャの選択や導入手順に悩んでいるときに読むといい
- ✅ アーキテクトでもチームメンバーでもどっちであっても読むといい
- ❌ 何かしらの具体的なアーキテクチャの実装例を求めて読むといい
意図的な構成を感じたので、具体的な実装例についてはきっと新しい本の執筆が進んでいることでしょう*1。
ちょっとずつ細かく
自分が本を読むとき、二周目移行に役立つよう章立てをガン無視してラベリングしたりするのでその構成でどんなときに読んでおくと良さそうか、を書きます。
アーキテクチャ導入を説明するときのモチベーションと運用方針
パート: 第一章、第三章、第四章
第一章では新規開発を例にとり、新規開発で求めたいものからアーキテクチャを用意することの必要性が語られます。とはいえ、新規開発でなくとも、現在のチームにその求めたい点が足りていないのであれば同様の考えを展開することは可能なので、自分たちのフェーズが新規開発でなくとも読んでおくと良さそうです。
第三章と第四章はアーキテクチャ例に関係なく読めました。アーキテクチャをチームにどうやって浸透させ運用していくか、それを大きな組織内で横展開するにはどうやればいいのか、著者の経験も含めて語られています。アーキテクチャを導入しても「将来的に腐る運用」であればそのアーキテクチャの寿命は短く、早晩に毒となりえます。自身の運用に自信がなくなったり、迷いが出てきたら非常に良い指針となる章でした。
選択などに悩んだとき用。既存アーキテクチャのまとめ
パート: 第二章
チームメンバーの学習強度といった外的要因から始まり、アーキテクトが大体ぶち当たるであろう、早期に抑えるべき点が列挙されています。また多層アーキテクチャなどの既知のアーキテクチャでカバーできることも丁寧にまとめてあるため、あとで選択に迷ったら読むと良さそうです。
アーキテクトの意思決定の理解の一助となるはずなので、チームメンバーにはぜひ読んでおいてもらいたいですね。
実運用フェーズで考慮すべきコードや運用のメタなポイント
パート: 第五章
Android チームだけではなく、バックエンド他のプラットフォームとの協調も考えなければいけない実例を元に話が進みます。一定の規模までプロダクトや企業が成長したら確実に遭遇するとまでは言いませんが、特に複数の協調するプロダクトを持つ会社ではありそうなパターンです。
その特徴から、開発効率性と堅牢性の双方を重要視するという話は非常に共感出来ます。ただそれを実現するのは非常に難しいので、どのように合意形成をしていくのかであったり、ドキュメント文化であったり、泥臭いことも含めて整備していくことの重要性ややり方が書かれています。
めっちゃ大変だったんだな、と想像しながら読みました(小並感)。
大きいプロダクトからかかる制約例 - モジュラモノリス
パート: 第六章
モジュラモノリスを新規開発段階で考える機会はそう多くはないと思いますが、参考になるのはもちろんのこと単純に面白いです。
多くの既存アプリや社内SDKと協調するプロダクトの開発経験に関する知見を得られます。これはアーキテクチャを主導する人だけではなく、参加する人にもかなり有益じゃないでしょうか? 単にプロダクトの大小に関する1軸ではなく、組織規模も含めた2軸以上を考慮したアーキテクチャはその複雑度や裏にある思想が多くなりがちです。それらをプロダクトに参加して即把握するなど超人以外には不可能なので、この章で知見を得ておくと将来役立つかと思います。
機能開発の効率増加やDX改善といったフィードバック運用方針
パート: 第七章、第八章
すごくエモい方法論の第七章と具体的なクラス特性を改善しつつ説明する第八章のセットです。アーキテクチャを運用していると確実にぶち当たる壁で、これを蔑ろにしているとそのアーキテクチャは腐ってしまいます。ここで紹介された運用手順を導入した場合でも、定期的に見返すことで運用の健全性を考えていくと良さそうですね。
退職と人事異動というコラムが最高だったのでぜひ買って読みましょう。
新規開発と大規模開発で意識する点まとめ
パート: 第九章
新規開発でいきなり複雑なアーキテクチャを導入する必要性はないように思うことも多いですし、逆に大規模開発では多様なレベルの関係者が増えることで制約を増やした方が全体的に健全になることもあります。そういった違いをぱっと見るにはこの章をあとで見返すことになると思います。
蛇足
個人的に本書で書かれたアーキテクチャ周りのモチベーションや思想はかなり近いものがあります。著者陣の二人と仕事をしたこともありますし、設計談義を良くするのですでに意見を知っているとは言え、改めて言語化されたことで再認識する点もありました。
執筆お疲れ様でした。
https://peaks.cc/books/architecture_with_team
*1:しらんけど
2020 買ってよかった気がするもの
めちゃくちゃ雑に書きました。お金を使ってしまったなぁ、という自戒も込めて。微妙だったものも書こうか悩んだんですが今回は書きません。
仕事編
Dell - U3419W
34 inch の曲面モニターです。今回買ってよかったものに入れていますが、購入当初は結構ネガティブなことを言ってました。
mobile.twitter.comこれは給付金入ったからって調子乗って十数万の UWQHD のディスプレイを買い、たった1ヶ月しか経ってない人の感想なんですけど、4Kディスプレイにする or 買わなきゃよかった👶 どんなに広くても画質が悪いと見続けるのがキツイので意味がない。
— 🦉だるま (@red_fat_daruma) July 27, 2020
このときは曲面モニターを iMac Retina 5k と併用していたので駄目評でしたが、今は Macbook とこの曲面モニターを繋ぎ、曲面モニターをメインディスプレイにしています(iMac は別で単体利用)。 画面左右半分で分けて、普通のディスプレイなら1枚でしか表示出来ない領域を2つ横並びで表示する形で利用しつつ、MacOS の Workspace 機能を併用して用途ごとにうまく切り替えてます(そしてその切り替えをゲーミングマウスのキーに当ててます)。また Slack のような watch する系のアプリは全部 Macbook 側に配置して、このディスプレイは作業のみに集中出来るようにしています。元々の問題は iMac との解像度の差だったので、今の構成だとそのデメリットは全てなくなり幸せです。
値段相応の価値があるかどうかに関しては「今の運用ならある」という感じで、運用次第で無価値にもなりそうだなという感覚です。曲面ディスプレイに慣れるまではそもそも作業効率に響く可能性は高く、単純に平面複数の方が嬉しい人も多いはずです。
佐藤ショップ - モニター台
スマホ台は使っていませんが、大きさが変化する点や最大幅であれば Realforce がシュッと入る点が気に入ってます。耐荷重的にも足的にも iMac をちゃんと置けます(耐震マット等はちゃんと対応しましょう)。小物が多くなる人にはオススメです。なお配線はどうにもならないので諦めました。
生活用品編
キッチン・食品
熊本製粉 - グルテンフリー ケーキミックス
米粉ベースなグルテンフリーのパンケーキがレンジで作れます。ボウルなどを必要とせず、そのままレンジで作れる時点で最高 of 最高なのは日頃パンケーキを作る民にとって自明だと思いますが、こいつはグルテンフリーな上に中々美味いです。僕はプレーンに低糖質ココアプロテインバーと牛乳をぶち込み、ココナッツオイルと蜂蜜突っ込む魔改造ブレンドが好みです。グルテンフリーなので、何を入れてもノーカロリーロー糖質です(ガバガバ計算)。
EMEBAY - 包丁 & まな板立て
少し足があり、安定感のある以下の包丁立てつきまな板置きを買いました。コンパクトで結構軽く、思ったとおり安定感もあって非常に便利です。これもそんなに足が長いタイプではありませんが、これ以上足が短いタイプを使っていたときに抱いていた不清潔だなーという感想がなくなって良い感じです。
岩崎 - スクリュートップキーパー
かの有名な保存容器です。スクリュートップできっちり閉まる、ちょうどいいサイズ感、清潔感のある見た目と中身がちゃんと見えるクリア度、レンジも食洗機もOKと最高最強の保存容器です。ダースで買いましょう。前からいくつか持っていましたが、今年小型のものをナッツケースなどにする目的もあり、全て新調しました。
霜鳥製作所 - カヌレ焼型
銅型・・・はさすがに高すぎるので、テフロン加工のもので縁巻き加工してあるものを選びました。ヤスリで削ってあっても、縁巻き加工していないものは手を怪我しかねないのでオススメしません。この製品は縁巻き溶接はされていないので、そこに汚れが入ると頑張って落とさないといけないです。とはいえ、お菓子作りの型はカヌレ型に限らず基本ブラシで洗うようにしてるので問題としていません。
mobile.twitter.comカヌレ焼けた~ウマイ!🤗 pic.twitter.com/gaKPv6cXth
— 🦉だるま (@red_fat_daruma) May 17, 2020
健康・スポーツ
LPN - ストレッチポール
リモートワークが増えたので肩甲骨を開いたりするためにストレッチポールを買いました。毎日10-20分くらい寝起きにやったり、疲れたなーってときに設計や仕様を考えながら延ばしてます。
腰や背中を伸ばすということもあり、何も考えずに乗っていると怖いので整体士と一緒にストレッチポールを組み入れたストレッチメニューを考えたりしています。
イケヒコ・コーポレーション - い草 畳マットレス
もう実家を出て10年になるんですが、未だにベッドが好きになれません(実家は和室に布団)。かといって和室の物件を探すと築年数が中々のものなので、今回ベッドフレームを捨ててそのまま畳のマットレスに切り替えました。この上に整体マットレスを敷き、寝く形です。
折りたたみ式で使ってないときはコンパクトに出来ることが売りっぽいんですが、割と重いので数日おきに起こして風通しをする以外は基本敷きっぱなしで生活しています。そのため休みの日はこの畳の上にクッションを敷き、胡座をかいてコーヒーを飲んだり日本酒をこぼしたりして幸せな時間を過ごしています。
アウトドア編
自転車
PIRELLI - P ZERO VELO 700-25C
今まで FELT F85 に 700-23C のタイヤ(標準)を装備していたんですが、パンク頻度やすり減り、それと70km超えのときの疲労が深刻になってきたので25Cにあげて付け替えました。めちゃくちゃ柔らかくて取り付けは簡単だし、街乗りには十二分の性能を発揮してくれます。
単純に 23C -> 25C になったことで振動も減り、その疲労は減ってます。ただ取り付けに寄与してるその柔らかさは普段の走りにも出てくるので、正直120km超えた辺りから加速がしんどくなりそうだなという感じ。限界圧もそこまで高いわけではないので、好みは分かれると思います。
キャンプ
ヘリノックス - チェアツー
元々名前も知らない安い小さめの折りたたみ椅子を持っていましたが、今回大きめの椅子を買いました。安定のヘリノックスです。座り心地はかなり良く、生地も丈夫で安心感があります。でかいモデルなだけあって、188cm 78kg の僕でもゆったり座る事ができます。
ついでにロッキングフットも買いました。地面がある程度しっかりしている必要がありますし、ないと利用出来ないとかいうわけではないので必須ではありません。ただ焚き火に当たりながらゆらゆらしたいという希望がある人は買うべきです。
Mozambique - キャンプテーブル(ロールタイプ)
キャプテンスタッグの例の王道テーブルはもちろん持っているんですが、かなり位置が低いので椅子から無理なく届く高さで、丈夫、そして軽いテーブルを探したところこのテーブルがヒットしました。
コンパクトにまとまり、出し入れが非常に簡単です。また布なので軽量さは言うまでもないです。それでいてテーブル面がしっかり平らになり、かなり安定感があります。めちゃくちゃ便利なので、普段から室内で時々利用してます。
バイク
KABUTO - CF-1W ピンロックシート と チークパッド
今年バイクの免許を取ったので、ヘルメットに KAMUI3 を選んだんですが何回か走りにいって以下の2つは必須だなと思いました。
CF-1W はクリアタイプの曇り止めシートで、ちゃんと装着すれば本当に曇らないです。ただ正直言って、何をもって「ちゃんと装着した」となるのか良く分からなかったので、部屋でヘルメットして作業して曇りを確認してました。絶対確認して調整しましょう。
チークパッドは 20mm を追加購入しました。デフォルトが 30mm なんですが、結構な圧迫感があります。太ったら終わるな・・・という危機感と戦っても良かったんですが、装着時間が40分超えた辺りから脱着後の痛みが発生したので諦めて買いました。
リモートワークでの足元ヒーター三銃士
買ったもの
出力切り替え型セラミックヒーター
このタイプには最大1000W、下は300-500W帯が多いです。
期待していたことは
- 初期コストの低さ
- 強弱の切り替えで十分
出力ダイヤル可変セラミックヒーター
下は200W辺りから、ダイヤルで任意の出力に設定出来ます。最大1000W超えが意外とあります。
期待していたことは
- 初期コストの低さ
- 細かく設定出来ること
- キャンプでの利用
足元を囲うタイプの遠赤外線ヒーター
色んな種類がありますが、下有りで上が空いてるタイプを選びました。また殆どがダイヤル式で任意の出力に切り替えられます。
期待していたことは
- 局所性のなさ
- 足裏への対応
評価
出力切り替え型セラミックヒーター
< 出力ダイヤル可変セラミックヒーター
= 足元を囲うタイプの遠赤外線ヒーター
<< 靴下 & 裏起毛ズボン & 座布団 (or スリッパ)
とても悲しい結果になりましたね・・・結局今は以下の構成の上で仕事をしています。(足裏汗っかき & 夏場を考慮しているので、湿気取りシートは必須です)
<足元のみミニカーペット>
<薄いカーペット>
<断熱シート>
<湿気取りシート>
<フローリング>
また窓枠には断熱シートを必ずしましょう。これだけで冷たい微風が発生しなくなるのでだいぶ楽になります。
出力切り替え型セラミックヒーター
- 👍 軽くて片付けたり取り出したりが楽
- 👍 出力は十分高い
- 👎 局所性の関係で弱い出力だと周りが寒く、強い出力だと暑すぎる部分ができてしんどい
- 👎 ホコリが溜まりやすく、溜まってると臭い
- 👎 消し忘れると怖かった
- 👎 蹴る、熱い、痛い、寝落ち危ない
出力ダイヤル可変セラミックヒーター
- 👍 軽くて片付けたり取り出したりが楽
- 👍 出力は十分高い
- 👍 柔軟な温度調整が出来るので、局所的なヒーティングに関してはかなりよい
- 👍 テント内のように閉じた空間であれば高出力でヒーティングできる
- 👎 ホコリが溜まりやすく、溜まってると臭い
- 👎 消し忘れると怖かった
- 👎 蹴る、熱い、痛い、寝落ち危ない
足元を囲うタイプの遠赤外線ヒーター
- 👍 ブランケットを併用するとシッティングだけならかなり暖かい
- 👍 コロコロを使えばいいので掃除しやすく、匂いもない
- 👎 案外温度調整が難しく、出力を下げても保温されてるので冷やす必要があり、だからとってブランケットを外すと一気に冷えてしまう
- 👎 かさばるし、意外と重量があるので結構邪魔に感じる
- 👎 膝辺りがちょうどいい出力だと足裏暑すぎて汗かく
- 👎 足元の遊びが減って、ちょっと動かすとぶつかる(意外と強い)ので集中力をかく
靴下 & 裏起毛ズボン & 座布団 (or スリッパ)
- 👍 シッティングにもスタンディングにも対応出来る
- 👍 そのままコンビニにいける
- 👍 温度調整は装備の脱着や他手法との併用で対応出来る
- 👍 椅子の上であぐらかいたり出来る自由度の高さ
- 👎 座布団はしっかりしたもの、またはマットにしないとスタンディングのときに危ない
- 👎 他に比べるとちょっとコストが高くなりがち
- 👎 睡眠への誘惑が高い
反省点
- そもそも局所的なヒーティングや空気を暖めるタイプは今回の用途に向いてなかった
- スタンディングとシッティングを切り替える人の場合、どちらもカバーしたいなら服での対応は前提条件
- 足裏はヒーターじゃなくて靴下やスリッパで頑張らないと汗をかく(もちろん体質による)
- スポーツ用のシャカシャカズボン(アレなんて言うの)を好んでいるので、ヒーターから距離を取る必要があるし、ヒーターがそもそも向いてなかった疑惑がある
- セラミックヒーターって安物が多く、安全装置が信用ならないと感じてしまって使う気を失っていった
- 全部買ったせいで初期コストが全く安くなかった
- 電気代は軒並み普通に上がったのでそこまで差は感じなかった
Javaからの利用を視野に入れたKotlinコードで何をするべきか
(2015年に書いたものをコピペ)
Kotlin Advent Calendar 2015 10日目.
TL; DR
Javaからの見た目を考慮して,アノテーションと修飾子を使って整形しましょう
@file:JvmName
,@JvmStatic
,@JvmOverloads
をつけようconst
,open
修飾子は適切に- interfaceのdefault/static methodの扱いには注意しよう
Javaからの利用を視野に入れるということ
Null-safeの恩恵は強いし,拡張関数は便利だし,他にも色々機能はあるし,多分金髪美少女だし,Kotlinは非常に扱いやすい可愛い言語です1.
さらに,普段からJavaを用いて開発しているひとにとって馴染みの深いbuild toolを用いた開発が可能です2.
つまりはbuild toolさえ動けば良いので,jitpack.ioなどのpackage repositoryサービスでもKotlinの利用が可能になっています.となると,Kotlinライブラリの配布・利用を行う壁は非常に低いことが分かりますね.
Kotlinの特徴を用いたライブラリの利点は KotlinからでもJavaからでも非常に高いと思っています.Kotlinだけをターゲットとしたライブラリであれば必要ないのでしょうが,JVM上で動作する便利ライブラリとして配布していくとしたら,最低限Javaからの利用は考慮する必要があるでしょう.
それらの考慮のうち,ひとの手による調整が必要/適切だと思われるものをあげていきたいと思います.
Staticメソッド周り
Kotlinで NameSpace.method()
と呼び出せるメソッドを定義する際,companion object, named object,Package-level function が挙げられます3.
例えば以下のような定義をKotlinでしてみましょう.
package daruma fun debu() = true class RedDaruma { companion object { fun fat() = true } } object Jmatsu { fun yaseru() = throw NotImplementedError() }
Kotlinからであれば daruma.debu()
,daruma.RedDaruma.fat()
,daruma.Jmatsu.yaseru()
で呼び出せるこのメソッドたちですね.
しかし,Javaから呼び出す際はそれぞれ daruma.DebudarumaKt.debu();
,daruma.RedDaruma.Companion.fat();
,daruma.Jmatsu.INSTANCE.yaseru();
と書くことになります.
KotlinではPackage-levelでのfunction定義が可能.
特に指定がない場合, Packege-level functionは "${filename}Kt"クラスのstaticメソッドとして充てがわれる.
でも "${filename}Kt"
とか Companion
ってださいしあんまり良くないですよね.そこで fileに対する@JvmName
と methodに対する@JvmStatic
アノテーションを利用します.
@file:JvmName("Majide") // Use Majide instead of DebudarumaKt package daruma fun debu() = true class RedDaruma { companion object { @JvmStatic fun fat() = true // Don't need Companion } } object Jmatsu { @JvmStatic fun yaseru() = throw NotImplementedError() // Don't need INSTANCE }
とすると,Javaからでも daruma.Majide.debu();
,daruma.RedDaruma.fat();
,daruma.Jmatsu.yaseru();
で呼び出せるようになります.
※ object
の場合,インスタンスメソッドであって欲しいときには関係ありません
Kotlinを知っている人からすると xxxKt
や Companion
といったクラスが補完で出てきたら色々と察するところではあると思うんですが,そうじゃない人たちにとってこの部分はなかなかの障害になるかと思います.
拡張関数について
拡張関数は定義した位置のstaticメソッドとして生え,レシーバーとして第一引数に充てがわれます.つまり上記のstaticメソッドのケースが当てはまります.ということで同様の対策を行いましょう.
ついついPackage-levelの位置で宣言しがちですので,@JvmName
を充てましょう.
Interfaceに載せる系の実装
Interfaceのstaticメソッド
JavaだとJava8からinterfaceにstaticメソッドを定義できるようになりました.
Kotlinでは companion object
を使うことでinterface上にstaticメソッドが生えたように見せることが可能です.(Kotlinから見た場合)
しかしそのとき,Javaから見るとCompanionオブジェクトが生えることは上記で説明しました.
では @JvmStatic
をつければよいのでしょうか? 答えはNOです.(そもそもつけられません.)
つけられるとしたらそれはJava8相当の動きになることを表していますね.
結論として,前述したstaticメソッドと同等の挙動を実現することは不可能です.
そこで妥協策としては named object で実装することで Companionという名前を回避することになります.
interface Foo { fun foo(): String object Bar { @JvmStatic fun baz() = 10 } }
とすれば,Javaからは Foo.Bar.baz()
として呼び出すことが可能です.
Interfaceのdefaultメソッド
JavaだとJava8から,interfaceのメソッドにdefault修飾子を指定することで初期実装を与えることができるようになりました. 詳細は割愛しますが,主な特徴として,interfaceを継承したクラスにおいてデフォルト実装を持ったメソッドをOverrideをするかしないかは任意となっています.
Kotlinのinterfaceではdefault修飾子は必要なく,通常のメソッド定義と同様にメソッドボディを持たせることができます. これをKotlinはJVMに解釈させるためにどう変換しているのかが問題になります. 以下の例を見てみましょう.
interface A { fun foo(): String = "foo" } class B : A { // Overriding 'foo()' is not needed }
同様の実装をJava8で書くなら
public interface A { default String foo() { return "foo" } } class B implements A { // Overriding 'foo()' is not needed }
となりますね.
ではKotlinで定義したinterface A
をJava側で継承し,自動生成してみましょう.
public class B implements A { @Override public String foo() { return null; // 'foo()' must be implemented! } }
はい,残念ながらJava8のdefault methodと同様の動きとはいきません. では消えてしまったのでしょうか? JVM上で動いてる以上,そんなわけはないですね.
代わりに A.DefaultImpls.foo(A $receiver)
が定義されています.
interface内部に定義されたstatic finalなclassにおいて,staticメソッドとして移植されるわけですね.
これに関してはKotlinから(アノテーション等で)どうこうできる問題ではありません. Javadocに「デフォルト実装がある」と書いておくくらいしか出来ません4. DefaultImplsという名前も変えることは自分ではできませんでした.また変えてしまうとデフォルト実装がどこに置かれるかがわかりづらくなるため,これに関してはそのままで良いという感じもします.
このケースではJava側が注意する必要があります. つまりKotlinのinterfaceを継承したクラスではDefaultImplsがあるかどうか,あるなら中でdecorateするといった行為が必要になるでしょう.
public class B implements A { @Override public String foo() { return DefaultImpls.foo(this); } }
Staticでfinalなフィールド周り
Staticでfinalなフィールドはまた違う問題があります.Kotlinは優しいのでフィールドにはgetter/setter
をつけてくれます5.つまり何も指定をしなければカプセル化をしてくれるということですね.そう,それが例えstaticでfinalであっても・・・
package daruma val debu = true class RedDaruma { companion object { val fat = true } } object Jmatsu { val yaseru = null // :bow::bow: }
とすれば,
- daruma.DebudarumaKt.getDebu();
- daruma.RedDaruma.Companion.getFat();
- daruma.Jmatsu.INSTANCE.getYaseru();
が推奨されたアクセスになります.この表現から分かると思いますが,
- daruma.DebudarumaKt.debu;
- daruma.RedDaruma.fat;
- daruma.Jmatsu.yaseru;
は非推奨のアクセスになります.※ ちゃんとstatic&&finalで宣言されてます
こちらはアノテーションではなく,const
修飾子を使います.
package daruma const val debu = true class RedDaruma { companion object { const val fat = true } } object Jmatsu { const val yaseru = null // :bow::bow: }
ちなみにこちらだと先ほどの推奨と非推奨が逆転した形になります.
デフォルト値を用いたメソッド・コンストラクタ
Kotlinを使っていると結構使うのがデフォルト値.便利の一言に尽きます.
class GitApi { fun push(remote: String = "origin", branch: String = "master", force: Boolean = false) { // do something } }
実はこれ,Javaから見ると GitApi#push(String, String, boolean)
しか定義されていません.割と困ります.そこで @JvmOverloads
アノテーションを使って解決しましょう.
class GitApi { @JvmOverloads fun push(remote: String = "origin", branch: String = "master", force: Boolean = false) { // do something } }
- GitApi#push(String)
- GitApi#push(String, String)
- GitApi#push(String, String, boolean)
@JvmOverload
アノテーションにより自動で各メソッド(今回だと追加で2種類の計3種類)が定義されます.引数が全て揃ったメソッド以外は中でdispatchするだけの存在になります.
実はこれコンストラクタにも使えるんですよね,ということで
Androiderの方には下記のコンストラクタ定義が結構おすすめ
import android.content.Context as Ctx // 横に長過ぎたので import android.util.AttributeSet as AS // 同上 class CustomView : View { @JvmOverloads constructor(ctx: Ctx, attrs: AS? = null, style: Int = 0): super(ctx, attrs, style) { // init action attrs?.apply { // load the attributes } } }
クラス継承とOverride
9日目で @RyotaMurohoshi さんがちょうどこの周りの話をしてくださいました6.
Kotlinでは継承に関して未指定の定義 == Javaでいうfinalで修飾された扱い となります.
これに関しては存在そのものになど賛否両論あるかと思います.ただ賛否どちらでも変わらない事実として,「このクラスは継承させたら困るからfinal」と考えていた人は「このクラスは継承してもいい/されることもあるからopen」という逆の考え方をしなければなりません.
自分のKotlinコードであればエラーが出た際に修正する程度で構わないのかもしれませんが,他人のライブラリ,あるいは自分が他人へ提供するライブラリではそんなことも言えないので,気をつける必要があるでしょう.
まとめ
- Package-level declaration は
@file:JvmName
で空間名の指定 - 静的メソッドは
@JvmStatic
で生やす場所の指定 - 静的な不変値は
const
で - デフォルト値は
@JvmOverloads
で自動多重定義 open
の指定は適切に- interfaceのstaticメソッドは
named object
&@JvmStatic
- interfaceのdefaultメソッドはJava8とは違う挙動になり,DefaultImpls
Kotlinは非常に便利ですが,Java100%相互運用という利点を活かそうと思うと,やはりひとの手である程度の補正を行う必要が出てきますね.
おまけ
IntelliJ上でのsealed classの扱い
Kotlin M13よりsealed classというものが追加されました7.
sealed
という修飾子をつけると,そのclassを継承する際に制限をかけることができます.その制限とは,「sealed classを継承するクラスはそのsealed classの内部クラスであること」になります.
sealed class A { class B : A() // ok } class C : A() // error
Javaから使った場合もちゃんとコンストラクタ周りで怒られて継承はできません.正しい挙動ですね.
ただ現状,IntelliJだと以下のコードにエラーがエディタ上に表示されません.
package daruma sealed class A
public class D extends daruma.A { public D() { super(); // 本来なら private access ということで怒られるはず } }
勿論コンパイル時にはエラーとして検出されるので,Runtimeでは全く問題がないのですが.
Kotlinのコードをjarにし,Eclipseで書いてみるとちゃんとエラー扱いになります.ただこのケースでもIntelliJだとやはりエラーが見えないという・・・ Javaでprivateコンストラクタのみを宣言したクラスに対する継承の場合はちゃんとエラーが出るので,Kotlinプラグインの問題なんですかね.
Javaから見るドキュメント
KDocを書いたときのJavaからの見た目ですが,特に差異はないです(違いを見つけていないだけかもしれませんが).
下記の環境の元,書かれました.
- Kotlin 1.0.0-beta-3595
- Android Studio 1.5.1 #AI-141-2456560 w/ plugin IJ141-11
- IntelliJ IDEA 15.0.1 #IU-143.382 w/ plugin IJ143-26