ukstudio

UX概論に参加した

【満席のため受付終了】UX概論 〜UXデザインの基礎を学ぶ勉強会〜 : ATND

この間の土曜日に参加してきた。ミニワークショップいれて3時間弱の勉強会だったけど、思ってた以上にUXに対する知識が浅かったなぁと通関した。すごく勉強になりました。講師の浅野先生、運営の倉光さん、その他スタッフのみなさん、本当にありがとうございます。

勉強会の内容だけど、UX自体はそんなにおおごとじゃないけど、じゃあどうやってそれを実現するの(つまりUXデザインの部分)ってなるとかなり大変そうだなぁという印象を受けました。ペルソナからしてちょっと甘くみてた感じです。

今後の課題としては社内のプロジェクト(とりあえず自分のチームだけでも)にUXデザインをどう取り込むかかなぁ。講師の方にアドバイスもらったけど外部の専門家でも雇って一緒にやって覚えるというのがよさそう。あとはいくつかの会社合同でワークショップをやるといいみたいな話もあったのでどこかのタイミングでやれたらな。

がんばるぞい

特定のGemの更新情報を追う

コード自体を追うなら大体GitHubで事足りるけど、Gemがリリースされたのを追いたいときにはRubyGems.orgのSubscribe使えばよさそうだったのでメモ。

Click subscribe link

RubyGems.orgの適当なGemのページを開くと右下の方にSubscribeというリンクがある。このリンクをクリックするとDashboardにそのGemの更新情報が表示される。あとはそこに表示されているRSSを追えばOK。

Get dashboard's rss

「マイクロソフトを辞めて、オフィスのない会社で働いてみた」読了した

Amazon.co.jp: マイクロソフトを辞めて、オフィスのない会社で働いてみた: スコット・バークン, 依田卓巳: 本

会社で買ってもらった本読み終わった。おもしろかったのでサクサク読んだ。おすすめ。

この本はマイクロソフトでプロジェクトマネージャーをやっていて、現在経営コンサルのスコット・バークンが社員全員がリモート勤務しているオートマティック社(wordpress.com作ってるところ)に勤務したときの話が書かれてる。所謂ドキュメンタリーに近いのだけど、誰かが観察したとかではなくて実際に著者が働いた時の体験がベースになってる。

37signalsの「強いチームはオフィスを捨てる」もまぁそんなにつまらなくはなかったけどなんかキレイ事だけっぽい感じがするのと対象に、こっちは良かったこと悪いこと両方について書かれていて色々考えさせられる。強いチームはオフィスを捨てるより色々参考になるのでリモートに興味がある人は読むといいかも。

スコットのすごいところは今までチームという文化が全然なかったところに(締め切りもないし見積りもない)、チームという文化を導入して実績を残したところ。著者が言うように、ある文化で染まっているところに新しい文化を導入するのはそう簡単なことじゃない。

それとリモートはやっぱり難しいなというのが率直な感想で、今のメンバーを散り散りに働かしても多分成果は落ちる。スコットも作中で「リモートでも良い仕事ができたが、いつもそばにいれたらもっと良い仕事ができたと思う」みたいなことを言っていた。逆にオートマティックのCEOは全員リモートがとてもよい働き方だとも思っているらしい(成果より社員の満足度・幸福度を軸に考えているのかも)

じゃあなんでリモートするのかというと、居住地に縛られず人を雇えるのが大きいのかなと思う。例えばちょーやばいハッカーがいるけど俺はカリフォルニアから出る気がないぜ、という人だと東京で当然雇えないがリモートだったら雇える可能性がある。つまり距離という制限をなくして本当に働きたい人と働くことができる。

あとはやっぱりリモートで時間に縛られないことで社員の満足度があがるとか(自分の好きなところで働きたい、子供の世話を見なくてはいけない…etc)についても言及されていて、ここらへんはなんとなく感じている通りかなという印象。

この本はオートマティック社がフルリモートでどう仕事しているのかというのもおもしろいが、それ以上にスコットがカオスな会社にチームという文化を導入するまでの流れの方がおもしろいかな。おすすめです。

スクラム実践入門読み終わった

Amazon.co.jp: スクラム実践入門 ── 成果を生み出すアジャイルな開発プロセス (WEB+DB PRESS plus): 貝瀬 岳志, 原田 勝信, 和島 史典, 栗林 健太郎, 柴田 博志, 家永 英治: 本

2015/4/3に読了。

会社で購入してもらったのでざっと読み終えた。

ソフトウェアはどこにあるのか。そう、僕らの心のなかにあるんだよ…

なんかふざけた見出しつけたけど、1章は結構好きで何回か読み直したいなという章だった。スクラムについて知るぞ〜と意気込む若者がよんだらちょっとびっくりするかもしれない。それでもまずは読んでみて自分なりに考えてほしいなぁと思う。僕もまだちょっと消化不良感あるので消化したい。

スクラムガイドのガイド

2〜4章はスクラムガイドに基いてスクラムについてコンパクトに解説してくれる。この辺はスクラムについてある程度知識はあったのでうんうんという感じで読みました。

正直、スクラムガイドってあれだけ読んでもピンと来ない人ってそこそこいると思うんだよね。スクラムガイドだけじゃいまいちわからんって人はこれらの章を読むとある程度理解できると思う。

各社の事例と問題解決の道標。

この本でしか読めないと噂の6〜8章。それと問題とその解決策を提示してくれる9〜12章。

この辺りの章もよかった。特に僕の場合、日々の開発でなにかしらうまくいかないことがあってそれの答えとまではいかなくとも参考になるなにかが欲しいという動機でこの本を買ってもらったのですごく参考になった。

理論の前半、現場の後半

前半と後半でそれぞれ読み応えがあるので、スクラムについて全然しらんという人でもスクラムについてある程度知ってたり経験があるっていう人でもなにかしら得るものがある本だなと思いました。

弊社でも1人、悩める人がいるのでその人には是非読んでもらおうかなと思います。

特定のコミットが含まれるGitHub Pull Requestを開く

今日たまたまあるコミットが含まれているGitHubのPull Requestをサクッと探したい事案が発生した。というのも自分が以前書いたコードがどうしてこうなっているのかというのを知りたかったんだけど、commit messageだけじゃよくわからんかった(〜を実装したみたいなことを英語で書いてあっただけ)。

Pull Requestは割と丁寧に説明を書いているのできっとPull Requestのdescriptionを見ればわかりそうという感じはしたのだけれどパッとそれを開く手段がわからず、色々ググったりtwitterで教えてもらったりした結果下のようなfunctionをzshrcに書いた。

function find-pr() {
  local parent=$2||'master'
  git log $1..$2 --merges --ancestry-path --reverse --oneline | head -n1
}

function find-pr-open() {
  local pr="$(find-pr $1 $2 | awk '{print substr($5, 2)}')"
  local repo="$(git config --get remote.origin.url | sed 's/git@github.com://' | sed 's/\.git$//')"
  open "https://github.com/${repo}/pull/${pr}"
}
find-pr-open REVISION

あまりシェルは得意ではないのでそこらへんは大目に見て欲しい。やってることはfind-prで該当のcommitが含まれているMerge commitを探してcommit messageからGitHub Pull Requestの番号を取り出している。リポジトリ名はgit configから取得して余計な文字はsedで削除。あとはURLを組み立ててブラウザで開くだけ。多分これでPull Requestを開けるはず。

なんにせよcommit messageはもうちょっと丁寧に書こうと思いました。

Vue.js便利

今のプロダクトにちょっと前からVue.jsを採用しているんだけど、少しずつうまく使えるようになってきていてすごく便利だなーと感じる。コンポーネントについても大体わかってきた。

RailsアプリケーションにVue.jsを採用してどう変えてきたかみたいな記事をそのうち スパイスな人生 の方に投稿したいと思う。お楽しみに。

TEX Yodaが届いたので使い始めた

TEX Yoda TrackPoint Keyboard - Massdrop

一部で話題のTEX Yodaが先週の金曜日に届いたので今週から使っている。

とりあえずできた

AKAMATSU Yukiさん(@ukstudio)が投稿した写真 -

ハンダ付け

久々のハンダ付けだけど、MXスイッチの足と基板をつけるだけだし、オフィスに先に組み立て済みの同僚もいたのでそんなに難しいこともなく終了。といっても幾つかミスもあったわけだけど。

  • LEDを付ける前に基板をネジ止めした
  • ハンダ付けしわすれた箇所があった

TEX YodaにはLEDつけるところがあるんだけど、そのLEDがキートップのパーツと同じ袋に入ってる。なので基板にひと通りスイッチつけて、満足してネジ止めして「さー、キートップつけるぞ」と思い袋あけるとそこからLEDがでてきて悲しい感じになる。ハンダ付けするときにLEDの話を同僚としていたのにこれだよ。

ハンダ付けしわすれたのは完全に自分のミス。ひと通り組み立て終わったあとに0のキーが効かず、ハンダ付けのときに基板壊したかなとすごい焦ったけど開けてみたら普通にハンダがついてなかったというオチ。ちなみに現状、左下のFnキーも動いてないのでそこも忘れてる可能性ある。

ゼロのキー動かんと思ったらこれですよ

AKAMATSU Yukiさん(@ukstudio)が投稿した写真 -

選んだ軸

実は買って届くまでMXスイッチの軸の色の意味を知らなかったんだけど、買うときに一番値段が高かったクリア軸にした。わからないときはとりあえず高いのにしておく精神。調べてみると茶軸に近い感じということらしい。茶軸使ったことないからそう言われてもわからないけど…。他にも色々な軸があるので試してみたい気がする。緑とか気になる。

ちょっとしたカスタマイズ

MXスイッチ互換のキートップが売ってたりするので適当に変えてみたりした。PCゲーマーではおなじみのWASD。あとIJKLを赤に。これらはFnを押すとカーソルキーの動きをしてくれる。あとはなんとなくスペースも赤にしたら顔みたいになった。

顔っぽい

AKAMATSU Yukiさん(@ukstudio)が投稿した写真 -

キーレイアウト

現時点のレイアウトはDIPスイッチの1,3,5がオフ、2,4,6がオンになっている。それぞれの意味はマニュアル参照。

TKB-600i-Datasheet_14-0603-Rev 1.0.pdf - Google ドライブ

大体よくあるレイアウトだとは思うけど、珍しいのはESCと`~が同じキーでどちらかをFnキー押しながらじゃないと入力できない(DIPスイッチの3番参照)。

最初は普通に入力したらESCにして`~をFnキー押すようにしていたのだけど~がShiftも押さなきゃいけないのがあまりに不便すぎてやめた。VimmerとしてはESCはコード書くときそんなに使わないし、普段もMacユーザーなのでKarabinerでctrl-[をESC扱いにするようにしてESC単体で押す必要をなくして無事解決。

総評

概ね使い心地には満足している。元々ThinkPad使っていたのでトラックポイントも違和感なく、机からマウスを排除できたし、むしろマウスのためだけに腕を動かさなくなったが大分よい。実はHHKで一番気に入らなかったのがDELETEの位置で、TEX Yodaではそこが\になったのも良い。

本体の重さがそれなりにある。その気になれば撲殺できそうな程度には。なので持ち歩くつもりでいるならHHKの方がよいかなと思う。俺はあまりキーボードを持ち歩く人間ではないので問題ない。

タッチ感だけど、音はクリア軸のせいかTEX Yodaがそうなのかわからないけど、ちょっとちゃっちい音のような気もする。クリック感は個人的には大分気に入っていて、HHK、KinesisとTEX Yoda(クリア軸)だったらTEX Yodaが一番好み。ちなみにAlphaGripは俺の中では黒歴史化している。

今massdropをみると$199までもうちょいなので、興味ある人は買っていきましょう。ハンダ付けも$25でやってくれる模様。買って損はしないキーボードだと思います。実物みないと…という人は弊社に2つあるので遊びにくるとよいですよ。

株式会社spice lifeに入社しました

あけましておめでとうございます。今年もどうぞよろしくお願いいたします。

さて、タイトル通りではありますが、本日2015年1月1日から株式会社spice lifeに入社しました。社員です。

なので2010年(だったかな)から続いていたフリーランス業も一旦終わりになります。フリーランスの時には様々な人にお世話になりました。本当に感謝の言葉しかでてきません。一部の方々にはご迷惑をお掛けしてしまったこともあります。本来直接伝えることなのでしょうがここで簡単にでもお詫びと感謝の気持ちを述べさせてください。本当にありがとうございました。

spice lifeには6月の終わり頃からフリーランスとして契約させてもらっていてとりあえず半年契約しましょう、その後はその半年働いてよかったら再契約しましょう、という感じでした。ところがどっこい、再契約どころか正式に入社という運びとなりました。元々社員に近い形で働いていたので働き方的にはあまり大きく変わりはしませんが、4年程度フリーランスをしていたのでちょっと感慨深くあります。

ここ最近はリリースの時にもこのブログでお知らせしたSPOTLIGHTSというサービスの開発に携わっています。もうしばらく携わっていく予定ですので何卒よろしくおねがいします。

ウィッスリスト

esaのストックとフローの絞り込みで(俺にとって)なにがうれしいのか

そもそもesaのストックとフローの絞り込みってなに?っていう人は以下のリンクからどうぞ。

release_note/2014/12/13/検索結果の絞り込み(Stock or Flow) - docs - esa.io

簡単に説明するとesaではカテゴリに日付が入っている記事はフロー、入っていない記事はストックとして扱いそれらを分けて検索できるようになった。

結論から

たまには長い話をすっとばして結論を書く。簡単に言ってしまうと

  • yy年mm月dd日にAの仕様を変更したよ
  • 現時点において最新の仕様はこうです

という2種類の情報を前者はフロー、後者はストックとして分けて検索できるようになった。大体においてほしい情報というのは後者のストックなので個人的には非常にうれしい。

そもそもストックとフローとは

記事自体にストックとフローという概念をもたせるのは実はあまり新しい話でもなく、「wiki ブログ ストック フロー」で検索するとそれなりに記事がでてくる。要はwiki=ストック、ブログ=フローということだ。もちろん、wikiのあるページにフローの概念をもたせることもブログのある記事にストックの概念をもたせることも可能だけど大枠としてそういうことにする。ブログもストックっていう人もいるけど、wikiとかブログとかはここではあまり重要ではないので置いておく。

僕の捉え方でいうと、時系列にそって情報の流れがあるものはフロー、累積されていくようなものはストックと考えている(これなんの説明にもなっていないのでは…)

議事録はフロー

esaでそれなりの量の議事録を書いてきたけど、これらはMTGの日付をカテゴリに入れているのでフローだ。これらは日々の仕様の変更の流れをそのまま現しているのでフローとして扱うのは妥当だと思う。

flow.png

こういった情報がフローだけだと困ることがある。議事録には変更の差分しか書かれていない。なので現時点であるべき仕様を議事録から読み解くのは大変だ。エンジニアにわかるようにいうとgitの各commitのdiffから現在のソースコードを想像しろというものだ。

そこでストック

つまり、フローである議事録とは別に今あるべき姿を累積する記事が必要になる。そこでesa上では日付の入っていない記事を作り、そこにあるべき姿を書いていく。重要なのはフローと違いストックはその記事をちゃんと更新する必要があるということだ。

今まではこういう風にフローとストックの記事を分けてもうまく検索することができずにREADME.mdにリンクを貼っておくということしかできなかった。なのでそもそも人の目につかず、結果更新もされないという感じだったけれど、検索しやすくなったことで情報が古いことが目につきやすくなるので自然と更新も行われやすくなるのではないかと思う(みんな更新してね!)

おまけ

そもそも仕様をesaに書くの?みたいな話ありそうだけど、実装の前にメンバーに仕様を共有するケースはそれなりにあるし、コードを読んでもWhyがわからないのでなぜこうしたのかみたいな部分はドキュメントに残したりもする。

それに今回は仕様の話を例にとったけど、例えばインフラまわりだと議事録でこういう構成にしたという話を残すのとは別に構成がかわったことによってデプロイ手順もかわったならそれはストックとして残したいという話もある。

spotlights.jpが本日10時にリリースされました

みんなで贈るソーシャルギフト・プレゼント \SPOTLIGHTS/(スポットライト)

今日の10時より株式会社spice life(スパイスライフ)からSPOTLIGHTSがリリースされました!!

ここ2ヶ月弱の追い込みにプログラマとして開発に関わらせて頂いてます(今後も関わっていく予定です)。実は自分のブログで関わってます!って言えるサービスは初めてだと思うので、期間はまだ短いですがちょっと感慨深いものがあります。

結婚式や誕生日のお祝いや日頃の感謝などにご活用ください。

RSpecでPower Assertをやるには

RubyKaigi 2014でpower assertの話を聞いてrspecでどうにかならんかちょっと考えてみました。まず結論だけ書くとrspecでpower assertを使いたければ以下の様に書けばOK。

require 'rspec'
require 'minitest'
require 'minitest-power_assert'

module Minitest
  module Assertions
    prepend  Minitest::PowerAssert::Assertions
  end
end

RSpec.configure do |config|
  config.expect_with :minitest
end

describe 'Test' do
  it 'test' do
    assert { 1.to_s.class == 1.to_i.class }
  end
end

これを

$ rspec --color -rpower_assert power_assert.rb

で実行するとこんな感じ。power_assertは事前にrequireした方が情報量がちょっと増える。

Failures:

  1) Test test
     Failure/Error: assert { 1.to_s.class == 1.to_i.class }
     Minitest::Assertion:

           assert { 1.to_s.class == 1.to_i.class }
                      |    |     |    |    |
                      |    |     |    |    Fixnum
                      |    |     |    1
                      |    |     false
                      |    String
                      "1"

letとsubject

powerassertの0.1.3だとdefinedmethodで定義されたメソッドの値が取れていないらしく、letやsubjectの値が表示されない。現時点でのmasterの0.1.4devだと修正されているとのことなのでちゃんと表示される。

describe 'Test' do
  let(:klass) { 1.to_s.class }
  it 'test' do
    assert { klass == 1.to_i.class }
  end
end

これを実行すると

Failures:

  1) Test test
     Failure/Error: assert { klass == 1.to_i.class }
     Minitest::Assertion:

           assert { klass == 1.to_i.class }
                    |     |    |    |
                    |     |    |    Fixnum
                    |     |    1
                    |     false
                    String

こんな感じ。subjectも大体おなじ。

expectとマッチャ

この方法はMinitestのadapterとminitest-power_assertを使うようにしているので無理。

ちなみに rspec で 手軽に power_assert 出力できるようにする の方法でexpectを使ってみると

require 'rspec/core'
require 'power_assert'

module RSpec
  module PowerAssert
    def power_assert(&block)
      ::PowerAssert.start(block) do |pa|
        begin
          pa.yield
        rescue RSpec::Expectations::ExpectationNotMetError => e
          e.message << "\nPowerAssert:\n#{pa.message_proc.call}"
          raise e
        end
      end
    end
  end
end

class RSpec::Core::ExampleGroup
  include RSpec::PowerAssert
end

describe 'Test' do
  it 'test' do
    power_assert {
      expect(1.to_s.class).to eq(1.to_i.class)
    }
  end
end

これは

       PowerAssert:
             expect(1.to_s.class).to eq(1.to_i.class)
             |        |    |      |  |    |    |
             |        |    |      |  |    |    Fixnum
             |        |    |      |  |    1
             |        |    |      |  #<RSpec::Matchers::BuiltIn::Eq:0x007f0850c91d78 @expected=Fixnum, @actual=String>
             |        |    |      nil
             |        |    String
             |        "1"
             #<RSpec::Expectations::ExpectationTarget:0x007f0850caa170 @target=String>

こうなってしまう。この場合、expectの@targetにStringという結果が入っているのでそれを取り出すようにして、eqの方も@expectedに期待するものがはいってるのでそれを取りだすようにすればいいのかなぁ。

もしくはexpectとeqの中の値さえわかれば良いといえば良いのでいっそ値をださなくてもいいのかも? 例えばこんな感じ。

       PowerAssert:
             expect(1.to_s.class).to eq(1.to_i.class)
                      |    |              |    |
                      |    |              |    Fixnum
                      |    |              1
                      |    |
                      |    |
                      |    String
                     "1"


別の例としてbe_falseyだとこんな感じ。

     Failure/Error: expect(nil.to_s.to_i).to be_falsey
       expected: falsey value
            got: 0
       PowerAssert:
             expect(nil.to_s.to_i).to be_falsey
             |          |    |     |  |
             |          |    |     |  #<RSpec::Matchers::BuiltIn::BeFalsey:0x007fa84b53bb00 @actual=0>
             |          |    |     nil
             |          |    0
             |          ""
             #<RSpec::Expectations::ExpectationTarget:0x007fa84b3e02b0 @target=0>

これに関していうとbefalseyにはfalseが欲しいという情報がない。befalseyを見れば求めてるものはわかるって話かもしれないけど… 更に言うとRSpec3でComposable Matcherが入ったりとか、以前からあるCustom Matcherとかがあったりして、それら全部対応するのは厳しいなーという感じ(そもそも対応できるのかもよくわからない…)

そもそもの話をするとそういったマッチャというか、たくさんあるassertion methodを使い分けしたくないからpower assertをつかうわけで別にマッチャとか使わなくていいのではという気持ちがある。

なのでexpectとかカスタムマッチャとかは(power assertを使う部分では)諦めてassertですませるのがよさそうかなと個人的には思う。

config.expect_with :minitest
config.expect_with :rspec

spechelper.rbにminitestもrspecも両方使うよう書けばpowerassertを使いたいところと、rspecを使いたいところで分けることができるのでどうしてもマッチャを使いたいところは素直にマッチャを書いてpower assertは諦めるしかない。

今あるテスト資産をそのまんまpower assert対応にはできないのが悲しいところではあるけれども、このassertを使う方法でもexpectation部分以外はrspecの機能そのまま使えるのでそこまで悪くはないかなと思う。

まだpower_assert gemの実装を理解できていないので、もしかしたらうまいことやれるかもしれないけどとりあえずここでギブアップ…

Arelあれこれ

Model.arel_table を読みづらいと感じる

例えばこういうコード。

Post.joins(:comments).order(Comment.arel_table[:created_at].desc)

発行されるSQLはこんな感じ。

SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"  ORDER BY "comments"."created_at" DESC

こちらの方が個人的には読みやすい。

Post.joins(:comments).order('comments.created_at desc')

問題もある

テーブル名を変えてしまったとき

仮にテーブル名がかわったら後者の場合はエラーになる。

SELECT "posts".* FROM "posts" INNER JOIN "new_comments" ON "new_comments"."post_id" = "posts"."id"  ORDER BY comments.created_at DESC
SQLite3::SQLException: no such column: comments.created_at: SELECT "posts".* FROM "posts" INNER JOIN "new_comments" ON "new_comments"."post_id" = "posts"."id"  ORDER BY comments.created_at D
ESC
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: comments.created_at: SELECT "posts".* FROM "posts" INNER JOIN "new_comments" ON "new_comments"."post_id" = "posts"."id"
  ORDER BY comments.created_at DESC

前者はモデルの方でテーブル名を変更すれば動作する。

class Comment < ActiveRecord::Base
  self.table_name  :new_comments
end

scopeでmergeしたいとき

class Comment < ActiveRecord::Base
  scope :recent, -> { where('created_at > ?', 10.days.ago) }
end

Post.joins(:comments).merge(Comment.recent)

これだとCommentのcreated_atが解決できなくてコケる。

SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (created_at > '2014-08-26 09:16:45.106691')
SQLite3::SQLException: ambiguous column name: created_at: SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (created_at > '2014-08-26 09:16:45.
106691')
ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: created_at: SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE (cr
eated_at > '2014-08-26 09:16:45.106691')

正しくはこう。

class Comment < ActiveRecord::Base
  scope :recent, -> { where(self.arel_table[:created_at].gt(10.days.ago)) }
end
SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" WHERE ("comments"."created_at" > '2014-08-26 09:19:17.406299')

僕個人の結論

Model.arel_tableはできる限り隠したい(読みづらいから)。そしてmergeを使いたいケースではArelを使っておく。その変わりmergeが必要になるまでは無理にArelを使わない。

さっきのComment#recentの例でいうなら最初はwhere('created_at > ?', 10.days.ago)で書いておく。merged使いたい時になったらArelの方で書き直す。

テーブル名の変更のリスクは気にしない。そもそもあまりテーブル変更しないし…。既にあるDBの上にRailsアプリケーションを構築する場合はDBリファクタリングのことを考えてArel使いまくった方がいいのかもしれない。

Vim(TagBar)でRSpecのctagsを扱う

rspec ctags

unite-outlineとかを使う人には不要なのかもしれないけど、あいにくuniteユーザではないのでctagsでなんとかできないか調べてみた。

まず、Funtooで入るctagsではrspecのタグは生成できないのでforkされたctagsを使う必要がある。

fishman/ctags

インストール場所はお好みで。個人的には手で入れる系のものは$HOME/localにインストールするのが好きなのでそこにインストールした。あとはTagBarの方でこのctagsを使うよう設定する。

let g:tagbar_ctags_bin="/home/ukstudio/local/bin/ctags"
let g:tagbar_type_ruby = {
    \ 'kinds' : [
        \ 'm:modules',
        \ 'c:classes',
        \ 'd:describes',
        \ 'C:contexts',
        \ 'f:methods',
        \ 'F:singleton methods'
    \ ]
\ }

これで上の画像のような感じでTagBarに表示されるようになるはず。

lsと間違えてerutasoを打ってしまうGentoo/Funtooユーザーのみなさまへ

ebuildを作ってみましたのでご活用ください。初めてのebuildなので不具合・不都合あればpull-reqを。ukstudioというoverlayを作りましたのでそこからインストールできるはずです。

https://github.com/ukstudio/ukstudio-overlay

curl https://raw.github.com/ukstudio/ukstudio-overlay/master/profiles/layman.xml > /etc/layman/overlays/ukstudio-overlay.xml
layman -f -a ukstudio

emerge erutaso
which erutaso #=> /usr/bin/erutaso

erutaso

See also

https://twitter.com/sgymtic/status/448832543039574016

BitlBeeでHipChatに接続する

HipChatのLinuxクライアントは残念ながら日本語入力ができないのでかわりにIRCを使ってみる。 HipChatはJabberが使えるのでBitlBeeを使ってJabber経由でIRCと繋ぐことにする。BitlBee自体の設定はなにもいらないので各環境にあわせて適当に入れて起動する。

sudo emerge bitlbee
sudo /etc/init.d/bitlbee start

次にIRCクライアントでBitlBeeに接続する。BitlBeeはlocalhostに6667ポートで立ち上がっているので(コンフィグで修正していなければ)、そこに接続する。文字コードはUTF-8でOK。 接続できたらbitlbeeの部屋でコマンドを入力し、アカウントを追加する。HipChatのJabberのアカウントは「Account Setting > XMPP/Jabber info」にある。

account add jabber username@chat.hipchat.com 'password'

次に各ユーザがニックネームで表示されるように設定する。これをやらないと数字の羅列で誰が誰だかわからない状態になってしまう。

account hipchat set nick_source full_name

次にアカウントを有効化する。この時点で認証などもしているので失敗したらアカウント情報を見直すこと。

account hipchat on

有効化できたらすでに部屋に参加できるが数字の羅列が頭についているので使いにくい。別の名前を割り当てることができるので適当に自分が使いやすい名前をつける。

chat add hipchat room_jaber_name@conf.hipchat.com #channelname

ニックの設定次第だとHipChatから怒られるのでその場合HipCHatで使っている名前を設定する。

channel #channelname set nick 'room nickname'

無事、部屋にjoinしてログが流れてきたら終了。

/join #channelname

BitTorrent SyncでQNAPとFuntooで同期する

QNAPの一部のディレクトリ(主に電子書籍)とローカルのマシンで同期を取りたかったのでBitTorrent Syncで同期を取ってみる。NFSでもいいんだけど、電子書籍ぐらいならローカルにおけるぐらいのストレージ容量はあるので。

QNAPにBitTorrent Syncを入れる

基本的にはQNAPのドキュメントを参照すれば問題ないと思う。簡単に説明しておくとQTSにBitTorrent Syncを追加し、BitTorrent SyncのWebUIを起動する。WebUIのアクセスユーザは途中で"Please modify the Login ID / Password"とか言われる画面でLogin IDとPasswordを入力し、Apply Changesをすればそのユーザで接続できる。

次にBitTorrent SyncのWebUIが起動したらAdd Folderから該当のディレクトリを選択する。Secret KeyはここでGenerateしておく。(後でローカルの方の設定で使用する)。QNAP側はこれで終わり。

FuntooにBitTorrent Syncを入れる

FuntooはportageにBitTorrent Syncのebuildがあるのでそれを使う。

sudo emerge bittorrent sync

起動は/etc/init.d/btsync startだが、コンフィグの修正が必要。init.dで起動するとログがでないからわからないが、/opt/btsync/btsyncで起動するとstorage_pathが存在しないと怒られるのがわかる。コンフィグは/etc/btsync/configがそう。

// "storage_path" : "/home/user/.sync",
"storage_path" : "/home/ukstudio/.sync",

ディレクトリはお好みで。

/etc/init.d/btsync startで無事btsyncが起動したら、http://localhost:8888/guiでWebUIにアクセスできる。IDとパスは'admin'と'password'。

WebUIにアクセスできたら、Add FolderでQNAPと同期させたいディレクトリを指定する。Secret Keyはここでは生成させず先程のQNAPのsecret keyをコピペする。保存し、WebUIのトップ画面で"connected devices and status"でダウンロード速度が表示されたら無事同期がはじまっている。

FuntooからQNAPにOpenVPNでつなぐ

まずはFuntooにOpenVPNを入れる。

sudo emerge openvpn

次にQNAPからOpenVPNの設定ファイルをダウンロードする。場所は「コントロール・パネル -> アプリケーション -> VPNサービス -> 設定ファイルのダウンロード」にある。(QTS 4.0.3)

zipが落ちてくるのでunzipするとca.crtとopenvpn.ovpnが展開されるので/etc/openvpnにmvする。他にOpenVPNで接続するところはないのでそのまま放りこむ。openvpn.opvnのままだと/etc/init.d/openvpn start時に怒られるのでopenvpn.confにリネーム。

/etc/init.d/openvpn start

で起動する。ユーザとパスを聞かれるのでadminで認証する。他のユーザーで認証したい場合はVPNサービスの設定からユーザを追加する。ローカルIPでQNAPに繋れば無事終了。

Kensingtonのslimbladeを導入

ちょっと新しいマウスを捜してたのでこの機会にトラックボールに移行してみた。購入したのはKensingtonのSlimBlade

昔はLinuxで使うと上の2つのボタンが使えなかったみたいだけど、今はパッチがあたったようで問題なく使える。なぜか右奥がバックボタンなのに左奥がミドルボタンだけど。この辺のリマップはxorg.confあたりでいいのかな。あまり困りはしないのでとりあえずは特に設定を変えずに使ってみることにする。

GentooからFuntooに移行しました

GentooからFuntooに移行した。Funtoo Linux インストール講習会から大分日が立ってしまった。

インストール自体はFuntoo Linux Installationをそのまま実行。boot-updateのビルドだけ失敗したが、texinfo-5.1以上をmaskしたら解決。

ネット関係はNetworkManagerが妙に不安定だったのでwicdを使うことにした。wicd-cursesがいい感じ。今のところ接続も安定している。

X環境まわりは例のごとくXmonadで。GNOMEも一度入れたけど、結局使わないのでアンインストール。mix-inのGNOMEも余計なUSEフラグをつけて邪魔だったので使わないことにした。

GNOMEを削除したのでGDMではなくSlimeを使うことにした。GDMとかstartxがxinitrcを読むのかxprofileを読むのかとかいっつも忘れる…

その他GitやらRubyやら入れてひととおり終了。カーネルをバイナリで入れてるので起動が遅いけどカーネルのコンフィグでハマるのもダルいしとりあえずこのままで行く予定。

ブログをWordPressからmiddlemanに移行しました

今まで当ブログはWordPressでブログを書いていたけれど、今回middlemanを使うことにした。特になにかが気に入ってmiddlemanを選んだわけでもないのだけど、しばらくはこれで運用してみようと思う。

運用はGithub Pageで行なうことにした。これで今まで中途半端に保持していたVPSを解約することができる。最近はIRCを全然使ってないからいいけど、なんかの機会に使うようになったらtiarraとかをどう運用するか考えなくちゃいけないなぁ。

デザインやその他足りない機能は追々増やしていこうとおもいます。とりあえずRSSだけは用意した。