Kyoto.なんかで“Introduce browserify”という発表をした

Kyoto.なんかという Kyoto.js の潮流を汲んだような汲んでいないような、勉強会のようななんなのかよくわからないイベントで発表した。

browserify という Common JS Modules/1.0 などに互換のあるモジュールを、Common JS Modules/1.0 などモジュール機構に対応していないブラウザで動かせるようにするツールについて簡単な紹介をした。

browserify-shim を使って jQuery plugin も browserify で扱えるようにするのがとても便利。

実際には browserify-shim が require() を解決し展開するやりかたはけっこう凝っている (出力されたコードとちょっと実装を読んだくらいで、僕も詳しい実装はあまり追っていない)。

作者の substack さんは browserify という比較的大きなツールを作る際に、細かく部品化してそれぞれ独立した npm モジュールとして公開されていたりする。

unix philosopher.

substack in cyberspace

というポートフォリオの一文が実にしっくりくる人だと思います。

anyenv-exec を作った

anyenvプラグイン anyenv-exec を作った。

使い方

たとえばインストールされている *env のバージョンを出力する例:

anyenv exec --version
# plenv 2.1.1-9-g26dbef7
# pyenv 0.4.0-20140404-10-g601ac4b
# rbenv 0.4.0-97-gfe0b243

rehash する例:

anyenv exec rehash

*env 系は大抵のサブコマンドが共通していることから、出力を比較したいとか、いちいち for 文を書くのはめんどうであるとか、そういった思いから作ってみた。

実装は大したものではないけれどけっこう便利。

インストール

mkdir -p $(anyenv root)/plugins
git clone git://github.com/aereal/anyenv-exec.git $(anyenv root)/plugins/anyenv-exec
aereal/anyenv-exec · GitHub

chrome.contextMenus.create() に parentId とコンテキストを指定するプロパティは同時に指定できない?


ドキュメントには特に何も書いていない。

子メニュー (= parentId を指定されている) は親メニューより狭いコンテキストを指定することはできない?

Vim で現在カーソルがあるテストメソッドを実行する

Perl には Test::Class という JUnit 風にテストを書けるモジュールがある。すなわち:

ことができる。

Test::Class はテスト実行時に環境変数 TEST_METHOD に与えられた値で実行するテストメソッドをフィルタリングすることができる。

Sometimes you just want to run a single test. Commenting out other tests or writing code to skip them can be a hassle, so you can specify the TEST_METHOD environment variable. The value is expected to be a valid regular expression and, if present, only runs test methods whose names match the regular expression.

Test::Class - search.cpan.org

テストコードが存在するソフトウェアに修正を加える場合、大抵、いつかのタイミングでテストコードを修正することになる。そうなるとまず修正したテストのみを実行し、最小限度のフィードバックを得たい。

つまり、TEST_METHOD を指定してテストを走らせたいのだが、いちいちテストメソッド名を入力するのも面倒である。

そこでテストの実行には vim-quickrun を、現在カーソルのあるメソッド名を取得するために current-func-info.vim を使う。

let g:quickrun_config['prove/carton'] = {
      \ 'exec'    : 'carton exec -- %c %o %s',
      \ 'command' : 'prove',
      \ }
let g:quickrun_config['prove/carton/contextual'] = extend(g:quickrun_config['prove/carton'], {
      \ 'exec' : 'TEST_METHOD=%a ' . g:quickrun_config['prove/carton'].exec,
      \ })
command! ProveThis call s:prove_this()
function! s:prove_this()
  let func_name = cfi#format('%s', '')
  if func_name == ''
    QuickRun prove/carton
  else
    execute 'QuickRun prove/carton/contextual -args ' . func_name
  endif
endfunction

メソッド名を得ることができればその値を引数として渡し prove/carton/contextual の設定を使って QuickRun を実行する。得られなければ prove/carton を実行する。

rbenv など *env でどの設定 (global, local, shell) を参照しているか知る

rbenv *1rbenv version-origin というサブコマンドがあり、それは「rbenv がバージョンを決定するのに使われた設定」を出力する。

出力は次の3つのうちのいずれかとなる。すなわち:

  • global の設定
    • $HOME/.rbenv/version
  • ディレクトリごとの設定 (local)
    • $HOME/myproj/.rbenv-version
  • シェルのプロセス固有 *2 の設定 (shell)
    • RBENV_VERSION environment variable

つまり rbenv version-origin の出力が:

  • global の設定ファイルに一致するならば global
  • global の設定ファイルに一致せず、ファイルとして読取可能ならば local
  • それ以外は shell

という風になる。

それでこのような zshスクリプトを書いた。たぶん bash でも動く。

dotfiles/.zsh.d/functions/llenv_version_origin at 78327cd0349b53686cacada45b1252a2cd38a95f · aereal/dotfiles · GitHub

*1:以下、plenv や pyenv など anyenv で管理できるものについてはそれぞれに読み替える

*2:厳密には環境変数 RBENV_VERSION が export されているあいだ

ログインシェルに fish を指定しているときに Vim の system 関数を実行すると E484 が発生する

解決

set shell=/bin/sh する。あるいは POSIX 互換のシェルを shell オプションに設定する。

原因

Vimsystem 関数はシェルに文字列を渡してコマンドを実行しようとするが、実行するシェルが POSIX 互換であることを期待している。

Homebrew で入れた Pow が起動しなくなる問題の解決

brew install pow したあと brew info pow に書かれている以下の手順でインストールした Pow が突然起動しなくなった。

sudo pow --install-system
pow --install-local

原因

~/Library/LaunchAgents/cx.pow.powd.plist にインストールされるプロパティ・リストの起動時の引数として Homebrew でインストールした noderealpath が書かれているが、この realpath にはバージョン番号が含まれているため、Pow をインストールした時点から node のバージョンが変わることによって存在しないパスを参照して起動に失敗した。

symlink を参照しても特に支障はないと考えたので起動時の引数を変更した。

diff --git a/cx.pow.powd.plist b/cx.pow.powd.plist
index e6e4e27..ded9906 100644
--- a/cx.pow.powd.plist
+++ b/cx.pow.powd.plist
@@ -6,8 +6,7 @@
         <string>cx.pow.powd</string>
         <key>ProgramArguments</key>
         <array>
-                <string>/opt/homebrew/Cellar/node/0.10.24/bin/node</string>
-                <string>/opt/homebrew/Cellar/pow/0.4.1/libexec/bin/pow</string>
+                <string>/opt/homebrew/bin/pow</string>
         </array>
         <key>KeepAlive</key>
         <true/>

結論

  • launchd に登録するプロパティ・リストには標準出力・標準エラー出力のリダイレクト先も指定しておく
    • StandardOutPath
    • StandardErrorPath

Go-lang で書かれた Fast GitHub command line client: gh を試している

jingweno/gh · GitHub

Go で書かれた hub の port のひとつ、と表現するのが簡潔でわかりやすい。

インストールの方法はいろいろある

拡張・追加しているサブコマンドは hub のそれとあまり変わらない。

hub のおよそ2倍ほど速いので、alias git=gh してもそれほどストレスを感じない。

コードもそれほど規模も大きくなくあまり凝ったことをしていないので Go-lang のコード・リーディングにもまあまあよさそう。

かばん情報

情報が集まっているので僕も提供します。

通勤、散歩

master-piece | MSPC PRODUCT : Effect No.12341

http://www.master-piece.co.jp/products/effect12341/12341-01.jpg

これのベージュを使っている。

通勤 (徒歩20分) やカメラを持っての散歩に使っている。一番使う頻度が高い。

なぜ大きくて重い一眼レフを毎日持ち歩いているかというと、昼休みにでかけて写真を撮るのが日課でありリフレッシュするための重要なアクティビティで、自分が写真を撮るとき最も信頼している道具が大きくて重たい一眼レフであるところの K-3 だからである。

モバイルバッテリの類は持ち歩いていない。平日はオフィスで仕事をしていて電源には困らず、休日など撮影にでかけるときはカメラを手にしている時間が長く、地図を見るなどの使い方の範囲では HTC J One は充分に電池が持つので信頼している。

休日は MacBook基本的に持ち歩かない。

休日などに撮影がてら散歩するときはのべ6〜7時間くらい鞄を背負ったまま歩いたり立っているので、中身は絞ってとにかくできるだけ身軽であろうとしている。

また、移動は大半が徒歩か鉄道であり、徒歩のときは考え事をする重要な時間だし、鉄道に乗って景観を楽しんでいるので、いわゆる暇潰し用のガジェットはいらず、スマートフォン (HTC J One) ひとつで事済んでいる。

気に入っているところ
  • 軽い (700g)
  • ちょっと雨にあたっても大丈夫 (撥水加工してある)
  • いいところにポケットがある
気に入っていないところ
  • ラップトップを入れるところがついていないのでパタパタする
  • K-3 + FA 77mm を入れるとちょっときつい
  • 1室しかなくてごちゃごちゃしがち
中身の様子 (通勤)

f:id:aereal:20140114022331j:plain

  • MacBook Pro with Retina Display 13インチ
  • PENTAX K-3 + smc PENTAX FA 77mm F1.8 Limited
  • Black Rapid R-ストラップ METRO
  • 財布
  • ケータイ
  • イヤフォン
    • 今まで使っていたやつが壊れたので HTC J One についてた試供品を使っている

ちなみにストラップは Black Rapid の R-ストラップという製品で、長さの調節が簡単だったり着脱が簡単だとかあってとても便利。

R-ストラップ METRO/メトロ

R-ストラップ METRO/メトロ

休日は MacBook が抜けて、代わりにクッションケースにレンズを1本入れたものを足したり、GXR を足したりする。

外出用 (1泊くらい)

Cote & Ciel のメッセンジャーバッグを使っている。

Cote&Ciel Laptop Messenger 2012 for 15 NEW TOFFY BROWN

Cote&Ciel Laptop Messenger 2012 for 15 NEW TOFFY BROWN

帰省するとき、東京に行くときに何度か使った。おしゃれな見た目に惚れて買ったけれどあまり使っていない。

17インチまで入る大きいサイズを買ったのだけれども、物はたくさん入るが、それに耐えられる肩がないので実用的ではない。このかばん自体がそこそこ重い (1kg くらい)。

着替えなどを持つ必要のある外出が1年に数回しかなく、そのうちのほとんど (あるいは全部) が帰省であり、その時にはトランクケースを持っていくことが多いのでやっぱり使う頻度は少ない。

気に入っているところ
  • ラップトップを入れる専用のコンパートメントがある
  • かわいい
  • 色がいい
  • アクセスしやすい外側にポケットが2つある
気に入っていないところ
  • 重い (これだけで 1kg くらいある)
  • 汚れが目立ちやすい (色がくすむ)
  • コットンキャンバスなので雨に濡れるとだめそう
  • マチが短いのでカメラを入れるのにあまり向いていない
  • 大きすぎる
    • たくさんものが入れても先に肩がおかしくなるので実用的ではない

雑談 (1)

余談だけれども、「これさえあれば (ある程度の妥協はありつつも) だいたいなんとかなる」的なデバイスとしてスマートフォンは存在していると思っているので、スマートフォンを持ちながらさらにごちゃごちゃとガジェットの類を持ち歩くのは前時代的だと思っているのでタブレットは持ち歩かないことにしている。*1

雑談 (2)

一眼レフを持ち歩くことについて、まあまあ葛藤もある。

  • そもそもカメラを持ち歩くこともないのではないか
  • もっと小さいカメラを使えばいいのではないか

OM-D E-M1 とか α7R とか見て、小さいなあ、と感心したし、けっこうぐらっと来た。α7R はともかく OM-D E-M1 はマイクロフォーサーズフランジバックが短いという利点を最大限に活かした小型化が行き届いていて素晴らしいなあ、と思う。

また、GXR や過去に持っていた SIGMA DP3 Merrill などコンデジもよく撮れるカメラだってたくさんある。

操作性がどうのという話もあるが、けっきょく FA 77mm に完全に参ってしまっており、これがある限りちょっとやそっとのことでは他のカメラシステムには手を出せないな、と思った。(他のレンズ交換式カメラも調べたけれど、これに匹敵するほどコンパクトで好みの写りをするレンズは見つけられなかった)

学び

  • そこそこ重いもの (2, 3kg〜) を持ち歩くならバックパックのほうがよい
  • ショルダーバッグにたくさんものを入れても重くて人間が耐えられない
  • 少なくともラップトップ用のコンパートメントがあると便利
  • 持ち歩くものを減らせば心身共に負担が減る

*1:けれども Kindle Paperwhite はかさばらないしいいかな、ってちょっと思っている

AquaSKK をインストールする Cask を書いた

homebrew-cask

homebrew-cask という OS XGUI アプリケーション (*.app のこと) も Homebrew のような DSL で管理できたらいいじゃん、という発想に基づいたプロジェクトがある。

homebrew-cask は tap という Homebrew に formula を追加する仕組みの上にできていてなかなか筋がよいと思う。

Cask を書く

自分は IME として AquaSKK を利用しているので、homebrew-cask を使ってインストールできるようにしようと思う。

homebrew-cask/CONTRIBUTING.md at master · phinze/homebrew-cask · GitHub

Cask *1 の書き方は上記のとおり、Formula と似ている。

Uninstall のサポートが興味深い。

OS XGUI アプリケーションはインストールされたパスではないところに設定などを保存したりする場合があるので後片付け処理を行わないといけないので、そのためのサポートが含まれている。

AquaSKK は pkg 形式で配付されているので、uninstall メソッドに :pkgutil オプションを渡す。

Cask を提供する tap をつくる

リポジトリ・ルート下にある Casks/*.rb を Cask として認識するようだった。

注意しなければいけない点として、tap として妥当なリポジトリ名の正規表現(homebrew-)?(\w+) なので - (ハイフン) は使えない。

In a nutshell, your repository name can only contain letters, numbers, and underscores.

brew tap · Homebrew/homebrew Wiki · GitHub

それでできた tap:

README に書いてあるとおり、brew tap aereal/homebrew-aereal_casks を実行すると使えるようになる。

brew cask install aquaskkAquaSKK がインストールできるようになる。

どうぞご利用ください。

*1:Homebrew で言う Formula

OS X の Network Locations を使ってプロキシの設定を分ける

SOCKS プロキシ

社内サーバなどファイアウォールの内側にあるサーバに SSH するために SOCKS プロキシを経由する必要がある。

また ProxyChains のようなソフトウェアを使って SOCKS プロキシ下でも名前解決ができるようにしたい。(参考: (ProxyChainsの最新版でSOCKS5プロキシを使った名前解決が出来るようになってた - yanbe.diff - subtech])

下記のような proxy.pac を書くと名前解決ができるようになる。

function FindProxyForURL(url, host) {
  if (/private\.host$/.test(host)) {
    return "SOCKS5 127.0.0.1:9050";
  else {
    return "DIRECT";
  }
}

ところでいつでも SOCKS プロキシを使いたいわけではない。SOCKS プロキシを使いたいのはリモートで作業する (自宅勤務、障害対応) ときなので。

都度、プロキシの設定を手で変えるのは煩雑なので自動化しやすい方法を考えたい。

Network Locations

そこで OS X の Network Locations を使う。(Network) Location とはネットワークの設定をまとめたものである。

What is a "location?"

In the Network preference pane of System Preferences, a location is a set of network preferences.

Using network locations (Mac OS X v10.6 and later)

(ちなみに最初から "Automatic" (ロケールによっては「自動」) という Location が存在している。)

Location を新たに作るには “System Preferences.app” で “Network” を開いて GUI で操作する方法 (詳しくはApple のドキュメントに書いてある) と、networksetup コマンドを使う方法とがある。(こちらも man networksetup すると詳細が読める)

Location ごとにプロキシの設定を含めたネットワークに関する設定を分けることができる。

たとえば nomad という Location を自宅作業用につくる。この Location に対してプロキシの設定を行う。nomad という Location を選択しているあいだはこの設定が有効になり、別の Location に切り替えると設定も切り替わる。

DNS の設定なども Location ごとに分けられるので、たとえば Google Public DNS を使う場合と使わない場合で分ける、といった使い方が考えられる。

ほかにも networksetup コマンドは Network.prefpane で編集できる設定はだいたい編集できるようだった。

はてなブックマーク REST API のクライアントライブラリ in Ruby

aereal/hatena-bookmark-restful · GitHub

JSON over HTTP な API であるのではたして「クライアントライブラリ」が必要なのか怪しい気もするけれど、手軽に API を利用しようと思ったときに生の Hash じゃなくてちゃんとオブジェクトが返ってくると嬉しいこともあるだろうと思って書いた。

どうぞご利用ください。

ついでにおしゃれポイントについて書いておく。

*1:この表現が正しいのかはわからない、include する module or class

2013→2014

2013年のこのブログではなんらかのトピック (たいていはソフトウェア技術) に関してなんらかの成果を生み出したら書く、というようなルールで概ね運用されていた。

自分の中で「成果」=「結果」に対するハードルが高くなりすぎた結果、なにか書こうと思っても「これはちょっと……」と思うことがあって手が止まることがあった。

本当はこのブログに書いてきた以上になにかしらの取り組みを行ってきた *1 ので、今年はそれを記していくことを疎かにしない。

きちんと試行錯誤を記録する。

*1:社内ブログ見たらたくさん書いてあった

ソフトウェア・テストと Web サービスの寿命