| @技術/プログラミング

Vimmabilityのなさ

TDD Boot Camp福岡で生まれて初めてペアプログラミングを経験した。自分のVimmabilityが思いの外低く焦った。書くの超とろいし、Rubyも全然分かってないしペア組んでもらった人に迷惑かけまくりな感じ。会社では誰もVimとか使ってなくてみんなEclipseとか秀丸使ってるし、周りにVimmerがいないので自分がどんなにしょぼいVim使いなのか気づいてなかった。

とりあえず今回、ペアを組んだ @mallowlabs さんに cw とか <数字>y とかを教えてもらった。あと

Vimでバックスペース使ったら負けだから

と言われてしまったのでバックスペースと矢印キーをなるべく使わずにプログラム書きたいと思います。でもTextMateとかCodaとか便利だからついつい使ってしまうんよね…。

プログラムが全然書けない

思ってたよりもプログラムができないことに気がついた。お題を与えられて、制限時間があるなかでコードを書いていかなければならない。しかもペアプログラミングなので一人でちんたら時間をかけて書くわけにもいかない。そしてやっぱ人に見られてると緊張する。Rubyの基本的なメソッドとかが分かってなくて教えてもらいながら書いてたけど、わからないと緊張してしまって頭が真っ白になって何も書けなくなる。いつもリファレンス本を片手にコードを書き捨てていたので、よくないなぁと思った。

というか、そもそも自分は仕事であまりコードを書いてないのだ。TDD Boot Campに来てる人たちはみんな公私ともにばりばりコードを書いててとても楽しそうだった。なんだかとても羨ましかった。

いろいろ考えないとなー、と思わせられた勉強会だった。

| @技術/プログラミング

CleanRuby を途中まで読んだ。一年半前に DCI 流行って、その後会社(東京の方)でも流行ってたので、「乗るしかない、このビッグウェーブに」と思って買うだけ買って積ん読してた。正月くらいから本気出して読み始めた。まだ全部読み終わってないんだけど、 Day One にメモ走り書きしてあって良い話っぽいのが書いてあったのでメモする。

2014/01/23

Clean Ruby 読んでる。まだ最初の方だけど何となく DCI についてつかめてきた。 DCI 、つまるところ RSpec みたいな BDD の考え方を製品コードにも持ってきたものだと思う。「テストコードだけ実際にプログラムが利用されるときの文脈( context )とか反映してるのもったいなくね? これプロダクトコードにも反映させるべきでは?」みたいなノリだと思う。


2014/01/26

Clean Ruby、3章くらいまで来た。 DCI の考え方だいたい分かった。Methodless Roles とはつまり良い名前を付けるところ、というところにぐっと来た。Clean Code からの引用で、「良い命名をすることがコードを良くしないことはない」というのが良かった。

モデルにいろいろ書くな、という話も良かった。 Being と Doing を分けるというやつ。モデルは変更しない情報(データ)だけを保存する場所にして、データを変更したりする処理は別の場所に書くという考え方。

サインアップについて。ユーザーがサインアップするとき、ユーザー自身がサインアップすることもあれば管理者がユーザーの代わりにサインアップすることもある。同じ種類のデータを作ろうとしてるんだけど、システムの挙動は異なる。管理者がユーザーの代わりにサインアップするときには、管理者にメールで通知する必要はない、など。モデルにデータの変更処理まで書くと、別の文脈からデータ操作しようとするときに苦しい感じになる。

頑張って最後まで読みたい。

| @技術/プログラミング

シェルの履歴から適当に拾って

CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.1.2

とやったら nokogiri のインストールでこけた。

gem install nokogiri
Building native extensions.  This could take a while...
Building nokogiri using packaged libraries.
ERROR:  Error installing nokogiri:
        ERROR: Failed to build gem native extension.

    /Users/morygonzalez/.rbenv/versions/2.1.2/bin/ruby extconf.rb
Building nokogiri using packaged libraries.
checking for iconv.h... yes
checking for iconv_open() in iconv.h... no
checking for iconv_open() in -liconv... no
checking for libiconv_open() in iconv.h... no
checking for libiconv_open() in -liconv... no
-----
libiconv is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/Users/morygonzalez/.rbenv/versions/2.1.2/bin/ruby
        --help
        --clean
        --use-system-libraries
        --enable-static
        --disable-static
        --with-zlib-dir
        --without-zlib-dir
        --with-zlib-include
        --without-zlib-include=${zlib-dir}/include
        --with-zlib-lib
        --without-zlib-lib=${zlib-dir}/lib
        --enable-cross-build
        --disable-cross-build

extconf failed, exit code 1

Gem files will remain installed in /Users/morygonzalez/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/nokogiri-1.6.2.1 for inspection.
Results logged to /Users/morygonzalez/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/extensions/x86_64-darwin-13/2.1.0-static/nokogiri-1.6.2.1/gem_make.out

Installing REE with rbenv with iconv support and Homebrew — eddorre という記事を参考に、 --with-iconv-dir オプションをつけて Ruby インストールしたらうまくいった。

CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-iconv-dir=`brew --prefix libiconv` --with-gcc=clang" rbenv install 2.1.2

| @Mac/iPhone

ApplicationIcon.175x175-75.png (175×175)

MacVim で Markdown 形式で文章を書いて Marked.app でプレビューしてた。 Marked.app 、便利なんだけどリストのネストの解釈が GitHub とかの Markdown と違ってて、スペース 4 つ入れないといけないのがだるかった。あとコードのシンタックスハイライトも GitHub のに比べたら弱い。やはり GitHub Flavored Markdown で Markdown をプレビューしたい。

ここを読めばやり方が書いてある。

GitHub Flavored Markdown と互換にしたいなら結局 GitHub が使っていると公言している redcarpet と pygments.rb (と Python の Pygments )がいることになる。 Docter というその辺の gem をラップする Node.js 製のソフトを使えと書かれているけどいらないものは入れたくなかったので gem install pygments.rb redcarpet するだけにとどめた。

rbenv とか rvm でインストールした Ruby のバージョンで gem をインストールして使おうとすると失敗するらしいのであまり気が進まなかったけど sudo つけてシステムルビーにインストールした。

そんでもって同じ URL に書いてある Docter の Docter/bin/github-flavored-markdown.rb at master · alampros/Docter をパクってちょっと改変してから使うことにした。これをテキトーな名前で保存して chmod a+x する。

なんか HTMLwithPygments#header は引数三つ受け取れるようにしてないとエラーになるっぽい。あと style は Marked で当たるのでここで当てる必要なさそう。

Marked.app 側の設定で Custom Markdown Processor にチェックを入れてファイルのパスを指定すればオッケー。

Marked.app でも GitHub Flavored Markdown に近いかたちで Markdown のプレビューができるようになるのでドキュメント大量生成するしかないですね。

| @技術/プログラミング

Rails で public_activity.gem を使っていて、 activities テーブルにレコードが追加されたタイミングで callback を仕掛けたい衝動に駆られた。ちょっと調べてみたけどやり方が見つからなかったので、チームの人と相談して以下のようにした。 public_activity は PublicActivity::Activity というモデルを gem の中に持っていて、こいつが belongs_to :model になる。

なのでこのモデルクラスを open して以下のように記述した。

# RAILS_ROOT/lib/public_activity/activity.rb

module PublicActivity
  class Activity
    after_create do
      HogeHogeMailer.send_mail(self.trackable).deliver
    end
  end
end

ただしこのファイルを config/initializers/ とかで require してやらないと Rails がファイルを読み込んでくれない。 Rails.application.config.autoload_pathslib/**.rb とかを追加しとけば自動的に読み込まれるんじゃないかなと思ったけどそうじゃなかった。 Rails の autoload は、 ConstMissing という例外が発生したときに定数の名前からファイル名を推測して require するらしい。名前が既に定義済みだと ConstMissing 例外が発生せず autoload では読み込まれないので明示的に読み込む必要があるということらしい。

読み込みされていないクラスを使用すると ConstMissing という例外が発生します。 この部分に介入して autoload_paths の中に規約に合うファイルがあるか確認します。 存在する場合は読み込みします。 存在しない場合は ConstMissing を発生させます。

Rails の自動読み込みの話 - そんなこと覚えてない

ナルホディウスですぞ〜!!!

そのうち忘れそうなのでここに書き記しておきます。

| @技術/プログラミング

Fukuoka.rbで Ruby で連続するダブルクオートの扱いについて @nagachika さんに聞いたら面白い話が聞けた。

Lokka のテストで FactoryGril でフィクスチャーデータ作ってるところに、以下のような文字列があった。

  factory :post do
    association :user
    sequence(:title){|n| Test Post #{n}” }
    body <p>Welcome to Lokka!</p><p><a href=“”/admin/“”>Admin login</a> (user / password : test / test)</p>”
    type ‘Post’
    created_at create_time
    updated_at update_time
  end

この body の部分で、ダブルクオートが連続して書いてある場所があって、ここがらみでテストを流してたら失敗する現象に遭遇した。テストに失敗したときのメッセージは以下。

Failures:

  1) Post markup default should == “<p>Welcome to Lokka!</p><p><a href=/admin/>Admin login</a> (user / password : test / test)</p>”
     Failure/Error: it { post.body.should == post.raw_body }
       expected: “<p>Welcome to Lokka!</p><p><a href=/admin/>Admin login</a> (user / password : test / test)</p>”
            got: “<p>Welcome to Lokka!</p><p><a href=\”/admin/\”>Admin login</a> (user / password : test / test)</p>” (using ==)
     # ./spec/unit/post_spec.rb:56:in `block (4 levels) in <top (required)>

なんか expect の方で HTML 内のダブルクオートが省略されてる。ダブルクオートが連続してるのが怪しいなと思って、文字列内でダブルクオートが連続したら、一つ目の はエスケープ文字列みたいな扱いになるのかなと思った。

しかし実はそうではなくて、 @nagachika さんの説明によると、ダブルクオートが連続した場合、一つ目の " で文字列の終端と判定される。すぐ右隣の " は新しい文字列の開始と見なされ、結果としては文字列として連結されるらしい(C 言語由来の慣習とのこと)。

たとえば、次のような文字列は

<p>Welcome to Lokka!</p><p><a href=“”/admin/“”>Admin login</a> (user / password : test / test)</p>”

“<p>Welcome to Lokka!</p><p><a href=“”/admin/“”>Admin login</a> (user / password : test / test)</p>” という三つの文字列と見なされ、クオートとクオートの間に何も挟まらないので自動的に一つの文字列として連結され、以下のようになる。

<p>Welcome to Lokka!</p><p><a href=/admin/>Admin login</a> (user / password : test / test)</p>”

これ、なぜいままで Lokka でこの状態で CI のテスト通ってたのかわからないけど、今日 wercker で CI の設定していてテストが通らなくてこの問題に気がついた。同じように手元でテスト実行しても落ちた。ひょっとすると Ruby 2.1.0 で落ちるのかも知れない。いずれにせよ "" は使わない方が良さそうなので修正して Pull Request 出そう。

| @技術/プログラミング

このブログを Capistrano 3 でデプロイするようにした。こちらを参考にした。

一点、 deploy:restart 内で、 invoke メソッドで他の namespace の task を呼び出すところ

The deploy has failed with an error: #<NoMethodError: undefined method `verbosity' for "/usr/bin/env unicorn:restart\n":String>

というエラーが出てた。調べたらどうも sshkit のバグっぽかった。

最新版では Pull Request マージされてて治ってるぽかったので Gemfile で

gem 'sshkit', github: 'capistrano/sshkit'

と書いておいた。

Capistrano 3、他の gem いれなくても色付いたりマルチステージになってたり rbenv 対応しててモダンになってると思った。あとシンボリックリンク作ってくれる task が便利。