最近の電話のゲーム事情2017-02

最近の通勤電車の立ち時間のゲームのラインナップ。座ってるときは読書、立ってるときは電話でニュース閲覧かゲームっすね。

Swipe Brick Breaker

これはmonthly23という別名からもわかる通り、作者が月に1個のゲームをリリースすると宣言して作った23番目のゲームらしい。Shoot Bubbleとブロック崩しを融合させたようなゲームで、なかなかに秀逸。どんどん数が増えていくのもいい。

難点は、1回のゲーム時間が長いこと。下手すると通勤時間丸々使ってしまうくらいだ。

面清倶楽部

名前の通り、面前の清一色の待ち牌を当てるゲーム。横持ちなのであんまり電車の中ではやりにくい。ので、座ったときで本を持っていないときにこれをやることが多いかな。時間制限もないのでゆっくり考えられる。おそらくランダムで問題を出しているため、ノーテンが多いのはご愛嬌。麻雀も長いことやってませんが、懐かしくはある。訓練にはいいと思います。まあ清一色で悩むのは、待ち牌以外が来た時にどれを切ったら広くなるのか、フリテンを防げるのか、といった点ですけどね。

Kuromasu

ゲームの正式名称は良く分からないが、パズルゲームの新星。ゲーム性は結構いい感じに思えているが、難易度が上がったときにどうなのか。正解が一意ではないような気もするんだけど、どうだろう。あとクリア画面が地味なので、クリアしてるのかどうか不安になる。

(追記) Kuromasuはニコリの「黒どこ」でした。

徒歩

前回の健康診断で引っかかったため、減量プログラムが組まれるに至りました。食事には気をつけます。ついでにてくてく歩いてカロリー消費…ひっそりそのような活動をしています。長らく痛めている足首も、サポーターを使えばどうにか騙せる。疲れ切って若干遅めに家に帰るといかにも激務のリーマン、って感じがして大人になった気になりますしw

私は故あって都心に勤めているんですが、あの辺だと一駅歩こう、とは言っても、都会なんで一駅っつっても何キロもないんですよねぇ。毎日一駅歩いてたんですけど、調べたら1kmとかそこいらでした。そんな…10分ちょいじゃんか。どおりで歩いた気がしないわけだよ。まあ新丸子←→武蔵小杉(500m以下)ほど近くはないが。それで、試しに二駅歩いてみたんです。それでも物足りないので、調子に乗って次の日は三駅歩きました。しかし通勤に使っている地下鉄はちょうどその辺でくねっていて、直線に近いルートを使えば四駅と三駅はあまり変わらないということをグーグルマップが教えてくれた。じゃあ四駅だ!

…というわけで、どんどん距離を伸ばしていったんですけど、こないだ国会議事堂前をてくてく歩いたんですよ。国立劇場だの最高裁判所だの国会図書館だの国会議事堂だの。日本の中心じゃないですか。歩いてる奴らもカジュアルさに欠けているし、やたらに格式の高そうな古そうな使いにくそうな建物が多いと思ったよ。でも、日本の中心なんだからさ、もうちょっとハイテクな感じにした方がいいんじゃないかな。

でも」と言えば、国会議事堂の近くはいつもデモやってんですかねー。なんかドラム音? に乗せてリズミカルに何か叫んでたなぁ。そことは別の団体? もいたみたいな感じだった。割といい拡声器使ってんですね。割と年配の人が多かったかな。警備員がたくさんいるので治安も日本トップクラスだろうし、道を聞くにもいいんだろうけど(聞かなかったけど)、なんていうか、てくてく通りづらい。まあまた通りがかってまたデモやっていたらあの道は敬遠して、別の良さげな道を探そうと思う。あの辺は皇居っていうでかい空間があるし、街並みの空間も均一ではなく表情が豊かというか、ところどころ、かなりハイレベルの絶景っぽい光景もあるので、ベストなてくてく道を開拓すれば良いてくてくライフを送れるんだろうと思う。

次はどこまで歩こうか…

GarageBandの入力

いやーまさかCommand(⌘)+クリックで入力できるとは思いませんでした。ずいぶん悩んだけど、ググればすぐ分かったんだよこんなこと!

気合いでキーボードでタイミングを合わせて打ち込むのかと、暗澹たる思いを持ってしまっていた。まあそこまでやるならabc2midiかなんかでテキスト入力していくけれども。慣れてしまえばGarageBandのこのインタフェースは便利と思える。スコアに直接入力することすらできる。まあスコア直接は使いにくいのでピアノロールかな。これでMacでも耳コピ作業をできる環境にあるってことが分かった。次はピアノロールの幅がちょっと狭いので、縦方向に拡大する方法を知りたい。横幅は拡大縮小できるということは理解した。

しかもそのままエンコードしてiTunesに送れるというね…いや別にそこまでは期待していないのだが。便利な世の中になったもんだねー。ただ難点は.midiファイルを書き出せないので、作ったデータを保管するのが面倒な話になるっぽい。あとMac版はコード入力ができないと。ふーん。

Java民によくいるsetterやgetterの信奉者はその罪深さを知るべきでは?

setterとgetterというバカバカしいものがありまして。クラスの中のメンバ変数をわざわざprivateにして、publicメソッドのsetXXX()やgetXXX()を作ってその変数にアクセスさせるという。結果、メンバにアクセスするコードはこうなる。

a.getXXX().getYYY().getZZZ().setAAA(1);

これ、外からprivateメンバにアクセスしてるんですよ。こういうイリーガルなコードが世間に流布していて、あまつさえ書いてるやつらは正しいことをしてると思ってるんです。クソが。

まあ、そういう文化と称するものがあるんですよ。何でもかんでもprivate変数にpublicなgetter/setter。これをIDEが自動生成するからいいんだそうです。おめでとう、人類はそこまで思考停止するようになった。例えば将来、最高に頭のいいコーディングAIが出てきたとして、そいつが書くコードがgetter/setterの嵐になっていることを想像できるでしょうか? なってるわけないですよね。

自動生成もコードに残ってると変な気分になるという罪悪感を感じた人物がいまして、lombokというのを作ったんです。これなら変数やクラスに@Setterとか@Getterをつけておくことで自動でsetter/getterのpublicメソッドを生成してくれるんですよ。なんてアホなんだ…で、みんな「これは偉大な発明だ!」みたいに感激して、ありがたがって使ってる。…教えてあげるけど、それオブジェクト指向が始まった頃からあるんですよ、publicって言うんです。それで変数を直接publicにできるんです。お前ら知らなかったんだろうけど! すごいでしょ。

いいですか、setterとgetterが存在すべき条件を考えてからprivate変数を作りましょうよ。JavaにはC#にあるようなメンバ変数へのアクセスにread/writeごとの権限をつけるシンタックスシュガーがないため、setterとgetterをprotected/private/publicとすることでread/writeごとの権限を管理できるようにしたわけです。若干の論理を入れたい場合もこれに相当しますが、そんな使い方は今となっては逆に単純に悪になってしまったので犬の餌にでもしとけ。クソが。

あとはライブラリとしてAPIを作る場合。これは将来の内部コードの変更に備えてgetter/setterをつけておいて、あとでメンバ変数の名前や役割を変えるとなった時にgetter/setterの名前を変えずに辻褄を合わせることができます。ただ、普通のライブラリだとそのくらいの非互換性は許容されていると思いますけどね。無理に互換性を保とうとすると効率悪くなりますし。割と広い、OSのシステムコールみたいなレベルのAPIの場合は、守り続けないといけないケースもありますけど、そのレイヤのプログラマはバカでない頭脳をしているのでsetter/getterなんて使ってない。

そういうわけで、read onlyな変数が作れないのでprivate変数にpublic getterをつけるというのはいいです。残念だがそれは認めるしかない。それなりの理由がある場合はいいんです。ですが、単にアクセサをつけるのが習慣なので…というバカバカしい理由で環境汚染を進めるのはやめてほしいです。だって実行効率は悪くなりますし、シンボルやコードも増えて、実行バイナリのサイズも増えますよね。ストップ地球温暖化。その罪を知りなさい。クソが。

あとEclipseの場合、このメンバ変数はどこからアクセスされているんだろう…と思う時に、lombokが作ったsetter/getter経由でアクセスされた時のリファレンスを辿れないんですよ。しょうがないので、まあライフハックみたいなものだけどどうしているかというと、メンバ変数の名前を適当に変えて保存してみて、それでコンパイルエラーになって赤くなったところ。そこからアクセスされているのだ、という感じで探していますね。それで自分がsetter/getter派に飼いならされて日に日に知性が失われていくことを感じるんですよ。AIが進歩して人類を追い越すのではなく、人類が後退しているのだ。

それと困ったこととしては、getXXX()とかsetXXX()て名前の別の意味のメソッドを作るときにためらわれる、というね。getterとは違う、getterみたいな名前のメソッドなんて、誤解されちゃうから作れないじゃないですか。使いやすい単純な名前取るなよ。どうせならもっと使いにくい単語…acquireとか? にすりゃいいじゃねーか。クソが。

というわけで、setter/getterつけてるメンバ変数は全部publicにしても不都合はないんです。たいてい、その方が少しはマシなコードになり、世界は救われます。それにしても、Java民が毎度毎度、よりによってクソな方の習慣に魅せられるのはなぜなのか。

セルフレジ

最近だとセルフレジの他に、商品登録は店員さんがやって、支払いのところだけ顧客がやる支払いセルフレジというシステムがあるじゃないですか。

小杉の東急スクエアの中のマルエツが支払いセルフレジというのを結構前に始めて、最初は「こいつら迷走してやがるな」と思っていたんですが、宮内ライフでセルフレジが始まって、セルフも経験してみると、私はマルエツの方が優秀だなと判定した。

あれは多分ライフのシステムが悪いんじゃないかと思いますが、結構厳しく作ってあって、ちょっと手間取るとすぐに「勝手に入れないで」みたいな感じの反応をされてしまうんですよね。小さなビニール袋の使用やレジ袋内の配置とかを考えてレジを通す順番を決める必要があるのに、そこで意外な反応ばかりされると調子が狂ってしまって、あー、みたいな感じになる。そして順番を間違えたせいでレジ袋の中を少しいじるとまた「勝手に入れないで」的な反応をされて…うーん。新城にある西友(ウォルマート系)のセルフレジではそんなに戸惑わなかった気がするんだけどな。あっちでは生鮮食品や惣菜を買わないからなのかもしれない。セルフは買う商品が1個とか2個とか、お菓子だけとか、そういう時だけにしておこうと思った。雑多なものをたくさん買うときには全く向いてない。

マルエツの場合はそこは適当で良く、小銭が十分少なければ「パスモで」と言って交通系ICカードでそのまま支払えるし、現金で払うとしても小銭をありったけ放り込んで足りなければ紙幣を入れるという気楽さ。そしてレジ袋に詰める作業はまた別なので、それも既存の手続きと同じでスムーズに動ける。店員も現金を触らないで済むのでハッピーだし。回転のスピードはもともとの向上幅は少ないが、支払いがもっさりしている顧客のせいで詰まるということはなくなった。顧客がやるよりは遥かに高速な、店員のスピードで回れるので。

gogsのバックアップの罠

GitLab.comでバックアップが機能してなかった事件の話を見て、まあよくある話だよね、と思ったんだ。実際に私の人生においても、周囲にいるベテランのエンジニアが機能しないバックアップによってデータロストをする、という経験が複数回あるんだよね。自分はさすがにそういうポカはやってなくて、それはそもそもバックアップしてなかったからだ、という…基本、手で作ったファイルは全部リポジトリかクラウドサービスに入れるようにしてるからね。

そんな私が、その「リポジトリに入れる」ために自宅内gitサーバとしてgogsをRaspberryPiで動かしているんだけど、gogsはgogs backupというコマンド一発でバックアップすることができる。しかし当然のようにgogs restoreコマンドはない。まあその辺はいざとなったら自分で何とかできるだろう。いつの間にかgogs importコマンドができていた。これでいけるのかな? 試してないけど。

で、リポジトリを作るたびにwebhookを設定して、pushされた時にバックアップが走るように設定してあるわけだけど、そうやって取ったバックアップはgpg -c(共有鍵)で暗号化してS3に送っているんです。共有鍵はパスワード管理ソフトとかに入れてある長いやつ。これだけ見ると玄人でしょ。

しかし、落とし穴はあった。

何かっていうと、webhookを実行しているデーモンとgogsのデーモンは別のユーザで動いていて、gogs dumpはカレントディレクトリにバックアップファイルを作るので、

cd /tmp
sudo sudo -u gogsuser /path/to/gogs dump -c /path/to/gogs/custom/conf/app.ini

みたいな感じのコマンドになっているわけだ。そして、gogsは/path/to/gogsディレクトリをカレントディレクトリにして動いているので、app.iniのDB(sqlite)の設定は相対パスになっている。

[database]
PATH     = data/gogs.db

これで何が起きるかっていうと、gogs dumpのcwdは/tmpで動いているわけだから、/tmp/data/gogs.dbをダンプしようとして失敗し、DBのダンプが取れていないという…実際に見てみると、最初のコメントの60バイトくらいしかgogs-db.sqlファイルができていなかった。ていうかそういう時はgogs dumpが失敗して欲しいんだけどな…

結局、app.iniのdatabase.PATHをフルパスで書くようにして解決した。衝撃に弱いのにケースを買わずに裸のまま運用されているRaspberryPi…ちっぽけなSDカードに託してしまっていたデータ…まあリポジトリは救えるんだろうけど、DB部分は全部飛んでてもおかしくなかったな。

このエントリを読んだエンジニアがバックアップからのリストアに成功しますように。私には今回のGitLab.comの事件によるアラートは、自分のバックアップを確認するきっかけになってくれて、ありがたかったです。

まあでも、まだリストアのやり方は試せていないんですけどねw

新事実

最近私に知られた事実があるんですけど、それを皆さんに知っっていたただきたいいので、ここでお教えしましょう。

それは、、、

冬場にジーンズが破れていると寒い

です。

いやーまじで寒い! どうしてくれる。夏場はあんなに暑かったのに。どうした太陽、もっと頑張れ。

まあ破れたジーンズで仕事しに会社に行くなよ、という話でもあるんですがね。千代田区に通う服装じゃない、という認識はあるんですが、ジーンズ冗長性を確保していなかったため、故障しても使い続けなければならず…流石にパンツ一丁はもっと寒いし…買いに行きたいとは随分前から思っているんですけれども。

JavaのDIを愛する奴にロクな奴はいない

かねがねから私はJavaのDIを信奉する人々を信じていなかったのだが、決定的なクソ仕様を発見したので、嬉々としてご報告する。

ソースがこんな感じになっているとする。パッケージが異なる同名のクラスね。

package org.abc.def;
@Component
public class Xyz extends BaseX {

package org.abc.efg;
@Component
public class Xyz extends BaseX {

これ、エラーになってプログラムは起動すらしません(ConflictingBeanDefinitionException)。component scanにゴテゴテに書けばどうにかなる可能性もあるけど、こんなんウンコでしょう。ネームスペースのことを理解していないんですよこいつら。パッケージが違ってクラス名が一緒なんてそこら中に転がってることでしょう? java.util.Optionalとcom.google.common.base.Optionalとか、タイムスタンプ系の各種DateだのTimestampだのTimeStampだのとか(すでに忘れてるけど、要するにたくさんある)。それはDIの世界では決して許されない。

何かの対象A,B,Cがあって、「作成」「削除」「更新」の操作についていろいろ書こうと思うでしょう? 操作と対象ごとに別々のクラスにして、こんな感じのパッケージ/クラスにしようと思うと。まあよくあるケースではないかと思いますが。

  作成 更新 削除
A org.abc.create.A org.abc.modify.A org.abc.remove.A
B org.abc.create.B org.abc.modify.B org.abc.remove.B
C org.abc.create.C org.abc.modify.C org.abc.remove.C

わかると思いますが、これでは動かせないんですね。ApplicationContext作る時点で落ちるから。

だいたいDI好きな奴らもクラスの差し替えなんて滅多にしない。どうせ@AutowiredするときやgetBean()するときにクラス名は一意に決まってるわけだから、ダブって判断できないケースなんてほとんどないにも関わらず、ですよ??

どうすればいいのかというと、、、

  • AやBの中にcreateやらremoveやらmodifyを入れる
    • 規模が小さければこれで通用するが、複雑になってくると困る
    • 対象が同一なだけで共通する処理がほとんどない場合、こうするメリットがない
  • CreateA, ModifyA, RemoveAみたいなクラス名にする
    • これはJavaの人が好んで使う方法で、ネームスペースを使わずに長大なシンボルやクラス名を作って満足するという、悪魔に魅入られたやり方
    • 言語仕様にパッケージ作って区別できるようにした配慮を完全無視
    • まあパッケージ自体使いにくいから私も好きではないんだけど
  • コンポーネントの引数で別の名前を書く
    • 次善の方法 
    • @Component(“blablabla”)みたいな
    • ただ無駄な記述が増えるよね。文字数で給料が出る人のための、Java的な解決方法でもある
    • @Primaryとかも効くのかな? その辺の動作はよく分かってないですが
  • DIを使わずに書く
    • これが最良な方法です
    • まあDIさえなければJavaは数倍マシになりますよ
    • Context作ってgetBean()なんて無駄な処理を書かずにnewできるようになるし、@Componentつけ忘れてcommitした奴に腹を立てることもなくなる!

下駄その後

以前に下駄を買った話を書いたけど、よくこれで散歩や買い物に行くようになっているんで、しばらく使った結果、わかったことを書いておきます。世界に下駄ユーザーが一人でも増えますように。

履き心地。これ、かなり良い。慣れると非常に快適。音、足への衝撃、視点が若干高くなり、足の指への力のかかり具合、包まれていないフリーな感覚。とにかくさわやかな、清涼感? みたいなものを感じます。

冬の寒さ。木でできた下駄は意外と温かいものです。木のぬくもりとはよく言ったもので、足の裏は靴+靴下よりも暖かいという感覚がある。冷たい地面から離れているし、木の層が厚いので、これはなるほどと思った。ただ、足の裏以外は冬場は寒いです。

頑丈さについて。まず鼻緒の裏側の結び目部分に金属でカバーが釘でつけられているのですが、これはあっという間に外れました。貫通しない短い釘は100円ショップで見つけることができなかったので、仕方ないとガムテープで止めてます。豪快w

そして、底の減り方はちょっと気になるね。砂というか小石が突き刺さってくっつくのと、歩き方の問題で、前列の外側が削れてくる。足が疲れた時に引きずり気味になっていたのが悪化を進ませたんでは、という気もした。下駄には左右の区別がないので、たまに左右を入れ替えて均等化してます。この感じだと、持って1年くらいかな、とも思える。まあやばくなったらまた買いに行こう。底を皮と金属で補強した下駄があるといいじゃないかな。←なぜかセルジオ越後みたいな口調になってますが。

モビリティについて。通勤にも使っているランニングシューズと比べるとモビリティは落ちますが、ちょっとした駆け足くらいはイケます。疾走はできません。あと靴よりも疲れるので遠出はできない感じ。急激な動きにも向きません。まあ、そんな時は下駄を脱いで裸足で走ったほうがいいです。

苦手な地形。ツルツルと下り階段は苦手です。底まで木なので、摩擦抵抗が少ないため滑りやすい。スーパーの店舗の中など、ツルツルな床というのが街には多いんだな、ということに気づかされました。そうじゃなくてもトイレに行くといきなりツルツルになる建物があったりする。こんなところで転べるかよ! 世間様においては、もっとバリアフリーに努めてほしいところ。それから、階段の下り。手すりを掴まないと怖い。高速に下ることができないため、急いで下に降りる用事がある時は下駄を履かないほうがいいです。あとぬかるんだところには行きたくないね。大事な下駄もそうだけど、足が汚れるからね。これはサンダルと同じ。なるべく濡らしたくないな、という感覚もある。

ファッション性は抜群です。まずバッタリ会った知り合いには下駄について突っ込まれますからね。子供に指さされたりもしますしね。みんなの憧れ。

MacとHomebrewとPythonの悩み

MacのHomebrewは我々のようなクリエイティブな人間にとっては必須とされるツールだ。

だが、ちょっとした悩みも生じるんですよね。

Macには最初からPythonとかが入っているんですけど、Homebrewにもpythonがある。2系と3系があって、共存できるようになっている。ただPython使ってる人はシステムに最初から入ってるPythonを使うか、pyenvで入れるだろう。pyenvで入れとけばsudoしなくても済むし、いろんなバージョンを切り替えて使える。pyenvからpypyを使ってもいいしJythonやIronPythonを使ってもいい。私も普段はpyenvで普通のCPythonを使っている。pyenv自体はHomebrewで入れている。つまり、以下の3つがあるわけだ。

  • システムのPython
  • HomebrewのPython
  • pyenvで入れたPython

pyenvはpyenvで問題はあって、やれzlibだのreadlineのヘッダがないとかで新しいバージョンのインストールがコケることが多発するのだが、それは置いておいて、問題はHomebrewのPythonだ。

ansibleやmercurialもHomebrewに入っているんだけど、こいつがHomebrewのPythonに依存しているのだ。つまりHomebrewのPythonを使わずにpyenvを使い、ansibleやmercurialはHomebrewで入れたい、と言ったことができない。pyenvならpyenvにどっぷり入って、pyenvが用意しているpipでpip install ansibleだのpip install Mercurialだのする必要があるわけ。

私はbrew update ; brew upgrade ; brew cleanupを毎日実行していて、パッケージをなるたけ最新に近い形で保っている。そこにgemだのpipだのnpmだのは入ってきてほしくないんだ。開発するモジュールに依存したpackage.jsonだのGemfileだのrequirements.txtは開発するモジュール側に入っているわけで、アップグレードして古いのを消す、みたいなのを回すとやばいと直感が俺にささやく。

だけどさ、ansibleやmercurialは最新に保ちたいんだよ!

つまり、、、

HomebrewのansibleやmercurialがシステムのPythonを使ってくれると助かるのに…

という話でした。gitの勝利が確定した今となってはmercurialを使うことは少ないけど、ansibleはマジで困る。

システムのPythonを使う場合にややこしいのは、普段使ってるPythonは3系のpyenvで入れたやつなんで、一時的にpyenv shell systemでシステムのpythonを使うようにしてから、sudo pip install …する必要があるのだが、sudoでpyenvがshellで使うPYENV_VERSIONが消えてしまうので、sudoersのenv_keepにPYENV_VERSIONを追加する必要があるのだ。それをしないと無意味にpyenv側のpipが使われてしまうんだよね。sudo -Eを使えばいいんだけど、大抵初回は忘れる。

参考リンク→https://github.com/Homebrew/legacy-homebrew/issues/29079