2015/04/13

pry-rails がマルチバイト文字を含むヒストリを追加できない現象の対症療法

Rails Console で 'ほげ' とかのマルチバイト文字を入れると、ヒストリへの書き込みができなくて落ちる問題にぶちあたったので対症療法と調べたログ。

環境

  • OSX 10.10.3
  • rbenv 0.4.0
  • ruby-build 20150319zf
  • ruby 2.2.1
  • rails 4.2.0
  • pry 0.10.1
  • pry-rails 0.3.3

問題

日本語を含むコマンドを rails console で打つと以下のエラーで rails console が落ちる。

たぶんこれを踏んでる。

history.rb の save_to_file でどうやら保存できない模様

$ Pry.history.instance_eval {def hoge line; binding.pry end; @saver = method :hoge}
$ にほんご
$ Pry.history.instance_eval {@saver = method :save_to_file}
とかして無理矢理に pry で pry に割り込む。
そしたら line が ASCII-8bit になってるっぽい。
ので正しいエンコーディングに変換してしまえば保存できた。
.pryrc に書くとすると


とか。

これでヒストリへの保存時に落ちなくなったけれど、プロンプトはやっぱりおかしいまま。
どこか根幹の原因があるっぽい。
pry と pry-rails と rails の console 回りを軽く読んだけれど、 encoding 回りを触ってるのは見付けられなかったのでとりあえずの対症療法としてブログにまとめる。

読んでる時にちょっとおもしろかったものとか

  • Rails::Configuration に attr_accesor :x とかがあった。このパッと見 x が何か分からない感。
  • Pry.REPL#start ってメソッドがあって、 repl の loop を始めるメソッドらしいんだけれど
    • prologue
    • Input の handling
    • ensure epilogue
  • とかしていてなんかネーミングセンス良いなー、とか

根幹の原因

対症療法は分かったんだけれど、根幹の原因が分からないなー、ブログに書くかー、と思って再現する最小限の Gemfile を書いてたら、どうやら pry-rails そのものが問題じゃなくて rb-readline と組み合せるとダメみたい。
ちなみに再現する Gemfile は以下。

そのうちまた調べるかなー。

2015/03/01

Agda のソースコードを listings で LaTeX に埋め込む

LaTeX で Agda のソースコードを含む pdf を作ることに。
他のソースコードは listings で埋め込んでいたけれど、Agdaで使っている特定の文字が化けて表示されない。
verbatim でも表示されないので、Agda のソースを LaTeX 用にエスケープして、記号処理は LaTeX に任せることで listings できるようになったお話。

環境

  • Mac OS X 10.9.5
  • MacTeX 20140525

埋め込み方法

listings の escapechar を設定して、表示されない記号を LaTeX 用に置換してあげる。
escapechar が @ で、≡ を置換したかったら @$\equiv$@ みたいな。
escapechar の中は LaTeX 環境になるので、$ で数式を直接書いてしまえばok。
スクリプトとかは以下。
.agda から置換した .eagda を生成してくれます。
LaTeX からの参照は .eagda を指定してます。




周り道とか

Literate Agda ってのもあるみたいです。
lagda で書いておけば LaTeX としても認識してくれるっぽい?
でも今回は使わない方向でいきました。
本来Agdaのソースを埋め込むのならこっちなのかな。

あと大きなソース(500行くらい)のやつを LaTeX に食わせるとメモリが足りなくて落ちる時が。
! TeX capacity exceeded, sorry [main memory size=5000000].
とか言われる。
/usr/local/texlive/2014/texmf.cnf に
main_memory=8000000
extra_mem_bot=8000000
font_mem_size=8000000
pool_size=8000000
buf_size=8000000 
とか書いたら動いた。
メモリの制限とか自前で持ってるのね TeX。

あと、utf8周りでもメモリ周りでも LuaTeX 良いよって指摘があった。
LuaTeX 使うのも良いのかもしれない。
ちなみに今回は platex 使いました。

あとは listings 側のオプションに escapeinside とか literate とか使えそうなのもあったけれど動かず。
これはどうしてなのだろう。
ウムラウト付きの文字なら literate できます、みたいなのは記事にあったんだけれど ≡ は置換されず。

参考文献

ギー沖解散パーティーに行ってきました

2014/02/21 にギークハウス沖縄解散パーティーがあったので参加してきました。

ギー沖の3周年+解散パーティーでした。

人がかなり来ていて、多い時には30名以上いたみたいです。
ギー沖に関わっている人って多かったのだなー、とつくづく。
お隣りさんも来たりして、ネットは広いのだか狭いのだか。

メインディッシュは豚の丸焼き。
始めて食べたのですけれど部位によって硬さとか油とか変わるので若干探検っぽい。
しばらく販売が止まってたカーリーフライを久々に見たりもしました。

ギー沖LTがあって、これまでのギー沖の思い出とか突然の brain fu*k の話とか。
brain fu*k の話があるならー、ということで飛び入りでAgdaの話をしてきました。

LT ではあまりギー沖の話をしなかったのでブログに書こうかと。
ギー沖、何かの動機で1週間くらい泊まったことが(2012/02 くらいだっけ?)。
そんなこんなでギー沖に行くようになって、 Okinawa.rb の weekly meetup にも参加。
私が Ruby を勧める時の「はじめてのプログラミング」 -> 「たのしいRuby」 -> 「メタプログラミングRuby」の流れは Okinawa.rb から来てたり。
初心者組がメソッド分からんって言ってる時に横で libkinjo さんがメタプロの話とかしていたよーな。
Okinawa.rb で hanachin さんと関数型の話して、結果的に Agda 書いてたりするので、Ruby に触れるのも Haskell やら触っているのも元はギー沖から来てるかも。
思えば libkinjo さんのみゅーたんとか tompng さんの Ruby で lisp interpreter できるよねー、とかぱかなさんのギー飯とかこたにんさん飯とか、思い返すといろいろとありますね。

イベントもたくさんあったし、人もたくさんいた場所でした。
ありがとうギー沖。

2014/12/27

私の git の参考文献とか使い方とかまとめ 2014

git どうやって勉強したのさー、って質問が。
参考になるかはともかく私の最近の git の使い方についてまとめてみます。
このコマンドはどういう挙動をします、って話ではなくて、どんな時に使う、くらいのまとめです。
調べるためのキーワード提供にでもなれば。


参考文献とか考えとか

  • staging とか workspace とか commit とか : どこだっけ。ちょっと覚えてない。
  • rebase とか –no-ff の知識 : こわくない git かな。 基本的に git の話するときはこれを勧めてます。
  • tips とか : ここ とか。必要になったら調べる感じ。
  • branching model : 過去のログを見るとここを参考にしてたみたい
  • branching model : 複数人数で git を使う時の自分の中ルールだと
    • master には直接 commit しない
    • origin/master への push -f は最終手段
    • merge は master に対して –no-ff
    • conflict の解消は branch での rebase で解決する
    • github を使ってるなら merge は pull request で、 conflict したら branch で rebase 
  • commit message とかの話 : ChangeLog を支える英語


基本的に使うコマンド

  • git init
    • リポジトリ作る。
  • git ( add | mv | rm )
    • ファイルの追加とか移動とか削除とか。
  • git st
    • status を見る。面倒なので alias かけてます。
  • git commit
    • コミット。
  • git log
    • ログを見る。2.0 くらいから特に設定しなくても色が付くようになってうれしい。
  • git diff (–cached)
    • diff を見る。
    • diff で commit と workspace 間の diff。 add してなかったらこっち。
    • diff –cached で commit と staging 間の diff。 add した後に diff りたかったらこっち。
  • git fetch
    • remote から変更を取ってくる。
    • commit してない変更がある時とか、ローカルブランチで作業してる時に変更が欲しかったら fetch
  • git pull
    • remote から変更を取ってくる + 変更を反映する
    • master で変更を取ってきたいなら pull で良いかな、くらいの使い方
  • git clone
    • リポジトリを clone する
    • github は https:// を clone すると毎回 password 聞いてくるので git:// で clone すると楽
  • git merge (–no-ff)
    • branch を merge する
    • 私は master には直接 commit せずに –no-ff する主義。
  • git branch (-a | -d | -D )
    • ブランチを見たり作ったり
    • -a で remote も含め全部。
    • -d で削除。 -D で強制削除。
  • git co ( -b | -f )
    • checkout する。面倒なので alias かけてる
    • 最近 branch するのが面倒なので -b を良く使う気がする
    • 作業前の状態にしたいやー、って時は -f を使う。
    • stash でも良いけれど本当にいらないと思うときはこっち。
  • git reset
    • add したやつを戻す。
    • soft reset, hard reset がある
  • git rebase -i
    • rebase は -i を良く使うかも
    • master から派生した branch にいる時は rebase -i master が楽
    • conflict したら –abort 諦めるくらいの軽さで commit の入れ替えとかたまにやる。
    • 最近は commit –amend するより commit して rebase -i で fixup とかする
    • fixup と rewind で –amend みたいなことができるし良いかなーといった感じ
  • git remote ( add | rm )
    • そんなに使わない
    • clone すると origin があるので基本はそれを使ってる
    • fork したリポジトリの upstream を設定する時くらい


あると便利

  • git grep
    • リポジトリ内を grep する
  • git ls-files
    • リポジトリに入ってるファイルの一覧
  • git remote prune origin
    • remote に無い branch を local でも消してくれる
    • branch -a がうるさく無くなるのでちょっと快適
  • git reset –hard
    • 最終兵器。
    • 間違って master に commit した時に checkout -b して reset –hard HEAD^ とか便利
  • git reflog
    • rebase, merge にミスった時はコレ
    • reflog 漁って git reset –hard で大体解決する
    • ので gc は設定で切ってたりします。コマンド打つと勝手に gc して止まるのも何だし。
  • git stash ( pop | apply |save )
    • workspace の変更を一時保存
    • 軽量 commit みたいなものだけれど最近は commit + rebase してしまうかも
    • この実装でいけるか怪しいけれど一応は保存しておきたい、くらいの時に save するかなー、くらい
  • git bisect
    • エンバグした時に便利
    • 動いてた時と動いて無い時を指定して、動かなくなった commit を特定するやつ
    • これをまともに使うためにも master は必ず動く状態の commit のみで構成したい理由はコレ
    • コンパイル通らない、とかだと bisect できない
  • git cherry-pick
    • 特定の commit を拾ってくるやつ
    • master に特定の commit があるなら rebase で拾うけれど
    • 欲しい commit が他 branch でそれ以外の commit を拾いたく無い時とかに使う
  • git archive
    • repository を zip とかにできる
    • なんか提出する時とかに使ってた記憶。そんなに使わないけれど特定の人達には需要あるかも

2014/12/14

ghc 読み会に参加してみた

コンパイラの講義で行なわれた ghc 読み会に紛れ込んできました。2014/12/06と07。

まずは ghc の内部構造の話から。
ここ を参考にしながら ghc がどのような流れでバイナリを吐くのか、みたいな話とか。
まずは Core に変換されて、STG に変換したあと LLVM なり gcc なりのバックエンドで実行コードを吐く、みたいな流れみたいです。
Core は Haskell でついてる型からどうやって Primitive 型に変換するか、みたいなのも処理する様子。
あと型変数とかも処理するので、関数に型を渡したりもできる言語っぽいです。
ほとんど Agda みたいに見える。
case で実行するので、 case を使う場所によって遅延評価にしたり正則評価にしたり変えられるみたい。
Core の定義そのものはシンプルっ。Exprは6種類しか無いとか。
ただ ghc 自体は 200k 行とかあって、シンプルな言語だとしても処理系側でカバーしてるだけなのかなー、とか。Core しかり Haskell しかり。
あとは Haskell はグラフだぜー、とか要素いろいろ。良い資料っぽさげ。


次に実際にデバッガで追っていこう、ということに。
Vagrant で box 作ってその中で実行したのでログとか。
  • $ vagrant init chef/ubuntu-14.04
  • $ vim Vagrantfile
    • メモリとか CPU 割り当てとか編集
  • $ vagrant up
  • $ vagrant ssh
  • $ sudo apt-get update
  • $ sudo apt-get install git cabal-install vim
  • $ sudo apt-get build-dep -y ghc
  • $ vim ~/.bashrc
    • export PATH=$HOME/.cabal/bin:$PATH
  • $ source .bashrc
  • $ cabal update
  • $ cabal install cabal-install
  • $ cabal install happy alex
  • $ git clone git://github.com/ghc/ghc.git
  • $ cd ghc
  • $ ./sync-all -r git://github.com/ghc get
  • $ perl boot
  • $ ./configure --with-ghc=/usr/bin/ghc
  • $ vi mk/buil.mk
    • buildFlavor を devel2 に
    • GhcDebugged = YES を末尾に
  • $ make MAKE="make -j" -j
    • 1時間くらい。付けなかったら3時間とかかった
  • $ sudo make install
  • $ ghci -fobject-code -cpp -DSTAGE=2 -I. -I./stage2 -I./stage2/build -illvmGen:prelude:cbits:specialise:stranal:coreSyn:stgSyn:basicTypes:main:stage2:iface:simplCore:simplStg:cmm:types:codeGen:typecheck:profiling:parser:rename:utils:nativeGen:hsSyn:deSugar:ghci:vectorise:stage2/build: main/DriverPipeline.hs
    • すると .o ができる
    • DriverPipeline は読みたいので DriverPipeline.hi を消して
  • $ ghci -cpp -DSTAGE=2 -I. -I./stage2 -I./stage2/build -illvmGen:prelude:cbits:specialise:stranal:coreSyn:stgSyn:basicTypes:main:stage2:iface:simplCore:simplStg:cmm:types:codeGen:typecheck:profiling:parser:rename:utils:nativeGen:hsSyn:deSugar:ghci:vectorise:stage2/build: main/DriverPipeline.hs
    • で b compileFile できる
  • $ s <- SysTools.initSysTools (Just "/usr/local/lib/ghc-7.9.20141205")
  • $ env <- HscMain.newHscEnv $ DynFlags.defaultDynFlags s
  • $ DriverPipeline.compileFile env (DriverPhases.Hsc DriverPhases.HsSrcFile) ("/home/vagrant/hoge.hs", Nothing)

とりあえず compileFile って関数があるので呼んでみよう、というログが上のもの。
ghc の main を直接 ghci で実行すると、「今呼んだらもう遅い」みたいな abort で落ちたので main 以外を実行しようとして見つけたのが compileFile 。
stage 2 の ghc の library とかを使って ghc の DriverPipeline.hs なるソースを読もうとしたログ。

読もうとした時に問題発生。
そもそも Haskell ってどうデバッグしたり追っていくものなのだろう、という疑問。
調べると ghci が出るんだけれど、 ghci の trace って読むために使うものだろうか。
とりあえずそれ以外の選択肢は無かったので ghci で実行してた。

実行することはできたのだけれど問題がいくつかあって
  • -I の指定順とか結構謎。オプションの順番変えると動かないとかあったり。
  • .o がある .hs を ghci で読み込むと、そのファイルの関数に break point が付けられない
  • けど -boot file は .o が無いと参照できないので .o を作らないといけないソースもある
  • 実行するためには HscEnv とかが必要なのだけれどそれを作るのが大変
とか。追おうにも追いづらい。
test から見ようにもテスト単位がユニットごとじゃなくて全体用のテストのみで単体の動作を追うのも無理。
Haskeller の人達ってどうやってデバッグ やソースコードリーディングしているのだろう。
あと、小さい単位に分けたりしなくても大丈夫なのだろうか。テストとか。HscEnv とか。(値が20個とかある型だった)
型チェックとかでどうにかしてるのかなー。その辺りの情報が謎。
ghc の Travis とか見たら結構 build コケてたりしていて実際どうやってるのか不安。

最後には Parser や Lexer をソースから読むことに。
Alex とか Happy とか使いつつ。
Parser も実際に動かすことはできなくて、 Haskeller はどうやってデバッグしてるんだろうか、というところでタイムアップ。

結局 Haskeller はどんな風にデバッグしたりソース読んだりテストしたりするのだろう、という疑問が募っておしまい、という感じ。
Core の構造とかを知ることができたのが収穫かなー、といったところ。