僕は、スイカという果物が苦手だ。
タイトルの通りである。僕はスイカという食べ物が苦手だ。 確かに食ったら美味い。甘いし、塩味を付けると尚更だ。
食うと美味いのは知ってる。でも最後には、皮のあたりの味のない部分を食う事になる。
人は面白いもので、第一印象が肝心という割に、記憶に残るのは最後の印象なのだ。
僕はスイカが嫌いだ。そして、故に人も苦手だ。これは今後も変わらない。 そして私自身も、そういった理由で良い印象を持たれていないかもしれない。後味を良くする努力なんてするつもりないしね。人生は短いのだ。自分のリソースは、最大限自分の思うべき事に注ぐべきなのだ。人との関係性を取り繕うリソースなどない。人なんてそんなもん。後味気にしてられるか。
これが持論、そして行動原則だ。
これは何があっても変わらない。変えるつもりも無い。
人にも押しつけない。だから人の後味も気にしない。
そしてもう一つ、私の人生観に一つ大きな影響を及ぼした物がある。 それは、「違和感には必ず原因がある。注意深くそれを探し続ける事」そして「自分の納得」という事の尊さを教えてくれた、古い友人の死だ。
これからするのは、そんな話。
生きてりゃ起きる、そんな話。
Web Music ハッカソン#3に実は行ってたって話。
またハッカソンいかへん?という話はエンジニアの松尾君(通称niuやん)と度々話をしていたものの、なかなか都合がつく良いイベントが見つからず...と、そんなときに出会ったのが、このWeb Music Hackathonでした。
しかも会場は情報産業界の憧れとも言えるGoogleの日本オフィス。行くっきゃない!
と、最近の話のようにいってますが、実はこれ9月の話ですorz でもこれを書かないで、次のハッカソンには行けないしね!
アイデア
いうまでもない話としてハッカソンは当日作ってなんぼなイベントである故、当日何が(APIとか、ガジェットとか)用意されているか?でやはり本番作るものは決めたいところですが、この辺は前回同様に松尾さんとのアイデア出しをあらかじめ行いました。
事前にある程度公開されていた機材類の他に意表をつく飛び道具が出てくることは幸い無かったので、事前ブリーフィングでのアイデアをほぼそのまま持ち出すことになります。。
アイデア出し
- WebAudio APIとWeb MIDI APIを使いたい。
- 「そういやGetUserMediaでマイクの音ひろって、スペアナ表示してるデモ見たことある。」
- 「WebMIDIあればポケットミクとかさくっと使えますな。」
- 何かしらの飛び道具を持ち込みたい。
上記のアイデア出しから、以下のようにまとまっていきます。
オーディオケーブル1本でMIDI化できるとしたら、
それはクールと呼べるのではないだろうか?
それが、今回の「オタマトーンをPCのライン入力に繋ぐだけで、MIDI化されるWebアプリケーション」です。非常にシンプル、そして誰の目に見てもクールです。多分。
が!
このアイデア、俺のやる事があんまりないんですよね....
そんなわけで、スマートフォン用UIを作るという私の仕事の創出を目的とした機能が付いたわけです。
開発
実行環境
- node-Webkit (サーバー実行環境)
- GoogleChrome (音響周りの処理)
なぜnode.jsではなくnode-webkitだったのか
node-webkitとは、簡単に言うとChromiumの中に入ってるJavaScriptエンジン(V8)を、同じV8派生であるnode.jsに置き換えた奇跡の融合物です。しかも1つのパッケージに纏めて、あたかも単体のアプリケーションのように振る舞うことも出来ます。
我々はデモマシンにnode.jsをインストールしたり、などの手間がないので単なるnodeなアプリケーションの実行にも使う事がありますが、今回の最大の目的は、WebMIDIやピッチ解析をnode-webkit内蔵のWebkitで行えば、アプリケーションを立ち上げて、そのアプリケーションが提供するWebサーバーにスマートフォンで繋ぎに掛かればスマートじゃん!という発想からでした。
まあ肝心のWebMIDI周りの実装が今のChromeに追いついていない事もあったので、結局node-webkit内での実行をあっさり諦めて単なるWeb+socket.ioなサーバーとなったのですが、単なるnode.jsでの実行としなかった理由はこういった経緯があったためです。(まあ動かせなくもなかったんでしょうが、その辺のスマートさよりも一通り動く事を優先する必要がありましたし、確実な方法を取ったと)
UI周り
ぶっちゃけ処理周りは専門外なので書いた奴のエントリー読んで頂くとして、私は前述の通りデザイナなので、スマートフォン上で展開されるUIを書いていました。
タイトルバーに出ていたYAYANEは、kirinsan.orgの名誉総教祖であるヤヤネヒロコ神からいただいています。(こう書くといつも本人に怒られるんですけどね!)
UIとエンジン部は前述の通りSocket.io越しで叩いています。この構造、まるでフォトカプラ越しにやり取りをするMIDIのような感じで素敵じゃん?とよく判らない事を考えて居たのですが、意外とこういう開発をするときにUIと内部の処理を切り分ける手法としては有りなのかもしれません。(ケースバイケースですし、ローカルで完結するようなもんであればはっきりいってお行儀は良くないですが)
感覚を与えるUI
ダイレクトな反応は、学習性の高いUIに必須だと思っています。そのため、今どの音なのか?ということの表示の仕方は、入力デバイスとしてのオタマトーンを扱う上での「感覚」を養うために非常に重要だと考えました。
これが、画面レイアウトの一番目立つ箇所に検出したノートを表示するようにした根拠です。
アニメーションの持つ情報
ピッチ変化はリニアな移動、もしくは時間と変化の2軸グラフで表現できるでしょう。ギターのチューナのようなものも考えましたが、今回は文字が上下に移動して切り替わるシンプルな物としました。ダイレクトに結果をきびきびかえても良いんでしょうが、変化に合わせてアニメーションするのは、自分の行動がどういう結果をもたらしているのか?を体感出来るようにする意図があります。
このあたりはほんとはもっと精密な制御をするべきなのかもしれませんが、シンプルにCSSのみでおこなっています。
プレゼンテーション
幸いな事に今回は日本語話者が中心だったため、プレゼンテーションは素直に日本語で行いました。
例によってゲラゲラ騒がしく作業していた事と、割と周りになにをやっているか理解されていた感があったものの、オタマトーンから銃声がするというだけで笑いが取れるのはなかなかに爽快です。芸人冥利に尽きます。
正直あとから見直すと不手際が目立つのも確かなので、このあたりどれだけスムーズに見せるか?は本当に以降気を付けたいところ。
反省点
- 事前にある程度スライドで準備しておけるところは準備しておこう...俺。
- 落ち着いて話そう、俺。
- 2人ともgitによるチームでの作業に不慣れ故Dropboxの共有で済ませてたので、次回からはちゃんとやろう、俺。
- 食わず嫌いせずにそろそろ生産性向上に強めよう。Scss使えよ、俺。
- 音色のプリセットの組み替えとショートカットボタンの実装はやりたかった。正直デモの時にそのあたり非常に無様だと自分で思ってしまったので、どうにかしないとな、俺。
終わってみて
まあ改めてこう思い返すと、我々kirinsan.orgの良い点は、目標設定が上手く行ってるという点かもしれないと思いました。作りたいと思った完成形になんだかんだ到達出来てますからね。実はこれって結構難しい事なんでないかな?と思う訳です。
そして我々2人のもう一つの良い点としては、「お互いを笑わせに掛かってる」という点かもしれません。
今回なかなかカルチャーショックだったのは、Chromeの中の人たちから日々変わるWebMIDIの実装、そして変わった結果、で、必要あらばできたてのビルドまで用意しているというまさに最前線の方々がそこにいたという点。これ感動でした。
そして肝心の結果は、総合3位!ありがとうございます。Tシャツもらっていきました。壁に飾ってます。
次回はもう明日に迫ったTechCrunch Tokyo Hackathon 2014です。正直まだなにをするのか、今まで以上に見当も付きませんが、今度も変わらずのスタンスで、kirinsan.orgらしい事が出来れば良いですね。
JIRAとかStashとかConfluenceとか突っ込んでみた時のメモ
殆ど自分用メモですが、実際に使ってるの見せられたこともあり、自分で試してみようとAtlassianのConfluence,JIRA Agile,StashをさくらたんのVPSに導入してみた時の注意点をば。 切っ掛けは某所でタスク管理に使うのにJIRA Agileがよさげだなぁ、と思ったのと、個人的に使ってみたかったので、10クライアントのライセンスがお安かったことを良いことにまずは自分で使ってみる事にした次第です。
前提
- 私はLinuxを言うほどしりまへん。
- すぐWebminに頼りたくなる系男子
- もっと言えば、バグトラッカーの類使うのもコレが初
環境
- みんな大好きさくらたん(さくらインターネット)のVPS。プロジェクトをいろいろ突っ込む事考えて少々ストレージに余裕が欲しいこともあるので、2Gプランにしてみました。
- 実は別に借りてる1Gプランの環境では先にJIRAを突っ込んでみた地点で妙に遅かったのもあり、多分全般的にそれなりにヘビーなものなのではないかと思う。
- OSは標準のCentOS。先項で試した1GプランはUbuntuだったけど、まあCentOS触ったことないし、良い機会だと思って。
引っかかったりした点
- 本質的には関係ないと思うんだけども、ConfluenceにしてもStashにしても、ユーザー管理をJIRAから引き継げるので、なににしてもとりあえずJIRAから準備するとスッキリできるっぽい。
- DBは後から簡単に移行できるっていってもやっぱり面倒なので、最初から素直にPostgreSQLで構築するのが吉。
- CentOS由来の問題として、yumで入るGitは古いままなので、Gitは自分でmakeする必要アリ。
- インストーラーで突っ込んだ場合は勝手にTomcat突っ込んで、各アプリケーション毎に環境作ってくれるんですが、コンソール用の管理ツール(config.sh)がOpenJavaだとスネるので、素直にOracleのJavaSEを突っ込む必要がある。
- ConfluenceはDBをUTF8で作らないと怒られた。
- 実際使うわけでないにしろ、非推奨の内蔵DBはインメモリ型故か、こっちで動作させてると少ないメモリのVPSが一気に亀化した。
と書くとたったこれだけなんですが、まあ何度かポカをしつつもどうにか3アプリケーションともに動くようになりました。
まあまだ善し悪しが分かるほど使っていないので、使ってみての感想はまた今度ということで。
退職エントリーからのどうしてこうなった。
前回の退職ポストから半年。なぜか無職になってからの方が忙しくなるという不思議現象に頭を抱えつつも、無職ライフをそれなりにエンジョイし、外でプレゼンする機会の度に「こんにちわ、無職です!」と挨拶する自分をどこか楽しんでいた半年。
あまりに無職無職連呼するせいでわざわざ仕事を作ってくれるクライアントの皆様には本当に頭が下がる思いでしたが、なんだかんだで食えてしまっている自分というこれ以上ない自信を与えてくれたのは他ならぬ皆様です。改めてこの場で感謝申し上げます。
ええ、その通り。
無職終了ポストです。
Web業界での実務経験がないだけに1度でもそういった実務経験が欲しいのもあり、職探しをしたいなと思っていた事が理由Aだった筈なのですが、じゃあ何故半年も無職をしていたかと言えば、先述通り「思いのほか仕事が貰えてしまった」というのが最大の理由で、何だかんだでホソボソと食いつなぎながらハッカソンにでたり(この辺また書きます)、久々にバイク触ったり、まあいろいろしてたわけです。
そんなこんな重い腰を上げて当初の目的通りバイト探すかぁ、といろいろ調べていた矢先に丁度連絡があったのです。
(注:あくまで当方フリーランスをやめるつもりが無いため、基本的にはバイトになるのです)
古巣から。
有休消化に1.5ヶ月掛かってたので契約上の離職から4ヶ月少々、前職からなにやらメールが飛んできていたのでちょっと話を聞きに行ってきました。まあ話は予想通りの「もう一度来ませんか?」だったので、素直に離職の経緯と現在の状態を話して、その上でこちらから条件を色々提示してその日はとりあえず帰ってきました。
上場企業らしい理由で「評価」に非常に腑に落ちない部分が大きかったことと、自分の時間を確保しないと次のステップに進めないこともあった故の離職、流石に前と同じ状態では受けれない事を強調したのは勿論ですが、後日まるでかぐや姫のワガママを書き記したような要求のうち半数以上がクリアされ、多くの特例を得た事もあり、素直に首を縦に振ることと相成りました。
結果としてかつて離職したときの不満を離職したことで勝ち取った格好です。まあここまで譲歩されると私としてもNoと突っぱねる理由はありません。
会社との契約が変わったこともあり非常に「お上に楯突きやすくなった」こともあり、今度こそは多くを変えていけると確信が持てています。ええ、よく判らない理由で変えることが許されなかった多くを、私の手で正すチャンスを得れたのです。素晴らしいですね!
そんなわけで、また会社員っぽい格好することにもなりますが、基本的にはフリーランスです。 この復職にあたって、複数のクライアント様のご理解を求める事になりましたが、快く承諾をいただけた事に改めて感謝。
まあなんとか上手くやってきます。
JavaScriptのifのとか()の知らなかった話
事の切っ掛け
事の始まりはこれ。とあるコードをOnline YUI Compressorに通そうとしたときに新しいツールを紹介されたので、そっちに通して見たときの事。ちなみにそっちの圧縮サービスはこれ。-> Refresh-SF - Online JavaScript and CSS Compressor
if(a=="foo"||b=="bar") console.log("Bazinga!");
たとえばこんな箇所が、以下のようにされていた。
("foo"==a||"bar"==b)&&console.log("Bazinga!");
この結果を見て不思議に思ったのでconsoleでちょこちょこ触ってみたところ「ぁー成る程、こう書けるのか」と妙に納得した。
一行ifを&&で代用する?
このカラクリは、&&は左側の値がfalseの地点で評価を進めないという事故。従って、左側の中身の括弧内の評価がそもそもtrueにならない限り&&右側の関数の戻り値を評価しない為、結果として関数も呼び出されない、という事のよう。
ではこのminifyツールで同じく今度は普通の{}囲みのif文を与えたらどうなるのか試してみた。
if("foo"==a){
console.log("Bazinga!");
console.log("Bazinga,again!");
}
"foo"==a&&(console.log("Bazinga!"),console.log("Bazinga,again!")));
こうしたら無名関数で囲まれるのかな、と思ったら違った。
勿論私のようなヘッポコの想像したとおり、無名関数にしても通る。
"foo"==a&&(function(){
console.log("Bazinga!");
console.log("Bazinga,again!");
})();
この何もないところの()のカンマ区切りがホントの所どういう意味なのか? この辺についてそもそもどうしらべたものか分からないので適当にコンソールでつついていると、以下のようになるのが分かった。
- ()とは、直前に指定されているfunctionオブジェクトに引数を渡すためのものである。
- なにも指定されていない場合の()は、functionに渡している時同様引数の評価を行う。
- その場合の戻り値は、一番最後の引数の結果が戻ってくる。
例えば、何気なく即時関数を以下のように書いているけど、これは最初の()にfunctionオブジェクトを渡して評価する事で戻り値にそのまま戻ってくるfunctionに引数を渡す()を与える事で関数として実行される、という流れが見えてくる。
(function(){ console.log("bazinga!");})()
ここまで来るとなぜfunction(){}を()で囲むのか、とかが何となく見えてくる。
要するに、単なる()は関数への引数としての処理と同様に中身が評価され、その末端の結果が戻り値である為、それは変数の中身に収めた関数の参照と等価であり、()を付ける事でそれが関数として実行される、という事か。成る程、納得した。
(function(){ console.log("ready?");},function(){ console.log("bazinga!");})()
// >bazinga!
故に無意味ではあるがこういう事も出来るわけだ。
面白い。何気なく使ってたコード中の()だったり、即時関数の理屈がなんかかなりスッキリ理解出来た気がする。
三項演算子とかboolとかの扱い
そしてもう1箇所。実は某お題の解答を書いていたときのコードを試しに同じようにminifyしてみた時の結果。処理は1桁の素数かどうかの判定をするだけの関数。
//Original
function isPrime(a){
if (a%2==0||a%3==0||a%5==0||a%7==0) return true;
return false;
}
//Minified
function isPrime(r){return r%2==0||r%3==0||r%5==0||r%7==0?!0:!1}
//あれ?もしかしてこれでよくね?
function isPrime(r){return r%2&&r%3&&r%5&&r%7?!1:!0}
まずはそもそも 三項演算子を使えばスマートでしたね....と。ハズカチ。問題はその後の式。true,falseじゃなく0,1の否定を行ってる。これはなるほどなーと思った。確かにこうすれば確実に動作出来る上に、true,falseと書くより遥かに少ない文字数でスッキリ書ける。
false === false //true
false == 0 //true
false === 0 //false
false === !1 //true
false == !1 //true
でもこれ1度否定で評価する故処理コストとしては増えそうな気がしないでもないけど、その辺はベンチしても微々たるさしか出てこない気も。実際の所はよくわからんです。(ベンチしろ?ごもっとも) 少なくとも単に0を渡すのは厳密比較をパスしないので×。
その点言えばこの方法は非常にスマート。ただこの記法が可読性に繋がるか?というと正直全く逆行はしてるとは思う。1バイトでも小さくする事を求められているときに有用はのは確かだけども。 ちなみに文字数は変わらないものの、こういう書き方も出来ますな。
function isPrime(r){return !(r%2)||!(r%3)||!(r%5)||!(r%7)?!0:!1}
個人的にはこの書き方好き。これも応用ですな。0との比較なので、そのまま%したときに戻ってくる数値を!で否定してしまい、0ならtrueになる....とここまで書いていて気づきました。
function isPrime(r){return r%2&&r%3&&r%5&&r%7?!1:!0}
0をtrueとして、trueが最低1つという条件なのであれば、別にfalseの存在が1つでもあればパスできなくなる&&で結んでしまえば良い。結果は反転してしまうけど、それは結果の処理の中身を反転してしまえば良いだけ。じゃこう書けばいいぢゃん!すっげー!可読性なんてクソ食らえ! オリジナルと改行抜きで30バイト短いし、無駄な評価(0を否定、とか)が減った分理屈上でも処理がシンプルになった筈。読みにくいけど、得体の知れ無さがアップして好み。
そんなわけで、minifyツールに色々気づかされた次第。まだまだ知らない事だらけだけど、JavaScriptは面白いですね。
Macのクリーンインストールで躓くなど。
メンテナンスの容易さが売りのMacですが...
まあ主題の通りです。おもっくそ躓きました。ちなみに状況は
- 15インチ MacBook ProのEarly 2011 (RAM16GB化、2SSD化改造)
- 暫く常時商用電源運用だった故に、バッテリーは死亡
- あまりにホイールがグルグル回る故に再インストールをして環境再構築を決意。
何で躓いたかというと、まさかの「ハードウェア的に特に問題なさそうなのに、いろんなパティーンでOSをインストールさせてくれない」という聞くからに面倒なトラブル。
とりあえずレッツ再インストール。
まあ今時のMacをお使いであれば、そもそもリカバリディスクなるものが存在しないのはご存じでしょう。例によってPowerキーを押してすぐOption(⌥)キーを長押しでブート領域を切り替えれるので、さくっとレスキュー領域から起動しましょう........
と思ったらこれです。
工工エエェェ(゚д゚; )ェェエエ工工
たまったもんじゃねえです。起動しやがりません。
さあもうこれでお終いかと思いきや、Macはそんなときでも大丈夫。起動ディスクの選択時に無線LANのアクセスポイントを設定すると、Appleのサーバーから直にブートイメージをダウンロードして起動してくれます。なんとも未来的じゃないですか。SSDを差し替えて真っ新なドライブとかにしちゃっても安心って事ですよ。
これで無事起動、インストーラーが立ち上がり.....あれ、Snow Leopard? Lion? ブートイメージとしてはSnow Leopardだけど、立ち上がるインストーラーはLion....なんか変ですね。まあそのまま先に進んでみると...
適格性の確認の段階でコケて、この表示。こまったもんですね...
the 手詰まり。
といってもまあ差し支えのない状態。こいつに付いてたLeopardのリカバリディスクなんてとっくの昔に捨ててますし...
PRAM周りか?だとしたら怪しいのはバッテリーが死んでる事なので、素直にバッテリーを交換する事にします。1.4万円ぐらい。まあしゃーないです。
というわけで交換して再トライ。
.......変化ナシ!
では今度は、手元のiMacでMavericksをダウンロードし、その中身のDMGをUSBメモリに書き出して、そこからブートしてみましょう。
なんでよ。MacBook Airだと普通に起動するのに。
内心ここでメモリモジュール周りとか、あるいは今まで遭遇したことのない対処のしようのない故障なのではないかとビクビクしてきたのですが、思い切って最後の手段を使う事にしました。
結局最後の頼みの綱は、ターゲットディスクモード。
Powerキーで電源投入後、Tキーを長押しする事で、MacはOSのブートではなくターゲットディスクモードなるモードに切り替わります。このマシンだと、FireWireとThunderboltのマークがスクリーンセーバーとして現れます。
実はこのモードで起動する事により、Macが単なる外付けHDDドライブとして機能します。この機能を使い、MacBook AirをターゲットディスクにしてiMacをAir上のディスクからブートさせる、といった離れ業も出来ます。
ここまで言えばもうお分かりですね?そう、MacBook AirとThunderboltケーブルで接続して、MacBook AirでOSをインストールしてしまうという手です。
とりあえずはOSのインストーラーは普段見慣れている通りに進みました。インストールが完了すると普通にMacBook Airが真っ新の環境で立ち上がりますが、電源を落としてThunderboltを引っこ抜けばまた内蔵のドライブからブートします。
これでMacBook Proを再起動してブートすれば大成功なのですが.....
上手く行きました!
地味にESDからの再インストールって鬼門なんだろうか
自分以外でこの症状にぶちあたっている人を見つけられなかったのですが、正直ちょっと面倒です。Macが複数台あれば簡単に解決できる問題ではあるものの、そうでなければなかなか絶望的ですからね。
まあなんてことない、困ったときにはこう言う事も出来ますよ、ということで一つ。
しかしこの不具合、Appleに報告したい一件なんですが、どこで言えば良いんですかね。
職場を離れて、フリーランス一本に戻りマスタ。
喧嘩して出て行くか、アホくさくなって行かなくなったとか、契約更新の書類を終了日に持ってこなかったことを良い事に出社を辞めたりと繰り返してやれ数度、まともに会社に座っていた試しがないワタクスが、ようやっとふつうに働くという経験をした職場が、つい昨日までの職場。
はい、そんなわけで1ヶ月ぶりのエントリは、やってみたかった事の一つ、退職ポストでございます。
元々某師匠の紹介3ヶ月ほどの予定でヘルプとして入った某大手旅行会社。仕事はWebサイトのメンテナンス要員。気がつけば足かけ4年。契約社員という話はフリーの仕事を手放すつもりが無かった故バイトにしたのでだったので、かっこつけようが社会的にはフリーターだったわけですが、職場といえる場所は思えばここが始めてだったんだなぁ、としみじみ思う次第でございます。
いつかは離れてまた集中して自分の仕事をする時間を作る必要がある、とは思っていたので、その時になったということです。自信が無いと、曲がりなりにも安定している払いと社保をくれる職を離れるのはやはり躊躇があるもの。これは日頃お世話になっている仕事仲間とクライアントの皆様が、私にその自信を与えてくれたからに他ならない。
そして、同時にここまで仕事をさせてくれていた会社に改めて感謝を。最終日、今までお世話になりましたという言葉と共に改めて、今後はOrange Designworks [ow;d]としてのよろしくお願いしますとお伝えし、ちょっと遅めに退社をした。
自分の残したコードと、今後に向けての諸々が良い方向に向かってくれることを祈るばかり。
さ、今日からはまた身一つで稼ぐ生活だ。頑張るぞ!
いえーい無職!欲しいもの並べといたから、買ってくれても良いよ!!! そのままポチれば俺に直行だ!まったく、テクノロジーは最高だぜ!!!!