RubyKaigi 2016に行ってきた
RubyKaigi 2016が京都であるということで、行ってきました。 俺は京都に住んでいて、今回の会場の国際会館には行ったことはないけれど、会社とわりと近いので、行かない理由がない!
この記事は個人用のメモで、RubyKaigiってどんなところだろうとか、どんな内容が話されていたのか気になっている人には役に立ちません。時間を無駄にしたい人だけ読もう。
RubyKaigiとは
RubyKaigiはいいぞ
Ruby3 Typing
Matzの話。最近は静的型付け言語が流行っていて、動的型付けのRubyはオワコンだよねみたいな風潮が嫌なので新しいことをしたいという話。 俺はよく知らなかったので、タイプヒンティングみたいなのが入るのかなーと思っていた。
class Duck
def bake(Fire f) -> Coal
end
end
class IMac < Computer
def bake(Fire f) -> DropBox
end
end
def ahiruyaki(Duck duck) -> Coal
duck.bake
end
そもそもbakeメソッドを実装していればあひるでなくても焼けるのがDuck Typingで、型を固定するとIMacを焼くことができない。戻り値も共通のスーパクラスがない。
俺は「とはいえ想定しない型を渡されても困るから、表明したほうが良いのでは?」と以前は思っていて、だからmikutterでも type_strict というユーティリティメソッドがある。しかし長くメンテナンスを続けていって、いろんな機能拡張を行っていくにつれ、「type_strictさえなければ動くのに!」ということがしばしば発生してる。短期的には型を指定するのは一見悪くないんだけど、長く使うコードだと癌になるということを身をもって体験しているところだった。
とはいえ型がなければ、そもそも短期的に事故る、そこをどうするか。Rubyでは全ての値はオブジェクトで、全てが何らかのクラスのインスタンスなので、型=クラスと考えている時期が私にもありましたけれど、型というのは同じ振る舞いをする集団であって、クラスではない。IMacもDuckも、bakeできるという意味においては同じ型で、このことを踏まえればDuck Typingによってどんなクラスでも引数として受け取れるメソッドは、特定の型のオブジェクトのみを受け入れているにすぎないと言える、のかな。タイプヒンティングはクラスと型を取り違えていて、少なくともRubyにとってはあまりよい手ではなさそう。クラスを限定すると、不必要なものを要求してしまう。joinメソッドさえあればいいのに、Arrayであることを要求してしまうとか。過不足無く要求を明示できれば、安全且つ将来にわたって拡張性を担保できる。
MatzはGolangのインターフェイスを取り上げて、あれはかなり上手くやっている方だと言っていた。確かにあの仕組みだと、クラスではなく型自体を明確に要求できて良い。そのGolangにMatzが「おしい!」と言っていた点は確か:
という点だったと思う。「名前を決めるのはめっちゃ大変」というのはかなり同意できて、日本語だったとしても、一言で説明できないと思うことは結構多い。今のRubyではこういう検査機構は無くて、型がほしいという人が本当に意味しているのはこういった検査機構がほしいということだと思う。型を静的に書くためには名前をつける必要がある。「絶対に型は書きたくない!」というフレーズがやたらと取り上げられているけれど、俺は「型の名前を考えたくない!」というのがその真意だと受け取った。確かにロジックは頭のなかに出来上がってるのに名前で迷ってしまって手が止まるということはよくあるので、名前を考える機会を増やさずにいくらかでもその恩恵に肖ることができるなら嬉しい。
ここからは俺の知識では正確な意味を捉えかねる部分だった。今時だと俺が使った中ではPHP Stormとかは静的にコードを解析して、かなり正確に要求される型を予測して、静的にエラーとなりそうな箇所を教えてくれる。Rubyは動的にメソッドを追加・削除することができてしまうのでこれが難しい。そんな中でもJavaScriptとかはわりと頑張ってるんだけど、動的になればなるほど静的な解析には限界があるなあと思う。
しかし何らかの方法で、あるメソッドが書き換えられてないと分かってしまえば、その部分については予想できる。完全ではないが、現代のRubyでは実行時にしかわからないエラーのうちのいくつかが、実行前にわかるのではないか。100%は無理だが、8割、5割でも分かれば、今より良いよね、という趣旨のことを言っていたのだと思う。
実行前というのはコンパイル時かというとそういうわけでもないようで、Gemとかには静的解析した結果みたいなファイルをつけておいて、そのファイルがRubyランタイムやIDEから利用できれば良さそうという言及があった。これは確かTypeScriptにそんなのがあったなーと思いながら聞いていたけれど、これは実際にはぜんぜん違うものを意図しているのかもしれない。
値というのはメモリ上のビット列に過ぎず、それがどういった値なのかを説明するのが型だったが、それはコンピュータの都合だったのでなんやかんやあって動的型が流行り、しかし最近は型推論が強くなったりマシンスペックが上がってIDEがいろいろと助けてくれるとかもあって、これからは静的型が優勝なんだなあと俺は思っていた。一方Matzはもっと長い目でこの流れを見ていて、Ruby3.0が出る頃にはまた動的型付けにボールが戻って来ているかもしれない、と言っていた。刹那の流行に流されて後追いになっていくと、本当に時代遅れの言語になっていきそう。確かに他の言語と同じことをやったのでは後追いになるので、追い越していったほうが面白くなると思う。
俺は目先のことしか見ていないんだなーということがよくわかった。Rubyがこれからどうなっていくのかわからないけれど、きっとなんかいい感じになると思いました!
dRuby
この3日間めっちゃ濃かったのでまともにまとめてたらめっちゃ時間かかってしまうので以下簡単にしか書かない。
これ標準ライブラリだったの知らんかった。Rubyなんもわからん。これ使ったらmikutterプラグインを複数プロセスで動作させられるのでは…。 フィルタは普通に今でもマルチスレッドだし、どうしても同じプロセスにロードされてないといけないプラグインっていうのもあるけど、それって依存プラグインでしょ?プラグインの定義ファイルで依存プラグイン明示してるし、静的にわかるじゃん。しかもforkするみたいな感じじゃなくて、既に起動してるmikutterにattachできるし、既にサーバから起動してるmikutterにUIだけattachして使うみたいなアホなことも頑張るだけでできるのでは…。
Ruby何もわからんなと思いました。
A proposal of new concurrency model for Ruby 3
Rubyはスレッドがない時代に生まれたのでC extensionがスレッドセーフに書かれておらず、その頃から互換性があるのでマルチスレッドで動くと破滅するという認識だったので、GVLがなくなって複数スレッドが同時に動くというのは無理なんだろうなあと思っていた。
でもRuby 3ではGuildという仕組みが導入される予定らしくて、複数スレッドが同時に動くことができるようになるらしい。 Threadは(必ず?)(ひとつの?)Guildに属して、同じGuildのThreadは同時に走らないが、違うGuildであれば並列に実行しようとすると。グローバル変数とかもGuildごとに分けるらしい。まあそうじゃないとおかしなことになるわな。 確かErlangかなんかは同じプロセスに複数のVMを持てたような気がするけど、Guildはそれに近い使い勝手になるのかな。実際の実装は知らん。でもRubyはもともとThreadのことは考慮されていなかったということは、C extensionで(Cの)グローバル変数とかstatic変数とか使ってたらあかんのでは。Cなんもわからん。
今気づいたけどこのセッション英語だったのか。その割には俺ちゃんと理解してるな(全く違う理解をしている可能性もある)。日本人の英語聞き取りやすいのでは?でも日本人となら日本語で話したほうが良いと思います。英語なんもわからん。
Unifying Fixnum and Bignum into Integer
数がFixnumになったりBignumになったりしてだるかったのでIntegerだけにするぞという話。 もともとFixnumとBignumは両方ともIntegerのサブクラス。FixnumとBignumはRuby 2.4ではIntegerを指す形で残るので、互換性あるよーという話。うああ、数という意味でFixnum使ってるコード手元にあるし…。Ruby 2.4でも普通に動くけど、Integerに直しておこう。
数値なんもわからん。
Fearlessly Refactoring Legacy Ruby
リファクタリングの話。mikutterとかは、6年前といえばユニットテストとか存在すら知らなかったし、mikutterにはテストがあんまりない。それが最近は苦痛で、PluggaloidをはじめとしたGemにはある程度テストを書いている。書いているうちに成長してきて、今はPluggaloidのテストとかマジアレだなと思ってる。つらいなあ。
このセッションのキーワードは Characterization test と Suture gem、ということでいいのかな。このセッションこそどの程度理解したか自信がないんだけど、要はリファクタリング前のコードの入力に対する出力を記録して、それがリファクタリング後とちゃんと一致することを以ってコードの意味が変わってないことを検証するというのがSutureの少なくとも一機能らしい。 Suture gemは面白くて、リファクタリング前と後を両方実行するとか、最後の方は集中力切れてて微妙なんだけど、どっちを実行するかを乱数で決めたりとかしてたような気がする。Sutureについては曖昧な感じだけどマニュアルしっかりしてるっぽいし実際に使っていったらわかりが発生するかも。
レガシーなコードにはテストがないので、リファクタリングの前にテストを書いてからリファクタリングするのが定石だと思うけど、どうせレガシーなコードはミュータブルなのでテスト書けず、まずは副作用をなくしてからテストを書きたい、しかし書き換えると言ってもそもそもテストがなくてだな…となって無限再帰に陥ってどれくらいかかるか見積もりもできない。憶えがありすぎる。mikutterお前のことだよ。2010年の俺、この記事見てるか。
リファクタリングなんもわからんけど、Sutureは手札に入れておくべきだと思いました!
How to create bindings 2016
お世話になっておりますと思いました!
GIの紹介。おお、Gtk3の実装に使われているGIっちゅうのはこうなっとったのか!と思いながら聞いていたけれど、どう使うかはわかった(つもりになった)がどうなってるかはなんもわからんかった。すごいなあ。
Learn Programming Essence from Ruby patches
俺もここ半年くらいになってようやくRubyのパッチとか読むようになったんだけど、このセッションはRubyのパッチを読んで学びを得ようと言う奴だった。 俺は、Rubyはでかいのでとりあえずパッチだけちょっと見とこうと思っていたが、パッチはその変更に関連する箇所しか出てこないし、コミットメッセージでその変更の内容や理由が説明されていていいぞっておっしゃられていて、たしかになーと思いました!
Ruby Reference Manual 2016 Autumn
るりまの話。よくお世話になる〜。mikutterに関するマニュアルとかちゃんと書きたいと思っていて、そのために役立つことがないかと思って聞いた。 本来の目的という意味では特に新たに得られたものはなかったかなという感じだったんだけど、るりまとるびまって1文字しか違うやんけとか、るりまのSEOとかいう面白いワードが出てきて個人的にはとても満足した。
あれ、なんか本当に良い話だったんだけど俺の文章スッカスカだな。日本語なんもわからん。
Modern Black Mages Fighting in the Real World
TDでFluentdの0.12→0.14で、APIがアレだった部分を修正したいけど互換性ぶっ壊れる…というところで、黒魔術を使ってうまく両立してやったぜ!という話。 mikutterでもそういうところあって、何度かおさけーさんにそのことを褒めてもらって第一話の平沢唯みたいにニヤニヤしたことがあったんだけど(アへへへへヘアへへヘ)、Fluentdはmikutterみたいな悪ふざけじゃなくてちゃんとしたものだから、ちゃんと大変な思いでちゃんと黒魔術を使っていて、すごいと思いました!
個人的には、Module#prepend確かに便利そうだけどどうやって実用するのかなんもわからんなと思っていたので、その実用例が見れて最高に盛り上がった。
It's More Fun to Compute
国際会館の最強の音響をフルに使って、Rubyでいろいろ演奏していてすごいと思いました!俺もPocket mikuでmikutterの効果音再生したりしてたけど、こちらはSonic Piを使っていました。 複数トラックを演奏するのにdrubyをさらっと使っていて、優勝かよって思いました!
Optimizing Ruby
Rubyは全然最適化されていないので、まだまだ早くなる余地があるとのこと。1+1とかも、Integer#+をオーバライドできるので単純に2に置き換えることはできない。 この話で初めてdeoptimizationという言葉を聞いた。純粋なメソッドは一旦最適化してしまって、メソッドがオーバライドされて純粋でなくなったら非最適化するというアプローチで、今まで最適化できなかった1+1のような式も思い切って最適化できるらしい。なるほど定義が変わったら戻してしまえばいいということかな? 確かにこの理屈だと、Rubyだったら無理そうだなーと思っていた最適化もできるようになりそうだし、実際かなり早くなっているらしい。Ruby3は3倍早くするとか無理じゃねと思ってたけど、目標に向かって着実に高速化を進めておられて、すごいと思いました!
まとめ
ほんと話聞いてただけなのにこの三日間は滅茶苦茶疲れて、翌日は1日寝てました。
3日というのはかなり長くも感じたし短かったような気もするし、とても充実してました。たくさんおもちゃを入荷したのでしばらくは遊べそうです。フィリスのアトリエの発売延期してつらいなあと思っていたけれど、調度良かったかも。
Rubyなんもわからんなと思いました!あと、RubyKaigiはいいぞ!
MC1.10 MOBに特定のMOBを打たせる方法
teocraftのバトルドームに出現させるモンスターを作っている時に、特定の別のモンスターを攻撃するモンスターを作成したくてハマった。要するに
- エンティティを召喚する時にUUIDを指定するには、UUIDMost:とUUIDLeast:を使う
- ThrownPotionとかSnowballのownerNameに"0-0-0-0-1"のような省略形は使えなくなった。ちゃんと指定する
ということになったらしい。
MOB A(ストレイ)にMOB B(豚)を打たせる
役者を召喚
スケルトンがMOBを誤射するとターゲットを変更するのを利用して、豚にポーションを投げさせる。それがストレイに当たると、ストレイは豚に対して敵対状態になる。
/summon Pig ~ ~1 ~ {CustomName:A,CustomNameVisible:1b,UUIDMost:0,UUIDLeast:1}
/summon Skeleton ~ ~1 ~ {SkeletonType:2,CustomName:B,CustomNameVisible:1,HandItems:[{id:"minecraft:bow"},{}]}
まずMOBを召喚。この時、豚のNBTタグにUUIDMost:0,UUIDLeast:1が設定してあって、召喚された時にUUIDが00000000-0000-0000-0000-000000000001になる。
弾を召喚
雪玉かポーションを召喚し、ownerNameには投げたプレイヤーの名前を書くのが普通だが、ここでは豚のUUIDを指定する。ポイントは、ここではUUIDMost:とUUIDLeast:ではなく、1.8同様UUIDを書く必要があるということ。コンバートするスクリプトとか手元に置いておくと便利かもしれん
/execute @e[name=B] ~ ~ ~ summon ThrownPotion ~ ~1 ~ {Potion:{id:"minecraft:splash_potion",Count:1,tag:{Potion:minecraft:healing}},ownerName:"00000000-0000-0000-0000-000000000001"}
これを実行するとストレイの頭に豚から投げられた治癒ポーションが出現してストレイに当たる。そうするとストレイは豚を狙い始める。1.9からポーションの書き方が変わったので若干手こずった
弾の困った問題
こういう用途には雪玉が良くて、ダメージを与えずに喧嘩を売ることができるし巻き込みもないので扱いやすい。1.10からか、なんか投げてからしばらくクールダウンタイムみたいなのが入ったようで、出現直後の雪玉に当たり判定がないっぽい。~3あたりから落としてやると当たるんだけど、Motionタグで落下速度を早めると当たらなかった。流石に自由落下させるとMOBが移動中だと回避されてしまうのでまずい。Wiki見てもそれっぽいこと書いてないようだし、今回はSplashPotionを使った。
でもSplashPotionにも問題があって、炸裂するので隣接する関係ないモンスターも同時に敵対してしまうことと、実際にダメージを与えないと敵対しないというのがある。ダメージを与えないと、というのは結構意外だった。1.9から追加されたエフェクトなしのスプラッシュポーションなどを当てても敵対しない。また、ストレイのようなアンデッドにダメージポーションを投げても(回復するので)敵対しない。slownessのポーションは状態異常にはなるが、ダメージがないからか敵対しない。毒が有効なMOBに変えてpoisonを投げてもだめだった(ポーションに因るダメージじゃなくて、状態異常に因るダメージだからか)。そういうわけでストレイにはhealingが有効だった。
とりあえず、あしゅりーをバトルドームに出現させて何故かモンスターにリンチされているというギミックは作れるっぽい
参考
Advanced Commands Tutorial: Controlling Mobs Using Custom UUID Targets - YouTube
30秒で通勤する方法
30秒で八王子から東京まで通勤するゲーム。無理に決まってるけど意外と頑張れば手が届きそうなんだよなこれ。電車の中で走れば早くつくぞ。あほか。
ゲーム開始時は寝てる
社内を走ってる。走るのは自動で、フリックでレーンチェンジできる。3レーンあって、人を吹き飛ばしながら進んでいくのだが…
デブに当たると加速が止まる。しかもデブは2レーン消費しているから避けるのが大変。痩せろ。
女性専用車両は難関。痴漢冤罪をかけられまくって全く進めない。ふっ飛ばして進んでいる人間に痴漢というのは適切なのか。こいつも2レーン使っている。
LINEでさくっとクビになった。
説明するまでもない完璧なバカゲー。Unity 3Dに謝れ。2016年最高の滑り出しといっても言い過ぎではない。こういうのを求めていた。
アクション要素があるので難しく感じるが、何故かプレイするたびに強化ポイントが溜まっていって性能をアップグレードできるので、やってりゃそのうちクリアできるようになりそう。俺は立川までしかいけなかった。ガルパンでも見て帰るか。
中央線の駅を覚えられる効能があるという謳い文句だが、無理。
怒りゲージがMAXになると、一定時間自転車に乗り始める。その間は痴漢女やデブを吹き飛ばせる。自転車で女性専用車両を駆け抜ける快感は、これをプレイした人間にしか味わえない。iOS/Android両対応なので、是非遊ぶべき。
超新感覚!Youtuber育成ゲーム
Youtuberを育てるゲームといえば、来年のどっかにリリースされると言われている外国のやつがこの間話題になってましたが、その前にリリースされた奴がありました。もうテーマから神ゲーの風格があってやるしかないって感じですね。
チュートリアル。全てが雑。もはや説明は不要。
いきなり変質者に罵倒される。
よくこんなこと思いつくもんだ
訴えたら勝てそう
Youtuberなので動画を投稿する。初投稿だ。
ただのDQN
Youtuberも大変なんだな。
このアプリ、何故かアドレス帳へのアクセスを要求していて、無効にしてから起動したんだけど、何だったんだろう。このアプリに限らないんだけどね。シェアボタンは押したことがないんだけど、そのあたりで使う仕組みなんだろうか(調べろ)
ゲームとしてはコンセプトが俺の好みど真ん中なので、結構面白い。よくある完全無料で広告見ろ系のゲームだけど、最近のやつはUnity Adsへの誘導が凝ってるのが増えてきたと思う。このゲームだと、Youtuberは引き出しが多くないといけないからテレビを見ろみたいなことを言って動画を見るように言ってきた。
あと、このアプリ、名前は「超新感覚!Youtuber育成ゲーム」なのか「うわ…俺の再生数、低すぎ?」なのか。最初前者のほうだと思ったんだけど、調べれば調べるほどわからなくなった。そういうことを気にせずに遊ぶのがいいんだろうけど…。なんだろう。出家なうのように心を無にして楽しむことが出来ない。悟りを開くゲームと、再生数という承認欲求を追求するゲームの違いだろうか(?)
ターミナルから松屋がどんどん出てくる
10日目
--
12/5(土)未明
お腹が空きました。こういう夜は松屋のメニューを作りたいですよね。
というわけで、松屋のメニューを出力するgemを作成してしまいました。
既存の松屋のメニューに使われている文字列を一定のルールでつなぎ合わせます。また、このgemを入れると残念なことにmatsuyaコマンドを使えるようになり、コマンドライン上からいろんなメニューを作ることが出来ます。
どうやってランダムなメニューを作り出しているか
さて、この松屋gemで何回もメニューを作っていると、だんだんお腹が空いてきます。ランダムに生成しているので「ネギ塩豚カルビ丼」の部分文字列を取って「塩丼」みたいな食欲がなくなるような物が大量生産されそうなものですが、必ずといっていいほどごはんと呼べそうなものが出てきます。松屋gemは乱数ではなく、こころをこめてひとつひとつ手作りなのです。
メニューの製造工程
お客様に商品をお出しするまでには、以下の様な手順を踏みます。
- 調理フェーズ
- 具材合成フェーズ
調理フェーズ
実際に調理するにあたって、松屋の「プレミアム牛めし」を例にとって考えてみました。まず、プレミアム牛があって、めしがある、完成。このことから、松屋のメニューは調理方法から名前をつけていると考えることが出来ます。深夜3時だったのでこの理論を信じて疑わなかったんです。反省しています。
プレミアム旨辛ネギたま牛めしなども同じ理屈で説明がつきます。この2品に限っていえば、客に出すまでの皿の状態の遷移は次のような図に表すことができます。
プレミアムときたら、旨辛か牛めしに遷移します。どちらを選ぶかはランダムです。旨辛に遷移した場合は、ネギ、たまを通って最終的には牛めしにたどり着きます。beginから調理は始まって、endに辿り着けばお客様にお出しすることが出来ます。
この理屈で、一通りのメニューを打ち込んでみます。
工程ごとの依存関係が明確になりました。例えば「オリジナル」は、必ず最初にしか現れず、次にハンバーグ、カレギュウ、カレーに1:2:1の確率で遷移することがわかります。その先も、例えばハンバーグはカレーに遷移する可能性がありますが、カレギュウには遷移しないといったこともわかりますね。この辺りは松屋に詳しい皆さんなら納得できると思います。適当に矢印を辿って行ったらなんかそれっぽいメニューができるので遊んでみてください。
松屋gemはまさに、この矢印を辿って文字列を作るアプリケーションです。どおりで、存在するメニューや、ありそうなメニューが頻繁に生成されるわけです。書いてる時は気づかなかったのですが、最初のバージョンが出来たあと寝て起きたらこれマルコフ連鎖じゃねってなりました。実装したこと無いので違うかもしれませんが多分そうです。どんだけ眠かってん
マルコフ連鎖は数年前にTwitterでへんなBOTを作るのが流行ったので、まさに同じことをやった人は多いんじゃないでしょうか。今だったらdeep learningとかなんでしょうけどあれは知らん。
この手法を使ったBOTのなかで私が気に入っているものに、圧縮新聞というやつがあります。短いほうが面白いとか、いろいろと似通ったところがあります。
一応断っておくとところどころちゃんとしたマルコフ連鎖ではありません。例えばあとで言及する「具材変異」なんかがそうです。
具材合成フェーズ
これを辿って行っても作れないメニューがいくつかあります。例えば「鶏のチリソース定食」「キムカル丼」などがそれにあたります。それぞれ「鶏チリソース定食」「キムチカルビ丼」がもっとも近い答えになるでしょう。松屋初心者がよく陥る罠です。
これらを調理するには、ある隣り合った2つの素材を合成するテクニックを使用します。「鶏チリ」が「鶏のチリ」、「キムチカルビ」が「キムカル」といった感じです。
上の図を見て「+」という要素が気になった人もいると思いますが、これはミニ牛めしセットなどを表す特殊な記号です。「A + B」は「A ミニBセット」に展開されます。長いメニューを生成するテクニックとして、ネギたっぷりループ法と、セットネスト法という2つの方法が主流になりつつあります。
こういった変換を行うために今回はegisonというライブラリを使用しています。
このライブラリ面白いんですけど俺の頭ではいまいち使いドコロを見つけられない。今回の例ならString#gsubでもよかったとは思うんですが、DSLがすごくかっこよくて私は好きです。
具材変異
これだけでもまあまあ面白いメニューは出来るんですが、ビビンバに遷移したら必ず丼に遷移するなど、サンプル数が少ないため面白みに欠けます。この秩序を適度に壊すための仕組みが「具材変異」です。
調理フェーズで具材を選出するたびに具材変異の抽選が行われます。変異すると、具材の依存関係を無視して、存在する具材の中からランダムで一つ具材を選出します。更に、その次の具材は、変異後の具材の子を選出します。先のネットワーク図で言えば、ランダムな場所にワープする感じです。この仕組みによって、「牛丼」のようなメニューが出てくることがあるのです。
この具材変異の確率は、オレたちが最もリスペクトする、松屋の店員の中でもイカれた野郎と噂になっていると噂になっているおかの先生にちなんで「おかの値」と呼ばれています。あまりおかの値が高過ぎると完全なランダムと変わらなくなってくるので、標準では0.1(10%)に設定しています。
あほなものを作ったものだ。しかし…
かくして悲惨なものが出来上がったのですが、意外と毎回ありそうなメニューが出てきて、深夜だったのでセルフ飯テロになってしまいました。そこでこの苦しみをみんなに知ってもらおうと翌日にRubygemsで配布したところ、何故か一気に流行りだして、いろんな人がmatsuyaコマンドを実行しまくる大事故に発展しました。
matsuya-generator-rubyが、cowsayコマンドと組み合わせるとシュールこの上ない。 pic.twitter.com/gxaudeU377
— ぐれさん (@grethlen) 2015, 12月 6
Unix哲学を感じる。
このあとmikutterプラグインも作ったのですが、matsuyaコマンドはプラットフォームに依存せずに実行できてしまうので、私のフォロワーや、一部のやばいmikutterユーザを飛び越えていろんな人がメニューを連投するようになってしまいました。
もっと悲惨な感じにしよう
さて、これだといちいちインストールしなければいけないので流行りません。もっと敷居が下がるといいですね。
というわけで、サクっとでっち上げました。JSで書こうかとも思ったのですが、こんなの二度と書きたくないというのが正直なところだったので、毎回リクエストするようにしました。
最初DBに何か記録しようとしてPadrinoで作り始めたんですが、何かって何だよって気づいた時にはだいたい完成してて、結果消防車で花の水やりやるような大掛かりな感じになってしまいました。マジでアホだ。
最近Webエンジニアじゃないから流行がわからなくてすごく古臭くなりそうだったので、HTML5などの最新の技術をふんだんに取り入れたtotori.dip.jpを参考にして作りました。
松屋ジェネレータ画像を一枚も使ってないしサムネもへったくれもないですね。あの松屋ロゴっぽい何かはSVGですけど。
案の定多くの人がこれのせいで松屋ジェネレート沼にハマってしまって、Twitterは大変なことになりました。herokuのログがあんな速度で流れるのは初めて見たぞ
ほたせんぱいに導かれて、オリジナルカレーと牛焼肉単品と鉄皿チキングリル単品を注文。 https://t.co/D5GrKTF3ht #松屋ジェネレータ #matsuyanow pic.twitter.com/brhd33hfgS
— JC(除毛クリーム)さん (575松屋) (@okano_t) 2015, 12月 8
生成された謎メニューを再現するネクロマンサーも現れました。
サードパーティアプリケーションも出てきました。
本家(?)ライブラリのほうも既に執筆時点で11回のリリースを経てバージョン0.2.3がリリースされており、私の他に2人がpull-reqを送ってくださるなど、かなり活発です。
やっぱりこういうのにハマる人間はアホで、mikutterユーザもアホなので、結果としてmikutter全体の進化が数日間止まるという甚大な被害が出ました。あとソフィーのアトリエもやってません。マジでアホだ。
感想
虚無感が凄い。これが報いだというのか。どこをとってもどうでもいいことしかない。
しかし書いているときはめっちゃ楽しかったです。楽しかったなぁ…
ばかたれ
ばかたれ
以上
おまけ
きょうは おやすみなので ソフィーのアトリエをするぷに!このゲームはぷにが出てくるからあしゅりーおじさんもすき
たたかう
ぷにを召喚するぷに
モニカちゃんのぷにぷに玉^q^
ぷ煮汁!
くさそう
ドイツのトリ!
これもトリ
疲れたからアトリエに帰るぷに
ドイツのトリ帽子をかぶった女の子が訪ねてきた
ドイツのトリアドベントカレンダーではドイツのトリを使った作品を発表するといいらしい。早速錬金術でつくろう
シュタルメタルが足りないぷに。こっちからつくろう
ど、ドイツのトリ!!!(腐りかけ)
ぷにぷに弾を作るぷに
マイクラと同じで、クラフティングテーブルに素材を載せるだけ、かんたん!(なんか穴あいてるけど)
†良さ†
!!?!????!?!?!?!??!!!!?????wwwwwwww
なんだこの見た目…
ぷにによく効く(一撃必殺(つよい(確信)))
恐ろしい物を作ってしまった…
つかってみる
!?
はげしい
おかしもつくった
ドイツのトリにも見える