CtrlPでcdnjs.comのURLを入力するctrlp-cdnjsを作った

試しにちょろっとHTMLとJavaScript書いて確認とかしたいときに、jQueryとかのライブラリをダウンロードして用意するのは面倒なのでどっかのCDNから拝借することが多いんだけど、このURLを毎回ググってコピペするのがいい加減だるいのでVimのCtrlPで選択して入力できるようにしてみた。
extensionの作り方がよくわからなかったのでmattnさんのextensionをパクり参考にした。



https://github.com/pasela/ctrlp-cdnjs


RetinaなせいなのかLICEcapでキャプチャすると滲んだみたいになる。もっと綺麗に撮る方法ないかな?

使い方

このextensionはファイルを開いたりするわけではないので、ちょっと行儀悪いと思いつつも以下のように割り当てを変えてある。

キー 動作
Enter URLを挿入する
Ctrl+T scriptタグ(cssの場合はlinkタグ)を挿入する
Ctrl+S URLスキームをhttp→httpsscheme-lessと切り替える
Ctrl+V cdnjs.com上のライブラリページをブラウザで開く(要open-browser.vim)

挿入されるURLのスキームはデフォルトではhttp:になってて、Ctrl+Sを押すごとにhttps:、scheme-less(//example.comみたいなやつ)とローテートする。

苦労した点

jquery-なんちゃらがくっそ多くて、ただのjqueryが選択できない。
CtrlPは該当する候補のうち一部しかリストに表示されないので、

jquery-gamequery (v0.7.0)
jquery-color (v2.1.2)
jquery-easing (v1.3)
jquery-footable (v0.1.0)
jquery-browser (v0.0.6)

みたいになっちゃってjqueryが画面内に出てこない。
バージョンまで指定すればマッチするけど、バージョンとか知らんし。
正規表現モードにすればマッチ可能だけど面倒くさいしユーザに委ねられるのが気に入らない。
g:ctrlp_match_funcでマッチング処理をいじるというのも考えたけど、これもユーザ側でグローバルに設定する機能なのでダメ。


で、うまい解決方法が浮かばなかったんだけど、とりあえずリストをソートしておくことで誤魔化してみた。
候補はリスト順に出てくるみたいなので、ソートしてjqueryが先頭に来るようにしてあればjqueryと入力した時点でとりあえずjqueryが近い位置に来る。


extension毎にマッチング関数が定義できたり、前方一致でマッチングできればよかったかも。

ToDo

ライブラリのバージョンを選べるようにしたい

cdnjs.comには過去のバージョンなどもあるので、特定のバージョンも指定できるようになるといいかもしれないと思ったのだが、うまいインターフェイスが思いつかなかった。
全バージョンを候補に並べると鬱陶しいし、前述の表示数問題があるので絞りきれない。


バージョン絞り込み用のCtrlP呼び出しに繋ぐというのも考えたけど、できるのかわからないし微妙な感じがしたので試してない。

複数ファイル収録されてる場合に対応したい

ライブラリによっては複数ファイルだったり.jsと.cssがセットになってるものなどがあるので、そのへんもまとめて挿入できたりするといいなと思った。
しかしminimizeしてあるやつとそうでないやつとか、.mapとか、css内で使ってる画像ファイルだとかが混じってたりして、どれが必要なファイルか判別できなかったので諦めた。
そして代わりにCtrl+Vでライブラリの詳細ページを開けるようにした。そこで必要なやつはコピーしてもらおうという逃げ。

複数選択して一括挿入したい

例えばjqueryjquery-uiを選択してまとめて挿入とかしたかった。
opmulというオプションを指定するとCtrlP標準のファイル選択みたいにCtrl-Zで複数選択できるのはわかったんだけど、ハンドリング方法がわからなかった。

ライブラリ情報をキャッシュしたい

毎回cdnjs.comにお伺いするのもあれなのでキャッシュしたかったんだけど、CtrlPのキャッシュの仕組みがよくわからなかったし、F5押した時のハンドリングもわからなかった。独自に実装するしかない?


自分がよくわかってないだけかもしれないけど、どうも組み込み機能では使えるけどextensionでは使えない機能とかあるっぽい。

Macで使ってるアプリ(2014年版)

Macを初めて買った時に環境構築の記事を書いたのだけど、あれから4年経って内容も変わってきたので改めて今使っているアプリを列挙してみる。
いちおう、参考として(使ってないけど)候補にあがった競合アプリも挙げておきます。
なお、UNIX系のコマンドラインツールとかはそれだけで別の記事一本になりそうなので割愛。


特におすすめだとかそういうわけではないけど、どんなアプリがいいんだろうと探してる人の参考になればと。
自分もそうやって他人のおすすめアプリ記事とかを参考にしてここまで辿り着いたしね。


App Storeで公開されているアプリについてはApp Storeのリンクも載せておきますが、

などのトラップがときどきあるので、各自で公式サイトなどを確認してください。

環境系

KeyRemap4MacBook
Macのキーマップを色々と設定できるツール。必須。
バックスラッシュ問題とかcapsを殺すとかUSキーボードでcmdにかなを割り当てるとか。


BetterTouchTool
トラックパッドを色々と設定できるツール。必須。
標準設定以上に細かくジェスチャを設定できる。マウスやキーボードの設定も可能。


Google 日本語入力
ことえり爆発しろ!


HyperSwitch
cmd+tabのウィンドウ切り替えをウィンドウ単位にするやつ。
なんでMacはアプリ単位なん?


ClipMenu
クリップボードの履歴を管理するツール。
WindowsでいうとCLCLに近い。スクリプトでカスタマイズもできる。


Alfred2
コマンド型のランチャー。
ワークフローっていうのを作ったりしてカスタマイズできる。
なお、App Storeにあるやつはv1系で古いので注意。


Bartender
メニューバー右側のアイコン(Windowsでいうタスクトレイ的なやつ)を消したり、ポップアップするメニューバーに追いやったりできるようにするツール。
常駐物が多い人はこれつかうとメニューバーがスッキリする。


DragonDrop (App Store)
マウスでドラッグ中のもの(ファイル)とかを一旦画面上に置いておけるようにするツール。
うまく説明できないのでサイトの動画見てw


Synergy
ネットワーク越しにマウスとキーボードを共有するツール。
WindowsMacLinux混在でも大丈夫。
WindowsMacを並べて置いてて、行ったり来たりするのが面倒という人におすすめ。


Caffeine (App Store)
Macのスリープを防止するツール。
自宅でACアダプタ繋ぎっぱの時とか、いちいちスリープしてほしくない時にオンにしておく。
Mountain Lionからはcaffeinateっていうコマンドで同様のこともできるけど、こっちはメニューバーのボタンワンクリックなので簡単。


MuteCon
OSの起動音を消してくれるやつ。
最近はスリープでしか運用してないからあまりいらない気もする。

参考
  • ATOK: 定番IME。いいと思います。
  • Witch (App Store): ウィンドウ切り替え。HyperSwitchが出てくるまではこれだった。
  • Pasteboard Recorder: クリップボード履歴管理ツール。
  • LaunchBar: コマンド型のランチャー。Alfred2に乗り換えるまで使ってました。
  • QuickSilver: コマンド型のランチャー。LaunchBarに乗り換えるまd
  • Growl (App Store): 定番の通知アプリ。最近は通知センターでいいかな、とか。

ネット

Google Chrome
なにはともあれ。


Firefox
いちおうFirefoxも。


Thunderbird
定番のメーラー
標準のMail.appだと仕事に使いづらいので。


LimeChat (App Store)
定番IRCクライアント。
なにげに動画のサムネイルとか表示されるのが素敵。


夜フクロウ (App Store)
定番Twitterクライアント。


Skype
とりあえず入れておいた。


IP Messenger for MacOS X
仕事だと相変わらずIP Messengerが使われる……。


iTerm
定番のターミナルクライアント。
標準のTerminal.appよりこっちのほうが好き。


Cyberduck (App Store)
FTPとかSCPとかWebDAVとかS3とかの転送クライアント。
公式サイトだと無料だけど、App Storeだと2400円ぐらいする。謎。寄付なのかな?

オンラインサービス系

Dropbox
Dropboxのクライアント。


Evernote (App Store)
Evernoteのクライアント。


Skitch (App Store)
画面キャプチャツール。
Evernoteとサービスが統合された。

参考

エディタ

MacVim-KaoriYa
Vim最高!


Atom
GitHubが出してるやつ。Sublime Textっぽい。


Markdown Pro (App Store)
markdownエディタ。
激安だったか無料だったかのセールの時に飛びついただけで正直使ってない……w


Marked (App Store)
markdownエディタ。
こちらもセールの時に(ry

参考

ファイラー

Path Finder
定番の二画面+タブファイラー。
カスタマイズも柔軟にできる。
キーバインドも自由に設定できるけど、キーボードファイラーのような操作体系にまではできない。

参考

音楽&動画

VLC
定番動画プレイヤー。


HUDTube (App Store)
ブラウザからドラッグ&ドロップしたURLを再生するミニプレイヤーみたいなやつ。

アーカイバ

The Unarchiver (App Store)
定番のアーカイバ(展開のみ)。
ファイル名のエンコーディングとかも指定できる。

参考
  • keka (App Store): 定番の圧縮・展開ツール。アイコンがキモいw
  • CleanArchiver: リソースフォークだとか.DS_Storeとかを除外して圧縮できる。

オフィススイート

LibreOffice
MSとやりとりしなければ、だいたいはこれで足りてる。


Microsoft Office for Mac
仕事ではこっちが必要。
でもWindowsとやりとりするとやっぱり微妙。


Keynote (App Store)
Numbers (App Store)
Pages (App Store)
iWorkセット。Keynoteしか使ってないかも……。

開発系

Xcode (App Store)
これがないと何もできない。


Homebrew
主にビルドして使うライブラリとかツールを入れてくれるパッケージマネージャ。
yumとかaptとかpacmanみたいなやつ。


VirtualBox
定番の仮想化ソフトウェア。
主にVagrantと組み合わせて使ってます。


VMware Fusion
定番の仮想化ソフトウェア。
Windowsなどのデスクトップ環境はこっちで使ってる。


Vagrant
仮想マシンを宣言的な設定ファイルから一発で構築してくれるやつ。
今の流行り。


SourceTree
GitとMercurialGUIクライアント。
コマンドラインでしか作業しないけど、人に説明するときとかに使う。
なお、App Store版はサポート終了っぽくて公式サイトから入れ直せと言われる。


Eclipse
定番IDE
vimしか使わないのでどうでもいいけど、Eclipseで云々みたいな話になったときに仕方なく使う。


Dash (App Store)
APIリファレンスなどのプログラミング関係のドキュメントビューア。
たくさんのドキュメントがサポートされてる。しかもどんどん増えていく。


Apache Directory Studio
LDAP系データベースをGUIで操作できるツール。
あんなのコマンドラインで操作してられっか!


Robomongo
MongoDBのGUIクライアント。
見た目かっこいいし、スクリプトも実行できるし結構便利。

参考

デザイン系

Adobe Photoshop Elements
デザインのお仕事とかしないのでElementsでいいんです。


GIMP
Photoshopが無い時はこっちを。


FireAlpaca
MacWindowsで使えるフリーのペイントツール。


Inkscape
ドローツール。
IllustratorもElementsみたいなの出してくれませんかね、Adobeさん。


Sketch (App Store)
ドローツール。
セールの時にとりあえず手に入れたのであんまり使ってない。


Pencil
アプリケーションのプロトタイピングツール。
MacとかiPhoneとかのステンシルがあって画面をデザインするやつ。

その他

AppCleaner
アプリをクリーンにアンインストールするツール。
.appのほかに関連する設定ファイルなども削除してくれる。


TrueCrypt
定番のディスク暗号化ツール。
物理ディスク以外にファイルコンテナでの運用もできるので気軽に使える。


1Password (App Store)
パスワード管理ソフト。Windowsスマートフォン版もあって同期できる。
これなかったらパスワードの管理どうするの?ってぐらい。

参考

Raspberry Pi(Raspbian)にmDNSを設定する

Raspberry Piにディスプレイもキーボードも繋がずに部屋の隅っこに転がしておいてリモートからアクセスするには、IPアドレスを知らないといけないわけだけど、せっかくのポータブルなRasPiに固定IPアドレスを設定するのも微妙な感じがするので、mDNSを活用してみることにした。
Appleが好きなアレ。コンピュータ名.localでアクセスできるやつ。


とりあえず、今回はRaspberry PiをなんとかしたかったのでRaspbianの内容だけど、CentOSでもUbuntuでもArch Linuxでもパッケージ名が違ったりするぐらいでだいたい同じ。

説明とかどうでもいい人向け

# ホスト名をきちんと設定する
sudo -e /etc/hostname

# avahi-daemonとnss-mdnsをインストール
sudo apt-get install avahi-daemon libnss-mdns

# avahiにsshサービス追加
sudo -e /etc/avahi/services/ssh.service

    中身
    ----------------
    <?xml version="1.0" standalone='no'?>
    <!DOCTYPE service-group SYSTEM "avahi-service.dtd">

    <service-group>
      <name replace-wildcards="yes">%h</name>

      <service>
        <type>_ssh._tcp</type>
        <port>22</port>
      </service>
    </service-group>
    ----------------

# 再起動
sudo reboot

ホスト名の設定

アクセスするためのドメインが"ホスト名.local"になるので、なにはともあれホスト名を設定する。

sudo -e /etc/hostname
paseraspi

avahi-daemonとnss-mdnsのインストール

sudo apt-get install avahi-daemon libnss-mdns


ちなみにavahiがmDNS/DNS-SDの実装で主にresponderとして使う感じ*1で、nss-mdnsの方はNSSのhostsでmDNSによる名前解決をサポートするためのプラグイン
ざっくり言うとavahi-daemonがこのマシンをmDNSで発見してもらうためのサーバで、nss-mdnsが別のマシンをmDNSで見つけるためのクライアントみたいな感じ。
なので、今回の用途だとavahi-daemonだけあればよくて、RasPiからどっかへ.localでアクセスする気がないならlibnss-mdnsはなくてもいいかも。

avahiの設定

/etc/avahi/servicesに応答させたいサービスの設定ファイルを作る。
例えばsshならこんな感じ。中身についてはman avahi.serviceで。

sudo -e /etc/avahi/services/ssh.service
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">

<service-group>
  <name replace-wildcards="yes">%h</name>

  <service>
    <type>_ssh._tcp</type>
    <port>22</port>
  </service>
</service-group>

で、avahi-daemon再起動。

sudo /etc/init.d/avahi-daemon restart

あとiptablesとかでファイアウォールを設定している場合は、224.0.0.251:5353宛のUDPを通す必要がある。


これで"ホスト名.local"でRaspberry Piにアクセスできるようになったはず。

nss-mdnsの設定

/etc/nsswitch.confのhosts項目を書き換えるんだけど、インストールした時点で自動的に書き換えられてるはず。

sudo -e /etc/nsswitch.conf
hosts:          files mdns4_minimal [NOTFOUND=return] dns mdns4

再起動とかは特にない。

avahi-browse

avahi-utilsに入ってるavahi-browseを使うとネットワーク内の利用可能なサービスを一覧表示できる。

sudo apt-get install avahi-utils
avahi-browse -ar

*1:avahi-browseとかもある

SassとCompassを使ってみる

完全に遅れてる感があるけど、今更ながらにSassとCompassの環境を整えてみた。
前置きとかどうでもいい人は「インストール」とかその辺の見出しだけ読んでください。
ぶっちゃけgem installとcompileとかwatchをちょろっとやってるだけなので、既に使いこなしてる人はそっとタブを閉じると時間が節約できます。

Sass

Sass - Syntactically Awesome Stylesheets
http://sass-lang.com/


SassはCSSをもっと便利で効率的にコーディングするための技術。CSSメタ言語
競合するものとしてLESSStylusもあるけど、最近はCompassとのセットでSassが流行ってる様子。


Sassを使うとCSSがこんな風に書けるようになる。

/* sass */
$item_color: #3bbfce

#navbar
  width: 80%
  height: 23px
  ul
    list-style-type: none
    li
      float: left
      a
        color: darken($item_color, 9%)

これをコンパイルすると下のようなCSSが生成される。

/* css */
#navbar {
  width: 80%;
  height: 23px;
}
#navbar ul {
  list-style-type: none;
}
#navbar ul li {
  float: left;
}
#navbar ul li a {
  color: #2ca2af;
}

SassはHamlSlimのようなインデントでネストを表現する。
その他にも変数や関数や継承といったプログラミング的なことができる。


それとSassにはSCSS(Sassy CSS)という普通のCSSを拡張したような記法も用意されている。
というかSCSSはCSS3のスーパーセット的な文法になっていて、普通のCSSはSCSSとしても扱える。ので、とりあえず普通にCSSで書いて、少しずつ慣れていきたい場合はSCSSで書くと良いかもしれない。


ちなみに上記の例をSCSSで書くとこんな感じになる。

$item_color: #3bbfce;

#navbar {
  width: 80%;
  height: 23px;
  ul {
    list-style-type: none;
    li {
      float: left;
      a {
        color: darken($item_color, 9%)
      }
    }
  }
}


細かい機能については公式マニュアルや色々な解説サイトを見てもらうとして、早速使ってみる。

インストール

SassはRubyでできてるのでRubyが入っていることが前提となる。
Macなら標準で入っているもの、Windowsなら別途RubyInstallerなどで入れたものを使う。もちろんrbenvで入れたものでもよい。


Sassはgemになってるので普通にgemコマンドでインストールができる。

sudo gem install sass

これでsassコマンドが使えるようになる。

sass -v
Sass 3.2.10 (Media Mark)
sass -h
Usage: sass [options] [INPUT] [OUTPUT]

Description:
  Converts SCSS or Sass files to CSS.

Options:
                :
                :

コンパイル

sass/scssファイルのコンパイルはこんな感じ。

sass example.sass example.css

出力ファイルを省略すると画面に表示される。


他に--style で出力されるCSSの形式を制御できる。
デフォルトはnestedで、インデントされた感じで出力され、compressedにすると一行で出力される。
ちなみに上の例はexpandedで出力した。

ファイルを編集したら自動的にコンパイルする

--watchというオプションを使用すると、ファイルの変更があったら自動的にコンパイルしてくれるモードで起動ができる。
入力と出力はコロンで区切って指定するので注意。

# ファイルを指定する例
sass --watch example.sass:example.css

# ディレクトリを指定する例
sass --watch sass:css

こちらはファイルだけでなくディレクトリも指定できるので、sass:cssとか指定して起動しておくと便利。
これを起動した状態でsass/example.sassを編集すると、自動的にコンパイルされたものがcss/example.cssに生成される。


とりあえず簡単な使い方はこんなところ。
あとは-hを眺めるとかマニュアルを眺めるとかググるとかして新しい発見をしよう。

Compass

Compass Home | Compass Documentation
http://compass-style.org/


CompassはSassを利用したCSSフレームワーク集(?)で、色々なmixin集とかスプライトの自動生成とか便利な機能が揃ったもの。


例えばこんな感じに書くと…

@import "compass";

.sample {
  @include border-radius(2px);
}

こんな感じのCSSにしてくれる。

/* line 3, ../sass/example.scss */
.sample {
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  -ms-border-radius: 2px;
  -o-border-radius: 2px;
  border-radius: 2px;
}

他にもCSSリセットとかbox-shadowとか色々あって、それらをベンダープレフィクスだけでなくクロスブラウザも考慮して自動的に変換してくれる。

スプライト

さらにCompassを使うとスプライト用画像とそれを使うためのCSSも自動的に生成してくれる。


たとえばこんな感じにアイコンファイルがあったとして、

images/my-icons/new.png
images/my-icons/edit.png
images/my-icons/save.png
images/my-icons/delete.png

こんなscssを書くと…

@import "my-icons/*.png";
@include all-my-icons-sprites;

こんな画像ファイルとcssが生成される。

images/my-icons-s5dcefb3c8d.png
/* line 66, my-icons/*.png */
.my-icons-sprite, .my-icons-delete, .my-icons-edit, .my-icons-new, .my-icons-save {
  background: url('/images/my-icons-s5dcefb3c8d.png') no-repeat;
}

.my-icons-delete {
  background-position: 0 -32px;
}

.my-icons-edit {
  background-position: 0 -64px;
}

.my-icons-new {
  background-position: 0 -96px;
}

.my-icons-save {
  background-position: 0 0;
}

もう頑張って切り貼りしたりスプライト生成サイトを使わなくてもいい!


ほかにもいっぱいいっぱい機能があるけど、それらについては公式マニュアルや色々な解説サイトを見てもらうとして、早速使ってみる。

インストール

CompassRubyでできてるのでRubyが入っていることが前提となる。というかSassを使ってるので必然的にRubyになる。
Macなら標準で入っているもの、Windowsなら別途RubyInstaller(ry


Compassもgemになってるので普通にgemコマンドでインストールができる。

sudo gem install compass

これでcompassコマンドが使えるようになる。

compass -v
Compass 0.12.2 (Alnilam)
Copyright (c) 2008-2013 Chris Eppstein
Released under the MIT License.
Compass is charityware.
Please make a tax deductable donation for a worthy cause: http://umdf.org/compass
compass -h
Usage: compass help [command]

Description:
  The Compass Stylesheet Authoring Framework helps you
  build and maintain your stylesheets and makes it easy
  for you to use stylesheet libraries provided by others.
                :
                :

プロジェクトの作成

CompassCSSや画像などの他にベースURLやコンパイルの仕方などを設定するファイルがセットになったプロジェクトディレクトリで作業することになる。

compass create example1

するとexample1ディレクトリに初期ファイルが作成されて、簡単な使い方などが表示される。

directory example1/
directory example1/sass/
directory example1/stylesheets/
   create example1/config.rb
   create example1/sass/screen.scss
   create example1/sass/print.scss
   create example1/sass/ie.scss
   create example1/stylesheets/ie.css
   create example1/stylesheets/print.css
   create example1/stylesheets/screen.css

*********************************************************************
Congratulations! Your compass project has been created.

You may now add and edit sass stylesheets in the sass subdirectory of your project.

Sass files beginning with an underscore are called partials and won't be
compiled to CSS, but they can be imported into other sass stylesheets.

You can configure your project by editing the config.rb configuration file.

You must compile your sass stylesheets into CSS when they change.
This can be done in one of the following ways:
  1. To compile on demand:
     compass compile [path/to/project]
  2. To monitor your project for changes and automatically recompile:
     compass watch [path/to/project]
                    :
                    :

ちなみに--css-dirなどのオプションで出来上がるディレクトリの名前などを指定したりもできる。
compass help createしてみると色々なオプションの説明が出てくる。
またconfig.rbの中にcss_dirなどの項目が書かれているので、ここを変更してもよい。

コンパイル

sassディレクトリの中のファイルを編集して、プロジェクトディレクトリでcompileを実行すると全てのファイルをコンパイルしてcssファイルを作成してくれる。
sassコマンドの時みたいにファイルやディレクトリを指定する必要はない。

compass compile

ファイルを編集したら自動的にコンパイルする

Compasswatchというコマンドを使用すると、ファイルの変更があったら自動的にコンパイルしてくれるモードで起動ができる。

compass watch

こちらもファイルやディレクトリを指定する必要はない。


とりあえず簡単な使い方はこんなところ。
あとはhelpを眺めるとかマニュアルを眺めるとかググるとかして新しい発見をしよう。


ちなみにコマンドのヘルプはhelpで表示できる。

compass help コマンド(watchとか)

compass statsでCSSの項目を有効にする(2013-09-30追記)

statsコマンドを使うとこんな情報が確認できるが、css_parserが入ってない場合はCSSの項目がDISABLEDになってしまう。
そういう場合は一番最後に書かれているようにcss_parser gemを入れてあげると対応される。

compass stats
unchanged sass/ie.scss
unchanged sass/print.scss
unchanged sass/screen.sass
unchanged sass/screen.scss
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |
| Filename         | Rules | Properties |    Mixins Defs | Mixins Used |      Filesize | CSS Selectors | CSS Properties |   CSS Filesize |
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |
| sass/ie.scss     |     0 |          0 |              0 |           0 |         271 B |      DISABLED |       DISABLED |
| sass/print.scss  |     0 |          0 |              0 |           0 |         213 B |      DISABLED |       DISABLED |
| sass/screen.sass |     4 |          4 |              0 |           0 |         121 B |      DISABLED |       DISABLED |
| sass/screen.scss |     2 |          1 |              0 |           0 |         341 B |      DISABLED |       DISABLED |
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |
| Total (4 files): |     6 |          5 |              0 |           0 |         946 B |             0 |              0 |            0 B |
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |

Install css_parser to enable stats on your css files:

	gem install css_parser

css_parserを入れる。

sudo gem install css_parser
compass stats
unchanged sass/ie.scss
unchanged sass/print.scss
unchanged sass/screen.sass
unchanged sass/screen.scss
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |
| Filename         | Rules | Properties |    Mixins Defs | Mixins Used |      Filesize | CSS Selectors | CSS Properties |   CSS Filesize |
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |
| sass/ie.scss     |     0 |          0 |              0 |           0 |         271 B |             0 |              0 |          271 B |
| sass/print.scss  |     0 |          0 |              0 |           0 |         213 B |             0 |              0 |          213 B |
| sass/screen.sass |     4 |          4 |              0 |           0 |         121 B |             2 |              4 |          185 B |
| sass/screen.scss |     2 |          1 |              0 |           0 |         341 B |             2 |              4 |          185 B |
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |
| Total (4 files): |     6 |          5 |              0 |           0 |         946 B |             4 |              8 |          854 B |
| ---------------- | ----- | ---------- | -------------- | ----------- | ------------- | ------------- | -------------- | -------------- |

binaryへのキャストって……?

昨日の「NULLへのキャストって……?」ではスルーしたけど、マニュアルの引用部分にあった(binary)も気になった人がいるはず。


使用可能なキャストを以下に示します。

  • (int), (integer) - 整数へのキャスト
  • (bool), (boolean) - 論理値へのキャスト
  • (float), (double), (real) - float へのキャスト
  • (string) - 文字列へのキャスト
  • (array) - 配列へのキャスト
  • (object) - オブジェクトへのキャスト
  • (unset) - NULL へのキャスト (PHP 5)

(binary) によるキャストや b プレフィックスのサポートは、PHP 5.2.1 で追加されました。

リストには入ってないけど、最後にしれっと一文追加されてるやつ。具体的な説明がなにも書かれていないのでどう使うものなのかさっぱりわからない。


先のマニュアルにはこのような例が載っている。


リテラル文字列や変数を、バイナリ文字列にキャストします。

<?php
$binary = (binary) $string;
$binary = b"binary string";
?>

しかし、PHPの文字列は元から(内部エンコーディングなどを持たない)ただのバイト列*1なので、わざわざキャストする意味がわからない。
試しにこんなことをしてみるが、なにか変わったようには見えない。

<?php
var_dump('こんにちは');                           // string(15) "こんにちは"
var_dump(b'こんにちは');                          // string(15) "こんにちは"
var_dump((binary)'こんにちは');                   // string(15) "こんにちは"
var_dump('こんにちは' === (binary)'こんにちは');  // bool(true)
var_dump('こんにちは' === b'こんにちは');         // bool(true)
?>

実際、ちょうど手元にあったPHP 5.4.13のzend_language_scanner.lではこのように定義されていた。

<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("string"|"binary"){TABS_AND_SPACES}")" {
    return T_STRING_CAST;
}

実はPHP6への布石だった?

どうもこれ、(かつての構想の)PHP6で内部実装がUnicodeになることへの布石だったようで、現在では特に意味が無いっぽい。
Unicode文字列がデフォルトになった時にバイト列を表現するために用意されているものらしい。
しかしPHP6でのUnicode化は断念して現在の5.3〜の道を歩んでるので……いらない子

NULLへのキャストって……?

PHPの型キャストは(array)とか(object)とか変態的なのがあるけど、最近(unset)なるものが存在することに気づいた。
unset($var)のことではない。(unset)$varだ。


使用可能なキャストを以下に示します。

  • (int), (integer) - 整数へのキャスト
  • (bool), (boolean) - 論理値へのキャスト
  • (float), (double), (real) - float へのキャスト
  • (string) - 文字列へのキャスト
  • (array) - 配列へのキャスト
  • (object) - オブジェクトへのキャスト
  • (unset) - NULL へのキャスト (PHP 5)

(binary) によるキャストや b プレフィックスのサポートは、PHP 5.2.1 で追加されました。

NULLへのキャスト?

<?php
$foo = 'test';
$bar = (unset)$foo;
var_dump($bar);                   // NULL

var_dump((unset)'string');        // NULL
var_dump((unset)12345);           // NULL
var_dump((unset)true);            // NULL
var_dump((unset)null);            // NULL
var_dump((unset)(new StdClass));  // NULL
?>

なるほど、NULLになるな。
で、これ何に使うの??

<?php
$bar = NULL;
?>

じゃだめなんですか!?


ググってもunset()のことばかり出てきて調べるのが大変なんだけど、Stack Overflowで2件ほど同様の疑問を投げかける投稿が見つかった。

回答の中にはこんな例が出ていたけど、わざわざこう書く理由がわからないし、回答者自身も含めて「うーん」な感じで終わってる模様。

<?php
$foo = bar((unset) baz());
?>
<?php
function fallback()
{
    // some stuff here
    return 'zoo';
}

var_dump(false ? 'foo' : fallback()); // zoo
var_dump(false ? 'foo' : (unset) fallback()); // null
?>


ソースコードをちらっと見てみたけど、型(?)の分だけ*1とりあえずキャスト用意しておきました感しかなくて意図がよくわからなかった。

(array)$var

ちなみに(array)はこんな感じ。
オブジェクトとNULLを除いて、自身を要素に持つ配列になる。

<?php
class Foo {
    public    $x = 10;
    protected $y = 20;
    private   $z = 30;
    function foo() {}
}
$foo = new Foo;

var_dump((array)'string');                    // (1)
var_dump((array)123);                         // (2)
var_dump((array)true);                        // (3)
var_dump((array)array(10, 20, 30));           // (4)
var_dump((array)array('x' => 10, 'y' => 20)); // (5)
var_dump((array)$foo);                        // (6)
var_dump((array)null);                        // (7)
?>
array(1) {                      // (1)
  [0] => string(6) "string"
}
array(1) {                      // (2)
  [0] => int(123)
}
array(1) {                      // (3)
  [0] => bool(true)
}
array(3) {                      // (4)
  [0] => int(10)
  [1] => int(20)
  [2] => int(30)
}
array(2) {                      // (5)
  'x' => int(10)
  'y' => int(20)
}
array(3) {                      // (6)
  'x'        => int(10)
  '\0*\0y'   => int(20)
  '\0Foo\0z' => int(20)
}
array(0) { }                    // (7)

NULLは自身を値に持つ配列ではなくて、空配列になる。
オブジェクトはなんか面倒なことになるので避けたほうがいい。


こういう感じで、1個の時はスカラ値でも渡せる関数…みたいなやつで時折見かける。

<?php
function do_something($item) {
    foreach ((array)$item as $x) {
        echo $x;
    }
}

do_something('foo');
do_something(array('foo', 'bar', 'baz'));
?>

(object)$var

(object)はこんな感じ。

<?php
var_dump((object)'string');                     // (1)
var_dump((object)123);                          // (2)
var_dump((object)true);                         // (3)
var_dump((object)array(10, 20, 30));            // (4)
var_dump((object)array('x' => 10, 'y' => 20));  // (5)
var_dump((object)$foo);                         // (6)
var_dump((object)null);                         // (7)
?>
class stdClass#1 (1) {                  // (1)
  public $scalar => string(6) "string"
}
class stdClass#1 (1) {                  // (2)
  public $scalar => int(123)
}
class stdClass#1 (1) {                  // (3)
  public $scalar => bool(true)
}
class stdClass#1 (3) {                  // (4)
    int(10)
    int(20)
    int(30)
}
class stdClass#2 (2) {                  // (5)
  public $x => int(10)
  public $y => int(20)
}
class Foo#1 (3) {                       // (6)
  public    $x => int(10)
  protected $y => int(20)
  private   $z => int(30)
}
class stdClass#1 (0) { }                // (7)

stdClassのインスタンスになる。
オブジェクトはそのまま。
連想配列はわかるけど、普通の配列はどういう状況なのかよくわからない。
というか連想配列もキーによってはやばい感じがある。

<?php
var_dump((object)array('x a b' => 10, 'てすと' => 20));
?>
class stdClass#2 (2) {
  public $x a b  => int(10)
  public $てすと => int(20)
}



オブジェクトがオブジェクトに変換される場合、それは修正されません。 他の型の値がオブジェクトに変換される場合、ビルトインクラスである stdClass の新しいインスタンスが生成されます。 値が null の場合、新しいインスタンスは空となります。 配列がオブジェクトに変換される場合、配列のキーがプロパティ名となり、 配列の値がプロパティの値となります。他の値の場合、 scalar という名前のメンバ変数が値を格納します。

*1:resource型などはなかった。

plenvとpyenvに乗り換えた

今までPerlはperlbrew、Pythonはpythonbrewを使っていたのだけど、最近なんとかenvみたいなのが流行ってるらしいので乗り換えてみた。


乗り換え動機

  • pythonbrewはメンテナンスされなくなったらしい*1
  • Rubyでrbenvを使ってるので同じようなやつで揃えたい

plenv

https://github.com/tokuhirom/plenv


基本的にはINSTALLATIONの通りにやればいい。rbenvなんかと同じ。
ただ、CentOS6に入れようとしたら、plenvを動かしてるシステムのPerlModule::Metadataversion.pmが古かったらしくてエラーが出たので、それだけ新しく入れ直す必要があった。(23:11訂正)

# CentOS6の場合
$ sudo yum install perl-CPAN
$ sudo cpan version

# cloneしてきてシェルの設定に追加
$ git clone git://github.com/tokuhirom/plenv.git ~/.plenv
$ echo 'export PATH="$HOME/.plenv/bin:$PATH"' >> ~/.zprofile
$ echo 'eval "$(plenv init -)"' >> ~/.zshrc

# シェルを起動し直す
$ exec $SHELL -l

設定部分は模範的な感じで書いたけど、各自の環境に合わせて設定する。
自分の場合.zshenvとかで色々仕掛けしてたりするので上記のようにはしなかった。


んで、とりあえず使ってみる。

$ plenv available
perl-5.17.8
perl-5.16.2
perl-5.14.3
perl-5.12.5
perl-5.10.1
perl-5.8.9
perl-5.6.2
perl5.005_04
perl5.004_05
perl5.003_07

$ plenv install 5.16.2

$ plenv global 5.16.2

# cpanmもコマンド一発で入れてくれるようだ
$ plenv install-cpanm
$ plenv rehash

plenv migrate-modulesでモジュールを別環境に移行できたり便利そう。

carton

https://github.com/miyagawa/carton


RubyでいうところのBundlerのようなやつ。
プロジェクト(ディレクトリ)毎にモジュールのインストールとバージョンの固定ができる。

$ cpanm Module::Install carton
$ plenv rehash

で、なんかこんなMakefile.PLを書いといて、

use inc::Module::Install;
name 'MyApp';
version '1.0';

requires 'Plack', 0.9980;
requires 'Starman', 0.2000;

WriteAll;
$ carton install

とかすると./local以下にインストールされて、carton.lockが生成される。

$ carton install JSON

みたいに直接インストールすることもできる。

pyenv

https://github.com/yyuu/pyenv


つづいてPython。こちらもインストール手順はほぼ同じ。

# cloneしてきてシェルの設定に追加
$ git clone git://github.com/yyuu/pyenv.git .pyenv
$ echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.zprofile
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc

# シェルを起動し直す
$ exec $SHELL -l

使ってみる。

$ pyenv install -l
Available versions:
2.5
2.5.1
2.5.2
   :
   :

# インストール。distributeとpipも入れてくれる
$ pyenv install 3.3.0

$ pyenv gloabl 3.3.0
virtualenv

https://github.com/yyuu/pyenv-virtualenv


あとvirtualenvをpyenvのプラグイン化したやつがあるので、ついでに入れておく。

$ cd ~/.pyenv/plugins
$ git clone git://github.com/yyuu/pyenv-virtualenv.git

pyenv virtualenvコマンドが増えるので、これで環境が作れるようになる。

$ pyenv virtualenv --distribute 3.3.0 env330

.pyenv/versionsの下に指定した名前でできるので、それに切り替えて使うことになるみたい。

$ ls ~/.pyenv/versions
3.3.0/ env330/

$ mkdir projA
$ cd projA
$ pyenv local env330

似たようなの増えてきた

というわけで、rbenv, plenv, pyenvの環境が出来上がった。
rbenvとpyenvは似てるけど、plenvは中身は結構違ってる印象。


しかし、この手のやつどんどん増えてくるけど、統合的な仕組み作って、各言語用のレイヤを追加していって……みたいな形にできないかなぁ。
Twitterで誰かが「llenv init ruby perl pythonみたいに出来ればいいのに」みたいなこと言ってたし。

*1:今はpythonzっていうforkなのかな?