upinetree's memo

Web系技術の話題や日常について。

CoffeeScriptでインスタンスメソッドを関数バインディングする

忘れないようにメモ。

イベントをバインディングする時、関数をコールバックで渡すことがある。

$('.hoge_field').on('blur', (e) -> updateHoge(e.target))

updateHoge = (hoge_field) ->
  hogehoge

でも、インスタンスメソッドを渡すときは同様にこうしてはいけない。

index: ->
  $('.hoge_field').on('blur', (e) -> @updateHoge(e.target))

updateHoge: (hoge_field) ->
  hogehoge

なぜなら、コールバックとして渡す際、thisの示す先が変わり、updateHogeが未定義となってしまうから。

なのでこう書く。

  $('.hoge_field').on('blur', (e) => @updateHoge(e.target))

ファットアロー => を使うと、thisの示す先を変えずに扱うことができる。

JavaScript苦手意識あったけど、CoffeeScript触るようになってからわりと楽しくやってるかも。

非表示要素はCapybaraのfindで検索対象になるのか

今日はもう一個書く!

Capybara使ってると、display: noneで非表示にしてあるものはCapybaraのfind対象なのか??

という疑問がでてきたわけです。

ここは公式みてみますか。

Module: Capybara::Node::Finders

visible (Boolean) — Only find elements that are visible on the page. Setting this to false finds invisible andvisible elements.

ふむふむ。

でもどっちがデフォルトなのかよくわからん。 ちょっとソースつついてみる。

lib/capybara/query.rb

def visibleありますね。visibleオプション指定がないときは、 Capybara.ignore_hidden_elementsを見て判定しているようです。

こいつはlib/capybara.rbにありました。

[ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)

デフォルトはtrueなので、見えないものは探さないってことですね。 Configureで設定可能のようです。

つまり

visible: true #=> display: noneのものは検出しない(デフォルト)
visible: false #=> disiplay: noneでも検出する

ということですね。

実際確かめてみる。

  • visible: trueで検索すると、@resultにdisplay: noneの要素が入らなくて@restに入る。
  • visible: falseで検索すると、@resultに要素が入って@restが空になる。

うん、そのようだ。 スッキリ。

テキストをクリックして入力フォームを出現させる (rails+haml+coffee)

一覧画面とかで、表示されているテキストクリックしたら入力フォームが出現して、 サクッと内容変更できたらカッコ良いじゃないですか。 例えばブログ記事のタイトルとか、クリックしたら編集できるようになるとか。

というわけで毎度のメモです。

haml

#posts
  - @posts.each do |post|
    .title
      .value= post.title
      = text_field :post, :title, class: :field

scss

.title {
  .value {
    display: inline;
  }
  .field {
    display: none;
  }
}

coffee

$('.value').on('click', ->
  $(@).hide()
  $(@).next('.field').show()
                     .val($(@).text())
                     .focus()
)

$('.field').on('blur', ->
   # $.ajax
   #   hogehoge

   $(@).hide()
   $(@).prev('.value').show()

# 直感的にはEnterで確定したいので作ったる
$('.label_field').keypress (e) ->
  if e.which == 13
    e.target.blur()

ちなみに

単純なテキストの切り替えだったらこんな感じ。

haml

#toggle_me
  #showing.toggle_pair Toggle Me!!
  #hidden.toggle_pair Toggled!!

:scss
  #hidden {
    display: none;
  }

coffee

$('#toggle_me').on 'click', ->
  $(@).children('.toggle_pair').toggle()

表示する要素と表示しない要素を用意して同時に表示・非表示を切り替えることで、見かけ上変化させるのがコツですね〜。

FactoryGirlでファクトリ継承時、クラス指定を忘れて困った

困ったのでメモ。

次のようなSTIな感じのモデルがあるとき、ファクトリ側でも継承を使いたいなーと思うわけです。

モデル

class Post < ActiveRecord::Base
end

class PhotoPost < Post
  belongs_to :album
end

Factory

FactoryGirl.define do
  factory :post do
  end

  factory :photo_post, parent: :post do
    album
  end
end

photo_postをparentオプションでpostから継承した。でも、こう書いた場合albumなんて知らんと怒られる。

pry(main)> FactoryGirl.build(:photo_post)
NoMethodError: undefined method `album=' for #<Post:0x007f8e1b52ccd0>

なぜなら、photo_postは継承元(post)のインスタンスとして生成されるため。

albumの記述を削除して確認。

pry(main)> FactoryGirl.create(:photo_post).class
=> Post(id: integer, title: string, body: text, type: string, created_at: datetime, updated_at: datetime)

postにはalbumとの関連はないため、参照しようとして怒られていた。 これを回避するには、ファクトリ定義時にclassオプションを指定する。

  factory :photo_post, class: PhotoPost, parent: :post do
    album
  end

classオプションによりファクトリphoto_postがPhotoPostを生成することを教えられた。 これで、生成されるインスタンスはPhotoPostになる。

pry(main)> FactoryGirl.create(:photo_post).class
=> PhotoPost(id: integer, title: string, body: text, type: string, created_at: datetime, updated_at: datetime)

class指定忘れずにしようねというお話でした。

libv8, therubyracer のインストールが OS X Mavericks で失敗する

はまったのでメモ。

Mavericks上でlibv8, therubyracerのgem installが失敗する現象への対処法です。

なお、最新バージョンのlibv8, therubyracerではもう対応済みのようです。 bundleで特定バージョン入れなきゃいけないんだけどーみたいなときに読んでください。

libv8だけ入れる場合

オプションで、--with-system-v8つけるだけです。

gem install libv8 -- --with-system-v8

bundleでやる場合は、

bundle config build.livb8 --with-system-v8

とかしてからbundle installすれば良いです。

ちなみに、設定したconfigは~/.bundle/configに保存されます。

therubyracerを入れる場合

前提としてlibv8がインストールされるのですが、このとき--with-system-v8オプションがついてるとこけます。 もうオプション付きでlibv8入れちゃっている場合は、一度アンインストールします。

gem uninstall libv8

brew install apple-gcc42
sudo ln -s /usr/local/Cellar/apple-gcc42/4.2.1-5666.3/bin/gcc-4.2 /usr/bin/gcc
sudo ln -s /usr/local/Cellar/apple-gcc42/4.2.1-5666.3/bin/g++-4.2 /usr/bin/g++
sudo ln -s /usr/local/Cellar/apple-gcc42/4.2.1-5666.3/bin/cpp-4.2 /usr/bin/cpp

gem install therubyracer

元から入っていたgccとかはバックアップ取っておくと良いかもしれません。

参考にした Stac Overflow にはexportしてbrew tapする方法ものっています。 試していませんが、こっちでもできるっぽいー。

転職します

今月中旬にSIerを退職します。新卒で入社してから今まで2年半、あっという間でした。

今度は神保町でWeb系のお仕事する予定です。皆さま、よろしくお願いします。

転職エントリ、知らないおじさんが「で、誰?」って言いに来るイメージあるのでこわかったのですが、同じ状況の人と共有できたら素敵だなって思ったので書くことにしました。

なぜ?

端的に言えば、技術者として楽しく、アジャイルに働きたかったからです。 その上で、興味のあった分野がWebで、Rubyでした。

労働時間やSI業界的な問題に関してはよくある話と大体同じです。 でもここでは不満はあんまり書きません。 ただ、疲れ果て、好きだったプログラムも書かなくなってしまった時期もありました。

以下、転職までに何をしてどう判断したか書きます。

出会い

幸いにも、僕は出会いに恵まれていました。

社内アジャイルコミュニティとの出会いがきっかけで、 アジャイルサムライという素晴らしい書籍を読み、 ようやく自分のやりたいことと向き合う気になりました。

そこで3年という期限を設けて、自分がどう進むすべきか決めることにしました。

そして、勉強会文化、Rubyコミュニティと出会います。

技術が好きで、自主的に組織しているコミュニティがあり、 そこで集まっている人々がとても楽しそうにしている。 目の当たりにして衝撃をうけるとともに、僕の周りにもこんなコミュニティが欲しいと思いました。

※社内アジャイルコミュニティには所属していたが、僕は新潟の支社におり、距離的な制約があった

やったこと

ということで、新潟支社内でアジャイル勉強会を立ち上げることにしました。 せっかくなので支社全体に通知。この立ち上げには、下記のような狙いがありました。

  • 新潟で仲間を作りたい
  • 自分がやりたいことを発信することで、自分の立場、環境を変えたい
  • 自分と同じ事に興味を持っている人がどのくらいいるか知りたい

とはいえ、最初からうまくいくはずもなく、ひとりぼっちで心が折れそうなときもありました。 でも続けているうちに、徐々に仲間になってくれる人や、助けてくれる人が出てきてくれました。 LT大会したり、本社とリモートで勉強会をやったり、TDDワークショップしたり、色々な試みもできて楽しかったです。

お得だったのは、自分の名前が広く知られたことです。 懇親会で知らない人の集まるテーブルに座っても、「あー、アジャイルの人かー」って感じで自己紹介の手間が省けました。

また、プロジェクトチームにも勉強会で得られたものをフィードバックしました。 朝会やタスクボード、ふりかえり等を、チームの特性に合わせて取り入れてみました。

わかったこと

以上のような試みを続けてみて、自分の環境は少し変わりました。 抱えていた不満は相変わらずでしたが、前より居心地が良くなりました。

わかったのは、自分の立場や環境は自分で変えることができるということです。 もちろんコントロールできる範囲には限りがあります。でも、愚痴だけ言って腐るよりはマシです。

一方で問題なのは、変える内容によっては、とても長く時間がかかるということです。

とりわけ、僕がやりたかった「技術者として楽しく、アジャイルに働く」ことを実現するには、ずっと地道な活動を続けなければならなそうでした。 制度や人事上の関係もあり、社内政治的な手続きが必要となります。 そのためにはコントロールできる範囲を地道に増やすしかない。

もしそれらをクリアした時、僕は技術者としてどんな立場にいられるのか? もしかしたらコードを書ける立場にないかもしれません。それでは本末転倒です。

そもそも、僕の目的は会社を変えることではないのです。なので、勇気を出して外に飛び出すことにしました。 そしてありがたくもご縁があって、次の職場で働くことになりました。

※勇気を出せたのにも色々な理由がありましたが、長くなるので別の機会に

まとめ

偉そうに長々と書きましたが、実際は悩んで死にそうになってた時期もありましたし、技術者としても未熟極まりないです。後者は本当に反省すべき。

でも、もし僕と同じように悩んでいる方がいれば、まずできることから始めてみて欲しいと思うのです。 始めてみれば、何かが少し変わるはずです。一方で、すぐには変えられないことも明らかになります。その状態をどのくらいの期間許容出来るか、もひとつの判断の指針になるはずです。

そして大事なのは、自分で行動したことによって、結果的にどういう選択をとるにしてもそれを納得できるようになることだと思います。

以上、転職エントリでした。

Happy working :)

長岡でScalaに入学した

9/28に新潟県長岡市でScala入学式に参加しました。 長岡IT開発者勉強会(#NDS33)の一環として開催されたハンズオン形式の勉強会です。 id:nkgt_chkonkさんが講師をしてくれました。

ScalaはおろかJavaすら普段いじってないレベルだったので不安でしたが、やってみるととてもおもしろかったです! 以下、簡単にレポートします。

ちなみに、資料はこちらにアップされています。

https://gist.github.com/Shinpeim/6740436

環境

Better JavaとしてのScala

写経したりしてScalaの動きを確認していきました。 お題となったのはドラクエ風RPGの戦闘。

PlayerからKnight、Magicianと継承させてみたり、 traitでWeaponを作ってLongSword object(static的なやつ)を作ったりしてました。

traitはRubyのmoduleみたいなやつで、ホント便利です。

trait Weapon
trait KnightWeapon extends Weapon

trait HasWeapon {
  protected var weapon: Weapon = NullWeapon
}
trait CanEquipKnightWeapon extends HasWeapon {
  def equip(w: KnightWeapon) = weapon = w
}

class Knight extends Player with CanEquipKnightWeapon

とかできる。 RubyいじったあとにJavaやろうとしてぐぬぬってなった記憶があったので、これがあると断然違います。 また、型をコンパイラがチェックしてくれるので、たとえばMagicianWeaponを装備しようとする怒られます。

型パラメータを使ってテンプレート的なやつを試したりもしました。 上記のCanEquipKnightWeaponだとCanEquip[T <: Weapon]みたいにできます。 scalaはいい感じに型で縛ってくれるので安心感ありますね。

モナド

Listの構造やmatchによる強力なパターンマッチ、再帰構造の利点など、手を動かして実際に確認していきました。 ここらへんからちょっとペースがきつくなっていきましたが、なんとかついていけました。 でも理解はふわっとした感じだったので、復習が必要ですね。

foreachとかmap、filterなどの高階関数Rubyで触ってたのですんなり理解出来ました。 Ruby使っているうちに、自然と関数型っぽい脳みそになっていたらしいです。

Optionモナドはすごくクールでした。 型で包み込んで忌まわしきnullチェックをコンパイラに任せられます。 Java8でも取り込まれるらしいので、ぜひ使いたい。

Futureモナドは遅延評価っぽいんだけどそうじゃないみたいでした。 このあたり理解が追いついてなくて、細かい部分でどう動作するのかってのがわかってないので復習したいです。

モナドって言葉が怖くてなかなかさわれなかったんですけど、今回はじめてやってみて、そんなに怖くないものだと理解できました。 モナディック!モナディック!

Twitter Bot

まとめとして、Twitter Botをみんなで作りました。 TLにぬるぽ見つけるとガッするやつ。

twitter4jを使ったのですが、gen-ideaってやるとsbtがダウンロードまでしてくれてとっても楽でした。

最終的にはTLがガッで埋まったのが良い思い出。

LT

マインドストームのPID制御の話が熱かった! 制御系出身で、マインドストームやったりもしてたのでテンション上がりました。

あと東京勢の発表は最初から最後まで草を回避できませんでした。 草を回避できないダメ人間ですみません。

僕も発表したんですが、内容を校正して、タイミングを見てブログ記事にしようと思いますー。

まとめ

とても満足度高い一日でした。

Scalaは日ごろネットで情報を見てもメリットが良く分からなかったのですが、 入学式では丁寧に「こんなところがカッコいいよ!」と教えてもらえたので魅力がよく分かりました。

積極的に、適材適所で使えるようになりたいです。