かしこくもなりたいし、女の子にもなりたかった。

とってもガーリーなゆるふわ愛され何でも屋を目指す、30代男性がお送りするファビュラスなブログ。

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アプリケーションともに動くようになりました。

まあまだ善し悪しが分かるほど使っていないので、使ってみての感想はまた今度ということで。

退職エントリーからのどうしてこうなった。

f:id:takustaqu:20141017000711p:plain

前回の退職ポストから半年。なぜか無職になってからの方が忙しくなるという不思議現象に頭を抱えつつも、無職ライフをそれなりにエンジョイし、外でプレゼンする機会の度に「こんにちわ、無職です!」と挨拶する自分をどこか楽しんでいた半年。

あまりに無職無職連呼するせいでわざわざ仕事を作ってくれるクライアントの皆様には本当に頭が下がる思いでしたが、なんだかんだで食えてしまっている自分というこれ以上ない自信を与えてくれたのは他ならぬ皆様です。改めてこの場で感謝申し上げます。

ええ、その通り。
無職終了ポストです。

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(⌥)キーを長押しでブート領域を切り替えれるので、さくっとレスキュー領域から起動しましょう........

と思ったらこれです。

f:id:takustaqu:20140525210438j:plain

工工エエェェ(゚д゚; )ェェエエ工工

たまったもんじゃねえです。起動しやがりません。

さあもうこれでお終いかと思いきや、Macはそんなときでも大丈夫。起動ディスクの選択時に無線LANのアクセスポイントを設定すると、Appleのサーバーから直にブートイメージをダウンロードして起動してくれます。なんとも未来的じゃないですか。SSDを差し替えて真っ新なドライブとかにしちゃっても安心って事ですよ。

これで無事起動、インストーラーが立ち上がり.....あれ、Snow Leopard? Lion? ブートイメージとしてはSnow Leopardだけど、立ち上がるインストーラーはLion....なんか変ですね。まあそのまま先に進んでみると...

適格性の確認の段階でコケて、この表示。こまったもんですね...

f:id:takustaqu:20140526010142j:plain

the 手詰まり。

といってもまあ差し支えのない状態。こいつに付いてたLeopardのリカバリディスクなんてとっくの昔に捨ててますし...

PRAM周りか?だとしたら怪しいのはバッテリーが死んでる事なので、素直にバッテリーを交換する事にします。1.4万円ぐらい。まあしゃーないです。

というわけで交換して再トライ。

.......変化ナシ!

では今度は、手元のiMacでMavericksをダウンロードし、その中身のDMGUSBメモリに書き出して、そこからブートしてみましょう。

f:id:takustaqu:20140525210522j:plain

なんでよ。MacBook Airだと普通に起動するのに。

内心ここでメモリモジュール周りとか、あるいは今まで遭遇したことのない対処のしようのない故障なのではないかとビクビクしてきたのですが、思い切って最後の手段を使う事にしました。

結局最後の頼みの綱は、ターゲットディスクモード。

Powerキーで電源投入後、Tキーを長押しする事で、MacはOSのブートではなくターゲットディスクモードなるモードに切り替わります。このマシンだと、FireWireとThunderboltのマークがスクリーンセーバーとして現れます。

実はこのモードで起動する事により、Macが単なる外付けHDDドライブとして機能します。この機能を使い、MacBook AirをターゲットディスクにしてiMacAir上のディスクからブートさせる、といった離れ業も出来ます。

f:id:takustaqu:20140525210628j:plain

ここまで言えばもうお分かりですね?そう、MacBook AirとThunderboltケーブルで接続して、MacBook AirでOSをインストールしてしまうという手です。

とりあえずはOSのインストーラーは普段見慣れている通りに進みました。インストールが完了すると普通にMacBook Airが真っ新の環境で立ち上がりますが、電源を落としてThunderboltを引っこ抜けばまた内蔵のドライブからブートします。

これでMacBook Proを再起動してブートすれば大成功なのですが.....

上手く行きました!

地味にESDからの再インストールって鬼門なんだろうか

自分以外でこの症状にぶちあたっている人を見つけられなかったのですが、正直ちょっと面倒です。Mac複数台あれば簡単に解決できる問題ではあるものの、そうでなければなかなか絶望的ですからね。

まあなんてことない、困ったときにはこう言う事も出来ますよ、ということで一つ。

しかしこの不具合、Appleに報告したい一件なんですが、どこで言えば良いんですかね。

職場を離れて、フリーランス一本に戻りマスタ。

喧嘩して出て行くか、アホくさくなって行かなくなったとか、契約更新の書類を終了日に持ってこなかったことを良い事に出社を辞めたりと繰り返してやれ数度、まともに会社に座っていた試しがないワタクスが、ようやっとふつうに働くという経験をした職場が、つい昨日までの職場。

はい、そんなわけで1ヶ月ぶりのエントリは、やってみたかった事の一つ、退職ポストでございます。

元々某師匠の紹介3ヶ月ほどの予定でヘルプとして入った某大手旅行会社。仕事はWebサイトのメンテナンス要員。気がつけば足かけ4年。契約社員という話はフリーの仕事を手放すつもりが無かった故バイトにしたのでだったので、かっこつけようが社会的にはフリーターだったわけですが、職場といえる場所は思えばここが始めてだったんだなぁ、としみじみ思う次第でございます。

いつかは離れてまた集中して自分の仕事をする時間を作る必要がある、とは思っていたので、その時になったということです。自信が無いと、曲がりなりにも安定している払いと社保をくれる職を離れるのはやはり躊躇があるもの。これは日頃お世話になっている仕事仲間とクライアントの皆様が、私にその自信を与えてくれたからに他ならない。

そして、同時にここまで仕事をさせてくれていた会社に改めて感謝を。最終日、今までお世話になりましたという言葉と共に改めて、今後はOrange Designworks [ow;d]としてのよろしくお願いしますとお伝えし、ちょっと遅めに退社をした。

自分の残したコードと、今後に向けての諸々が良い方向に向かってくれることを祈るばかり。

さ、今日からはまた身一つで稼ぐ生活だ。頑張るぞ!

いえーい無職!欲しいもの並べといたから、買ってくれても良いよ!!! そのままポチれば俺に直行だ!まったく、テクノロジーは最高だぜ!!!!

多階層かつ親参照も出来るprototypeなサムシングを書く旅

まあほとんど自分用メモなエントリで申し訳ないですが、ここ最近俺の中で最もホットかついまさらなprototypeな話。

例えば、以下のようなコードがあったとする。

var Foo = function(){
    this.prop = "test string"
}

Foo.prototype.foofoo = function(){
    console.log("this:",this)
}

まあ当然、このコンストラクタでオブジェクトを作ると中身はこうなる。

{prop: "test string", foofoo: function}

で、ここの下にprototypeでまたいろいろぶら下げるとなると、出来れば関数を階層構造にしたいと思うわけです。まあある意味予想していたものの、実はやり方があるんじゃないか?とJavaScriptのthisの親参照はどうやら出来ない事が師匠2人の答えからも分かったので、最終的にどうしたかをば。

var Foo = function(){
    this.prop = "test string"
    this.bar = new Bar(this);
}

Foo.prototype.foofoo = function(){
    console.log("this:",this)
}

var Bar = function(arg){
    this.parent = arg
}

Bar.prototype = {
    kirin:function(){ console.log(this.parent) },
    zo:function(){}
}


var foo = new Foo();

結局のところ、コンストラクタの下にぶら下がるprototypeを多階層化しつつ、そこにさらに親参照を付けようとすると、コンストラクタ内でその子要素のコンストラクタを呼び出し、そいつの中に親要素を保持させる(ここであれば、引数としてthisを渡し、子要素の中のparentの中に代入する)必要があるっぽい。

あまりこの方法で深い階層を作る気はないものの、出来れば同じ接頭辞の関数を乱立させるぐらいならオブジェクトの中にネストした方が見た目的にも理解しやすいなーという事があり、先にこの辺を試してみた次第。

prototypeにオブジェクトリテラルで渡す事の善し悪しはともかく、この書き方は個人的には今のところ書きやすい&保守しやすい。

沖縄の師匠にこの辺の話を深く考えさせすぎてしまった感はあるものの、もっとナイスな解決が出てきそうな予感なので、出てきたらそっちも試そう。

WebAudio APIで効果音ならすライブラリを作ろう。

f:id:takustaqu:20140321133838j:plain

さて、ずいぶん大げさな書き出しになってしまいましたが、iOSのWebAudioAPI対応は、それぐらい素晴らしいものなのです。

何気に Audioタグを試した方はご存じかもしれませんが、audioタグは必ず1度クリックやタップのイベントで発火させないと音が鳴らないというスマートフォン特有の制約がございまして、これのために無意味な連打などをさせるWebアプリケーションが御座いました。

そこに現れたWebAudio APIスマートフォンでもこのような制約に掛からず、また同時にiOSのaudioタグが同時発声できないという制約にも縛られません。つまり、効果音ならしまくりって事なワケです。

boombox.jsでWebAudioAPIの素晴らしさを体感したものの、ちょっと自分の使い道だと不便なので、自分で使いやすいように出来るように自分なりに書いてみました。

動くサンプルはここに置いてあります

ええ、結局またきりんです。きりんさんです。 ヤヤネヒロコ神の声は本当に汎用性が高いですね。

続きを読む