雑記帳

ちょっとした文章とかメモ書きとか。

hsenvで複数の切り替え可能なghc環境を整える

RubyでいうrbenvのようなツールはもちろんHaskellにもあります。hsenvですね。

これは$HSENV_ROOT/bin/activateスクリプトにより独立したghc環境を作るものです。

rbenvの時とは少し作法が違うので注意してください。

hsenvの場合は、hsenvを実行したディレクトリに.hsenvが掘られ、そこにghc環境が新たに作成されます。使い方によってはcabal sandboxと被ってしまいますが、今回は異なるghc環境の切り替え用途で使ってみます。hsenvは$PATHで指定されているディレクトリに既に有るものとします。

$ mkdir ~/.haskell
$ cd ~/.haskell
$ hsenv --ghc=<ghc tarball>.tar.gz

とする事により、新たなhsenvによるghc環境が~/.haskell/.hsenv以下に作成されます。

例えば、ghc-7.8.2をhsenvを使った切り替え可能なghc環境としてインストールするとしたら次のようになります。

$ wget https://www.haskell.org/ghc/dist/7.8.2/ghc-7.8.2-<architecture & OS type>.tar.gz

としてghc-7.8.2のtarballをダウンロードしておき、

$ mkdir -p ~/.haskell/hsenv/ghc-7.8.2
$ cd ~/.haskell/hsenv/ghc-7.8.2
$ hsenv --ghc=<path to ghc-7.8.2 tarball>

とすると~/.haskell/hsenv/ghc-7.8.2の下にghc-7.8.2環境が作られます。

$ source ~/.haskell/hsenv/ghc-7.8.2/.hsenv/bin/activate

とすればこの作成した環境に切り替えられます。

これを、例えば~/.bash_aliases~/.zshenvなどに

alias hsenva='source ~/.haskell/hsenv/ghc-7.8.2/.hsenv/bin/activate'

みたいにしておけば環境の切り替えも楽に行えます。hsenvaはhsenv activateの略のつもりです
今回はghcを一つだけhsenvでインストールしたのですが、例えば

$ ~/.haskell/hsenv/ghc-<version>

のようなバージョニングルールを決めておけば、
複数のhsenvでインストールしたghc環境がどれがどれだったか分からなくなる事がなくなると思います。

hsenvにより新しいghc環境を作成した後、cabal sandbox init後に依存ライブラリを入れるようにすればより快適なHaskell開発環境が手に入ると思います。お試しあれ。

Ansibleでketerのデプロイ環境を整える

Ansibleを触って、keterでのデプロイが出来るまでのAnsible playbookを作成してみました。

目標:AnsibleでサーバーへHaskell開発環境を入れずにketerの環境を作成する。

Yesodのデプロイツールのketerサーバーで実行する段階ではネイティブのバイナリの実行ファイル(ELF)です。

Yesodのデプロイ環境をketerで作成するとプロダクションサーバーに一切開発環境やインタプリタやコンパイラを入れること無くアプリケーションを動かせる、ということになっています。

とってもセキュア!

そうして出来上がったのがこちらのplaybook: ansible-playbook-for-keter-deploy

このplaybookを動かすにはhostへの対象サーバーの記述と、binaryディレクトリへketerのELFバイナリを置く必要があります。

ついでにserverspecでserverの状態を確認するテスト書きました。

  • gcc, clang, ghc等の開発ツールを誤ってインストールしていないか
  • keterがサービスとして動いているか
  • avahi(bonjour) daemonが動いてホスト名の名前解決が行えるか

等のserverspecを書いてあります。(が、テストをどうやってCIするか悩んでいるのでCIはまだしてないです)

Yesodのデプロイ作業はいくらscpで<<Yesod App Name>>.keterをプロダクションサーバーに投げつけるだけとは言え、そこまでの環境を用意するのがめんどくさかったのですが、Ansibleのplaybook化してしまえばYesodのアプリケーションをデプロイするまでの作業がかなりラクになりそうですね。

新宿Scala座2014年3月号に参加してきた

新宿Scala座に参加してきました。

普段自分の時間を使って書く時はHaskellやらRuby(のC FFI)やらを書いている訳ですが、何を思ったかScalaに手を出してしまいました。

Scala始めて間もないのでScalaを書く時にはまったこと、というタイトルでスライドを作りました。

Scalaを書いていて結構OOPだなーと思っていると実はScalazがあるよ!みたいなことだったり、かなりBattery includedな感じだったりと、どうしても重厚なものになってしまうのは仕方ないのかなぁとか。

あと、最近はdispatchの新しいものが出たこともあり、dispatch-classicと新しいdispatchの情報が混在していてやめてくれーって感じでした。

Scala、もっと使っていきたいですね。

GroongaのHaskellバインディングを書いた。

Groongaのドキュメントの作業のお手伝いをしていく中で、自分の好きな言語の一つであるHaskellから使えたらなんて面白いんだろう、と思ったのでHaskellバインディングを書きました。

ツイートにある通り、Haskell + GroongaHaroonga(はろんが)です。
https://github.com/cosmo0920/haroonga

Groonga(ぐるんが)のようなどっしり(?)した響きではなく、Haroonga(はろんが)だと「Haskellの世界にはろー」みたいな軽いイメージが連想されますね。(「はろー」というよりも「はろろん」みたいなもっと砕けたイメージかなと思いますがまぁ置いておきましょうか。)

HaskellでFFIを使ったバインディングを書くにあたって何種類か方法があるわけですが、その中で使った方法がc2hschsc2hsを使う方法です。この方法を取ると、c2hscがC言語のヘッダーを静的に解析し、<c言語のヘッダー名>.hscという中間形式を吐きます。こうすることにより、FFIを行うにあたって8割以上の作業は終了します。

FFIを使用する理由は何でしょうか。そうですね、FFIを使ってその言語に無いライブラリを使いたいのです。その目的を達成するのには、APIがこなれないのかも知れないけれどもツールに頼るのが良いでしょう。
幸運な事に(Glasgow) Haskellではそのやり方を推奨しているように見えます。c2hscは使い方が単純ですし、hsc2hsはwell documentedなのです。

ただ、c2hscにも弱点はあります。複雑に定義されているC言語の構造体をごく稀にパーズできないことがあります。ただこれは本当にごく稀で、そのような構造体をHaskellの世界に持っていく事に迫られるケースは多くありません。Haroongaを作る際にもgrn_obj構造体の扱いに悩みましたが、これはあくまでもHaskell側からは型のみを取り出して中身はブラックボックス(Haskell側ではアクセスする手段を提供しないが、Haskellの世界にgrn_obj構造体に当たる型が存在する)、とする事に落ち着きました。

それにより嘘みたいに簡単に作成することができました。

こんな具合です。

Haroongaのモジュールの中でBindings.Groonga.RawはGroonga 3.1.1のgroonga.hからc2hscを使って生成した後、すこし手直しをしています。また、Bindings.Groonga.CommandAPIはgroongaコマンドで出来るレイヤーのAPIを提供します。当初このモジュール名はSimpleAPIでした。CommandAPIの方がどのように使え、何が出来るのか、が分かるのではないかというGroongaのメーリングリストの指摘によりこのモジュール名を選択しました。
指摘して下さった須藤さんありがとうございます!

現時点ではまだHackageにリリースされていませんが、もう少しAPIを練ってみて自分なりに納得したらリリース…できるといいなぁと。

Hackageのアップロード権限の申請が通ったので、Hackageにリリースしました!

cabal install haroonga

でGroongaが導入済みで、Haskell Platformがインストールされている環境ならばインストールすることができます。

趣味でのソフトウェア開発をする際に気をつけていること

自分の時間を使ってソフトウェアを開発するにあたって、趣味のコードを触る時に気をつけていることでの現時点での考えを明文化しておきます。

1. 問題が起きた際にはupstreamに報告をする。可能であればpull requestやパッチを送る。そうではない場合は、再現可能な手順を添えてissueやチケットを作成する。

2. 動く状態にして公開する。その際、変更しても壊れてないかどうかを判定する仕組みを導入出来るのであれば導入しておく。

3. 2つ以上の方向から理解するように心がける。

です。

まず1.から。これはRuby-GNOME2のメンバーになった辺りから考え始めました。ククログにもある通り、

「既存のソフトウェアの開発元に問題を報告し、可能なら問題を修正するパッチを添える」です。ソフトウェアの開発元のことをupstream(アップストリーム)と呼ぶこともあるため、「upstreamで直す」と呼ぶこともあります。

これにかなり近いですね。upstreamで問題を解決できれば、手元で回避するよりも結果的に掛かるコストを削減できると思っていますし、感じているからです。フリーソフトウェアでは基本的にソースコードは公開されていますから、フリーソフトウェアにおいて「問題を手元で回避する」とは凡そ「問題を回避するパッチを作成し、手元のソースに当てておく」だと思います。しかし、一時期はそれでしのげるものの、パッチはいずれ当たらなくなります。

また、フリーソフトウェアでは英語で議論をすることが多いため、拙い英語でもいいので(本当はもっとしっかりとした英語を書くべきですが)、問題を報告します。英語で報告したものでもきちんと筋が通っていれば大抵の場合は対応してくれます。英語で対応した例として、yesod-paginatorのPull Requestyesod-binのscaffoldがビルドできなかった問題があります。

2. について。これは主にCIに関する話です。主にGithubに上げるコードでは可能な限りTravis CIに掛けてCIをするようにしています。CIをして、greenになるまでは確かに大変ですが、恩恵もあります。CIでpassしていれば大抵他のマシンで開発を継続することができます。CIをする、という事はビルド手順やテスト手順が明文化されているという事なので他の方々が修正する時の道標にもなるでしょう。

3. について。これは、普段の心がけの話と言うよりは受けてきた教育の影響によるものでしょう。詳しくは話しませんが、僕は理学系の出身でソフトウェア工学の学問をしてきたわけではありません。理学系の人々の特徴としてあるものを作って満足というのはまずありませんし、振る舞いからおそらくこうなっているだろうという妥協した推測をしません。振る舞いから可能であれば法則を導き出し、また可能であればデータを取ります。感覚的な議論ではなく、出来れば定量的に議論を進めます(定性的な議論をすることもあります)。法則に関していえば、ひとつの例だけの理解に留めることはありません。最低限2つ以上の事象で理解しようとします。2つでは少ない、5つ以上だという方も中にはいます。それくらい多角度から客観的に物事を取り扱うように習慣づけられています。

例えば、Haskellを理解するにしてもHaskellを書いてみる事だけではなく、理論的、つまり圏論の方面から考えて見るという事をしますし、出来ればコンパイラの中を覗くことをします。型理論をかじってみたこともあります。HaskellのGroongaのC APIバインディングであるHaroongaもその一環で開発中です。

これはRubyに関しても同じことが言えます。Rubyに関する本を読むだけでなく、CRubyの処理系のコードを読んでみることや、C言語拡張のコードを読んでみる、書いてみる事も当てはまります。

また、方向とは少し異なりますが、その言語でのFFIを使ってみるだけでもかなり理解が深まるではないでしょうか。またまたRubyの例で申し訳ありませんが、Rubyはとても興味深い言語です。RubyistはRubyの世界しか見ない傾向にありますが、それはなんてもったいない事をしているんだろう!と思います。
というのも、RubyはRubyと処理系の境界を曖昧にする言語だからです(*)。C言語でRubyを拡張することができますし、なにより、C言語拡張からはC言語の関数が呼べます(当たり前ですね)。これを利用すると、例えばmikutterが使っているruby-gtk2のようなバインディングが書けるのです。そうすると、Rubyの世界からは違った様相が見えてきますし、CとRubyの使い分けも出来るようになるでしょう(と言っておきながらそこまでできてないのですが…)。
RubyはRubyの世界はオブジェクトがぽんぽんできては消え、掴みどころがないのですが、C言語拡張の世界ではメソッドはVALUE staticですし、理解がむずかしいselfも明示されます!

と、ここまで書いてみました。
この心がけは万人向けではありませんし、現時点での僕の心がけです。フリーソフトウェアを使って開発する際にはそのソフトウェアのコードが手に入りますし、直そうと思えば手元でも直せてしまいます。
しかし、何のためにフリーソフトウェアを公開してくれているんでしょうか?
感謝の気持ちを込めて開発元に適切な手段で報告すればその開発者は喜んでくれるのではないでしょうか。

最後に、問題を報告する際には丁寧に状況を説明し、相手を不愉快な気持ちにさせないように心がけたいですね。問題を報告される側になった時はまず初めに感謝の意を表明することも心がけています。

(*)理解が浅いとかありましたら、コメント欄に是非。

mikutter無しな*nix環境なんてあんまりだ

この記事はmikutter Advent Calender 21日目の記事です。

タイトルは若干誇張気味です。
Linuxや*BSDを入れたらTwitterをしたくなった時にツイッタークライアントは何を使いますか?
僕はmikutterを使います。いや、使わせてください。

ですが、mikutterはRuby製でしかもruby-gtk2への依存も有るわけです。ちょっと手軽に使うには依存が多過ぎます。

何かもっとこう、サクッとインストールしたいと思うわけです。

そこでChefですよ

Chefとは最近Chef社に社名変更したChef社が作っている(DevOpsと最近呼ばれるようになった)インフラ構築自動化フレームワークです。

え?自動化しても嬉しくない??いやいや、嬉しいことはあります。
sshログイン出来る環境だったらknife-soloによりsshして調理するだけでそのマシンにmikutterが!

他には、Vagrantとの連携が考えられます。
Vagrantは各所で語られてきているので省略するとして、なぜ自動化すると嬉しいかもうひとつの回答を示しましょう。

それは・・・

vagrant upしただけでcookbookのレシピが導入済みの環境が気軽に手に入るわけです。すばらしいですね。夢のような話です。

が、

今回はそこまで到達しませんでした。無念。。。

mikutterのcookbook

そうして出来上がってしまったmikutterのcookbook。ただし、かなり手抜きなのでておくれgitリポジトリからcloneしてくるcookbookになっています。。。
cookbookがちゃんとした形式に沿っているかは食の批評家に判断してもらいましょう。
はい、foodcriticの出番です。

批評するタイミングはgithubにプッシュしたタイミングで行なって欲しいですね。Travis CIまで動員してみましょう。
動員するには.travis.ymlをGithubのリポジトリに作成した後、Travis CIのアクセスをONにします。(詳しい説明は省きます)

そうすると批評家が自動で批評してくれるわけですね。

mikutterをインストールするcookbookはこちらです。

(実はvagrant+berkself用に書いたものなんですが…。)

これで新たに環境をセットアップした時にすぐにmikutterの環境が手に入ります。詳しいcookbookのカスタマイズの仕方はREADMEを見て下さい。

え?ておくれ要素が無いのでは、って?

*nix環境にmikutterがインストールされて無いなんてあんまりだ、なんて言っている時点でておくれです。

第九回Kernel/VM探検隊でLTをしました

時間が経ってしまいましたが、Kernel/VM探検隊でLTをしました。

mikutterを使っていたらひょんな事でコミット権を得てしまい、
歴史を感じるコードに右往左往した記録(?)です。

今はTravis CIのVM imageが新しくなっているかも知れないのでGreenになっているかどうか怪しげですが
typoをスナイプしたコミットをしたらGreenでした。
過去600回以上もの間Travis CIがFailureと言い続けていたのをGreenにする作業に(全部ではないですが)貢献できたのは良かったなぁと。

LTではあまり詳しく話せなかったのでどんな事をしてたかはスライド中のリンクを辿るなりして眺めてみて下さい。

近況報告

Ruby-GNOME2プロジェクトメンバーになりました。

Ruby-GNOME2のリポジトリへPull Requestを何回か送っていたらkouさんにRuby-GNOME2プロジェクトメンバーにならないかと提案されたので快諾しました。

現時点では「Ruby-GNOME2プロジェクトをもっとも知らないRuby-GNOME2 teamメンバー」です。よろしくおねがいします!!

追記:GithubへのPull Requestやissueの報告、返答はすべて英語で行いました。
というのも、GithubのRuby-GNOME2チームは日本語を第一言語としていないメンバーもいたためです。
日本語を読めない人々が議論に参加できるようにするならそのほうが良く、またプロジェクトの第一言語が英語であるならそれに従ったほうが良い、との判断から英語を用いてやり取りすることにしました。

Kernel 3.10向けのパッチとか設定とか

Kernel 3.10向けのパッチとか設定とか

VMWareのドライバのビルドが落ちる問題は以下の2つで解決できます。

kernel 3.10のvmnetのパッチ:
http://communities.vmware.com/thread/446113?start=0&tstart=0

vmblockのパッチ:
http://mysticalzero.blogspot.fi/2013/07/vmblock-patch-for-linux-310-vmware.html

→VMWare Player plus 6.0.0で解決済み

NVIDIAの公式ドライバのビルドが落ちる問題は次のパッチで解決できます。

NVIDIAの公式ドライバのKernel 3.10向けパッチ:
http://pastie.org/7942599#5,13,280

→325.15で解決済み。

Kernel 3.10にしてfailed to execute /initと出てkernel panicをする場合

次のconfigを試してみるといいかも知れません。

failed to execute /initと出る場合はCONFIG_BINFMT_SCRIPT=yにする
http://www.linuxquestions.org/questions/slackware-14/kernel-3-10-0-won%27t-run-initrd-slackware-14-0-a-4175468404/

MathJax.jsのSVGレンダリングでより綺麗に出力

MathJax

MathJax.jsはWebページに綺麗な数式を表示させるJavascriptです。

最新版は現在v2.2です(13/7/3現在)

MathJaxのCDNがあるのでそこから引っ張ってくるのが手軽な使い方です。

よく以下のように使うと書かれています。

<script type="text/javascript"
  src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>

しかし、MathJax.jsのv2.2はsvg画像でのレンダリングもサポートしているのでこちらを使ったほうが拡大により数式が荒くならず、また、表示も速くなります。

svgでのレンダリングは以下のようにします(参考:http://docs.mathjax.org/en/latest/configuration.html#using-a-configuration-file):

<script type="text/javascript"
  src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG">
</script>

こうすることで、表示がsvgでされるようになります。

また、以下のようにしておくと日本語環境での場合の数式入力がよりしやすくなるかもしれません。参考:http://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [['$','$'], ["\\(","\\)"]],
      displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
    }
  });
</script>

こうすることで、数式の開始、終了に$記号が使えるようになります。

svgでのレンダリングの例が見当たらなかったのでメモ。
フォロー

新しい投稿をメールで受信しましょう。

現在1,188人フォロワーがいます。