会議室名がオシャレ過ぎて覚えられない君へ #vgadvent2013

f:id:lesamoureuses:20131213202642j:plain

この記事はVOYAGE GROUP エンジニアブログ : Advent Calendar 2013の14日目の記事になります。
ちょっとハマってて気が付いたら日付が変わってました。


さて、去年のAdvent Calendarは社内図書館のOASISの本の整理の話を書いたので、「今年も会社の話で何かないかなぁ」とネタを探してました。

会議室の名前と場所が覚えられない


はじめに会議室の地図の写真を載せましたが弊社、会議室の名前がオシャレ過ぎて覚えられません。
どのくらい覚えにくいのかを理解できるようにいくつか紹介します。


まず、いつも #ajiting で飲んでるAJITOは大丈夫。デカいし入口だし覚えやすいです。
f:id:lesamoureuses:20131213235814j:plain


畳があるジパング。ふむ、これはまだ覚えやすい。
f:id:lesamoureuses:20131213235628j:plain


段ボール素材のアトランティス。こっからもうキツいですね。これはもう「段ボール部屋」と呼んじゃってます。
f:id:lesamoureuses:20131213235707j:plain


レムリア。「糸がたくさんの部屋」みたいな感じで呼ぶ。
f:id:lesamoureuses:20131214012137j:plain


ユーラシア。「何かアノすごく茂ってる所」
f:id:lesamoureuses:20131213235728j:plain


こんな感じでいろんな会議室があるんですが、とにかく名前から場所を思い出すのがつらいわけです。
(わかりづらいが故に僕らは会議室の場所をひねり出すため脳内メモリにあった仕事用記憶を一回スワップ領域に追い出すだなんていう煩わしい作業をしなければならないわけですよ!!!!)

覚えられないなら覚えなければ良い


ということで、覚えなくて済むようにAcme::VOYAGEGROUP::ConferenceRoomというモジュールを作りました。


インストールはcpanmでサクッと。

cpanm Acme::VOYAGEGROUP::ConferenceRoom


インストールするとconference_roomというコマンドが使えるようになるので引数に会議室の名前を入れるだけです。


たとえばzipang。
f:id:lesamoureuses:20131215030718p:plain
おぉ!わかりやすいですね!


次にajito。赤くなってるのが大変わかりやすくて良いですね!
f:id:lesamoureuses:20131215030829p:plain


大文字の方がしっくりくるってこともあるので大文字にも対応しました。
f:id:lesamoureuses:20131215030939p:plain


「まぁでも普段カタカナ使うよね」ってこともあるかもなのでカタカナも。
f:id:lesamoureuses:20131215031008p:plain


せっかくだからひらがなも。
f:id:lesamoureuses:20131215031049p:plain


「うーん、どうせだったら出力はJSONがいいなぁ」と言われる可能性も考えて第2引数にjsonと渡すことでjson出力できるようにもしました。
f:id:lesamoureuses:20131215031206p:plain


これで昨日覚えたjqでもアクセスできますね!!!
f:id:lesamoureuses:20131215032355p:plain


「jsonあるならXMLもあるべきなんじゃないの?」ってことでXMLも。
f:id:lesamoureuses:20131215032534p:plain


最後に「せっかくだからMessagePackでのデータのやりとりも考えるべきなのでは?」ということでMessagePackにも対応しました。
f:id:lesamoureuses:20131215032718p:plain



以上です!
Acme::VOYAGEGROUP::ConferenceRoom、総じて便利ですね!!!これでもう会議室の場所を覚える必要はありません!!!

まとめ

  • 本エントリでは弊社の会議室名のオシャレさについて言及しました。
  • ギリギリになって書き始めるとハマって日付が変わるということについて言及しました。


明日はアラビア語の学習環境を整えることで著名@hagino3000 さんです!もしかするとアラビア語でのpostになるかもしれませんね!

正規表現のx修飾子を使い、かつ、"ム"を指定するとTest::MinimumVersionでrequires 5.017009になる

2014-01-03 追記

これ、PPIx::Regexpのせいだった。
「ム」を16進数表示すると\x{E3}\x{83}\x{A0}になり、この最後のA0がWhitespeceと見なされてx修飾子と一緒になると

'perl_version_introduced' => '5.017009'

となる。
https://rt.cpan.org/Ticket/Display.html?id=91798

(でも、そもそもx修飾子使ってた所でsyntax変わらないからversionは元のままでいいんじゃないかな?)
x修飾子の動きが変わったのは5.17.9だからperl_version_introducedとしては合ってるのか。

元記事

5.8で動くようなコードでminil distを実行したらなぜかrequires 5.017009のエラーが出て「えー!何でー!」となりハマりました。


試しに5.17.9のperldeltaを見てみたんですが、そこに関わるようなコードを書いてなさそうで良くわからなくて断念。


とりあえずどんどんコード削除していった結果、最小の再現コードが作れました。

「ム」と「x修飾子」を使うと起こる。

で、もう一度5.17.9のperldelta見た感じ、ここの部分に当たるんじゃないかなと推測。
ただ「/xの空白の話だし、ムはU+30E0だからここかどうかは確実じゃないなぁ」とも思いまして。


ここでふとCompiler::Lexer をつかって Perl::MinimumVersion::Fast をかいてみた - blog.64p.orgを思い出して、Test::MinimumVersion::Fastを使って試してみたらエラーになりませんでした。


ここまでわかった所でその後どうしていいかわからないのでとりあえずメモ。


正規表現のx修飾子を使い、かつ、"ム"を指定するとTest::MinimumVersionでrequ ...

tmuxでanyenv(*env)で*env/shimsがsystemのPATHより前に読まれてsystemが使われてしまう対処

anyenvを使っているんですが、

/usr/local/heroku/bin
/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/shims
/Users/monmon/.anyenv/bin
/Users/monmon/local/bin
/Users/monmon/bin
/usr/local/sbin
/usr/local/bin
/usr/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin

のようなPATHがtmuxを起動すると

/usr/local/heroku/bin
/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/bin
/Users/monmon/local/bin
/Users/monmon/bin
/usr/local/sbin
/usr/local/bin
/usr/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/usr/local/heroku/bin
/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/bin
/Users/monmon/local/bin
/Users/monmon/bin
/usr/local/sbin
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/shims

のようになってshimsが

/usr/local/bin
/usr/bin

より前に読まれてしまい、plenvのperlではなくsystemのperlが使われてしまいます(typeset -U path PATHはしてない状態)。


で、自分の環境だけの話なのかなぁと思ったら
http://konboi.hatenablog.com/entry/2013/12/12/213931
みたいなのも見つけて

rbenv works by inserting a directory of shims at the front of your PATH:
~/.rbenv/shims:/usr/local/bin:/usr/bin:/bin


Understanding Shims

ってのも見て「どうしたらいいんだろう?」と中身見てみた。


結果、anyenvだけの話ではないのだけど、~/.anyenv/libexec/anyenv-init内の

102   echo "$(${ENV_ROOT}/bin/${env} init -)"

の所で、初めに実行された時には

export PATH=/Users/monmon/.anyenv/envs/plenv/shims:/Users/monmon/.anyenv/bin:/Users/monmon/local/bin:/Users/monmon/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

なんですが、tmuxを起動した時にもう一度実行された時には

source /Users/monmon/.anyenv/envs/plenv/libexec/../completions/plenv.zsh

になるので、shimsをPATHに入れるタイミングが初めにしかなく、shimsがsystemより前になってしまう。


ということで、結果的に良いか分からないけど、shimsをPATHで読み込むようにしました。

-  ANYENV_ADD_PATH="${ENV_ROOT}/bin:${ANYENV_ADD_PATH}"
+  ANYENV_ADD_PATH="${ENV_ROOT}/bin:${ENV_ROOT}/shims:${ANYENV_ADD_PATH}"

https://github.com/monmon/anyenv/commit/5e976cd66904b8e4771f1aca8ed4b32ab43de80d


こうすることで、tmux使ってない場合には

/Users/monmon/.anyenv/envs/rbenv/bin
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/bin
/Users/monmon/.anyenv/envs/plenv/shims
/Users/monmon/.anyenv/envs/rbenv/shims
/Users/monmon/.anyenv/envs/plenv/shims

となってしまって良いのか悪いのかわからないけど、僕はtypeset -U path PATHでPATHの重複消しているのでいいかなと思いました。
これ、anyenvだけの問題ではないと思うのでもっといい解決方法あるんじゃないかなと思ったんだけど探せませんでした。

「Minillaをインストールしようと思ったらテストが通らない!><」と思ったら~/.gitignoreのせいでした

家でサクッとインストールできたはずなのに会社で以下のようなエラーが出て「あれー!」となりました。

===(      49;1  0/?  0/?  1/? )=========================================Use of uninitialized value in string eq at /Users/no-kumagai/.cpanm/work/1386851499.15174/Minilla-v0.11.0/blib/lib/Minilla/ReleaseTest.pm line 49.

        #   Failed test at t/filegatherer.t line 32.
        #          got: '.gitmodules,META.json,README,foo,libfoo/foo.c'
        #     expected: '.dot/dot,.gitignore,.gitmodules,META.json,README,foo,libfoo/foo.c,xtra/.dot,xtra/.dotdir/dot'
        # Looks like you failed 1 test of 1.

    #   Failed test 'include_dotfiles'
    #   at t/filegatherer.t line 33.
Use of uninitialized value in string eq at /Users/no-kumagai/.cpanm/work/1386851499.15174/Minilla-v0.11.0/blib/lib/Minilla/ReleaseTest.pm line 49.
===(      50;2  0/?  0/?  2/? )=========================================    # Looks like you failed 1 test of 3.

#   Failed test 'FileGatherer'
#   at t/filegatherer.t line 45.
# Looks like you failed 1 test of 2.
t/filegatherer.t ................... Dubious, test returned 1 (wstat 256, 0x100)

で、コケた結果見たらわかるとおり.(ドットファイル)でこけてる。
単純に~/.gitignoreに

.*

が入ってたからだけでした(ドットファイルはとりあえず弾いて必要なやつだけ追加できるようにする派です)。

idobata.ioでGeneric HookでFAILUREとかSUCCESSを出す

こんにちはmonmonです。
みんなが大好きグループチャットのIdobata
JenkinsのHookが使えたりして便利ですが、cronとかでも失敗した時の
f:id:lesamoureuses:20131028212008p:plain
や成功した時の
f:id:lesamoureuses:20131028212018p:plain
を出したいなって思ったりしますよね。


ということでGeneric Hookを使って出しましょう。


まず失敗。

<span class="label label-important">FAILURE</span>

こんな感じでlabelとlabel-importantのclassを指定したHTMLをidobataさんに飛ばすだけです。


次に成功。

<span class="label label-success">SUCCESS</span>

こんな感じで今度はlabel-successのclassを指定すれば良いです。


ということで、
f:id:lesamoureuses:20131028213228p:plain
って感じや
f:id:lesamoureuses:20131028212747p:plain
って感じの通知をidobataさんに出すことができます。


簡単ですね!

jQueryの.data(key)はjQuery.parseJSONでparseできないときにobjectを返せないからstringを返すよ

JavaScript部分にサーバ側で動的な値入れるのエスケープ考えないとだし嫌だよねー」
「htmlタグのdata属性使ってhtmlのエスケープだけ考えればいいようにしたいよねー」
とか思って

<html data-name="monmon">

みたいなことよくやります。

で、さらにjQueryなら

<html data-obj='{"name":"monmon"}'>
<script type="text/javascript">
console.log($('html').data('obj'));      // Object {name: "monmon"}
console.log($('html').data('obj').name); // monmon
</script>

という感じでJSON形式で書いて.data(key)使ってオブジェクトで受け取るなんてこともよくやります。

なのですが、「\が入ったときどうなるの?」って質問されてちゃんとドキュメント読んでないことに気づきました。

When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string.

.data() | jQuery API Documentation

「validならjQuery.parseJSONでparseしてオブジェクトで返すけど、parseできないなら文字列で返すよー」って話だった。
具体的にはjQueryの.data(key)はobjectを返す場合とstringを返す場合がある - jsdo.it - Share JavaScript, HTML5 and CSSの通り。

結論としては、.data(key)で返って来た値でエラー処理入れればいいですね。

データフレームの列に変数を使ってアクセスするときは[[]]を使う

やりたいことはhogeという列をもったdfrmというデータフレームがあったときにhogeが入ったrow_nameという変数を使ってアクセスしたいというもの。

row_name <- hoge

# TODO: row_nameを使ってdfrm$hogeのようにアクセスするにはどうやって書けばいいの?!


いつも

dfrm$name

というアクセス方法しかやったことがなく「これきっとシンタックスシュガーで何かしら書き方あるんだろうなぁ」と思ってRクックブックをパラパラしたらP.66にあった。

1つの列を選択するには、以下のリスト表現のいずれかを使います。

dfrm[["name"]]

nameという名前の1列を返します。

dfrm$name

構文が異なるだけで上記と同じです。

ということで先の場合には、

dfrm[[row_name]]

でいけました。