blog.sowatchasayin

Rails etc.

RubyConf2010(1)

RubyConf 2010に参加しました。
Ruby界最大の国際カンファレンスです。
網羅的なレポートは書けないので、気になったトピックについてのみ漫然と記しておこうと思います。

Dave Thomas - Keynote
Dave Thomasの基調講演はRuby10年史、3つのチャレンジー自分とは違う誰かをインスパイアすること、自分達を多様化すること、レールを外れることーについてでした。

発表の中で気になったのは、オープンソースの世界の女性の少なさはコミュニティの文化に由来するところもある、という指摘。いわゆるハッカー文化/倫理の、自分たちは「メインストリーム」から外れた存在である、という自己定義の内に、女性をそのメインストリームとみなす価値観が含まれている、という指摘はもっともだと思いました。自分がコミュニティの価値観から外れる存在であった時の居心地の悪さは、恐らくこのブログを読んでいる人なら感じたことはあると思います。

そして、これは日本でも起こっている現象かと。
向こうで言うハッカー倫理にあたるものは、こちらでは「リア充」って言葉になると思います。
リア充」って表現もハッカー倫理と同じように女性への特定の視点(もしくは視点自体の意図的な排除)を含んでいます。ハッカー倫理的なものと違って、こちらではプログラマー=「非リア」という自己定義は意図的なものではありません。でも、それを否定しない雰囲気はありますよね。そういうラベル付けを受け入れてしまっていることが、自分のコミュニティの多様性を損ねているという点は認識すべきです。

ずっと感じていた違和感をうまく形にしてくれたキーノートでした。
これを機にコミュニティの多様性について考えてくれる人が増えると良いのですが。

Rails cache by memory_store with 1-day expiration

Rails cache has no expiration by default.
So I save the time cached in the cache itself.

Sync crontab and Rails with Capistrano

1. Put `crontab -l` into a file and add it into your repository
2. Add lines below to your config/deploy.rb



that's all. crontab on production server will be refreshed after every deployment.

新しいの5個だけ残してあとは消す

Rubyで書こうとしましたが、間違いでした。
Unixすばらしい。

rails + passengerでbasic認証

こんな感じでを追加してあげればOK。
LocationディレクティブはDirectoryディレクティブとは違ってウェブ空間に対する設定を行うので、/adminとか相対URLで指定できると。


<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName xx.xxx.xxx.xxx
ServerAlias xx.xxx.xxx.xxx
DocumentRoot /var/www/myapp/current/public
<Directory /var/www/myapp/current/public>
Options FollowSymLinks -MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
<Location /admin>
AuthUserFile /home/somebody/.htpasswd
AuthGroupFile /dev/null
AuthName "Please enter your ID and password"
AuthType Basic
require valid-user
</Location>
</VirtualHost>


.htpasswdの場所はホームディレクトリ以外がいいような…。

こちらを参考にしました!
Slicehost Forum - Passenger and htaccess, multiple login prompts

カレントディレクトリの*.erbを*.hamlに変換

Hamlいいですねー 楽です。キモ綺麗。
Hamlが動けばZen Codingいらず。

Haml同梱のhtml2hamlってコマンドでerbをhamlにできるのですが、ディレクトリ内一括でやっちゃたいのでちょっと工夫しました。
備忘もかねて投稿。

ruby -e "Dir.glob('*.erb'){|erb|system \"html2haml #{erb} #{erb.sub('erb', 'haml')}\"}" 

ただ、erb.html.erbとかいうファイル名があったらおかしくなっちゃいます。

「開発者のキャリアプラン」は会社にとって損なだけ?

「アーキテクト」や「マネジメント」を目指すべきとされるキャリアプランに対して「ただいいものを作りたい」って答えると…上司が嫌な顔をする。そんなの無視するか、じゃなきゃ辞めちまえ、という反論に対して…

and this takes me to my second point - does this actually damage the organisation because people start leaving or, worse, playing political games, feeling stressed or distracted by the things they have to do in order to live up to the career structure

そう、誰かが辞めることは会社とって損害だと。

Weblogs Forum - Do Career Plans for Developers Actually Damage an Organisation?

Enumerable.all?は空だと常にtrueを返す

ううむ…空集合の全てって一体何だ?

irb(main):001:0> [].all?{false}
=> true
irb(main):002:0> [1].all?{false}
=> false


そして、安易なソリューション。

class Array
def not_empty_and_all?(&block)
return false if self.empty?
self.all? &block
end
end


Enumerable - Rubyリファレンスマニュアル

screen文字化け

windows+puttyで文字化けしちゃうときはこれを試してみるとよいです。

$ vi ~/.screenrc
defkanji utf8

live with no boundaries

jQueryでは.bind()でイベントハンドラを登録できます。
Ajax Requestで帰ってきたエレメントにもイベントハンドラをくっつけてあげたいので、.ready()以外にもajaxCompleteでglobalなcallbackをつけてあげました。

function init(){
bindEvent1(); //色々bindしている
bindEvent2();
bindEvent3();
};
$(document).ajaxComplete(init);
$(init);

すると、Ajax Requestごとに、イベントハンドラが増えるじゃないですか。

調べてみると、.live()ってメソッドで重複なしのイベントハンドラ登録ができるみたい。.bind()から.live()に書き換えたら、無事重複は無くなりました。


Global callback for Ajax calls in JQuery

.live()はこちらで発見

.live() – jQuery API
Ajax Events
Ajax callbackについてはこちら。

ちなみにprototype.jsで同じ事をやるならこうかしら

function init(){
bindEvent1();
bindEvent2();
bindEvent3();
};
window.onload = init;
Ajax.Responders.register({
onComplete: init
});

ArrayのjQuery的な挙動をRubyで

あの勝手にmapしてくれる感じをRubyでも…。適当、かつ冗談です。


module Jq
def method_missing(method_name, *args)
self.map{|a|a.send(method_name, *args)}.flatten
end
end

class Array
include Jq
end


こういうことができます

User.all.articles.comments.body
=> [コメント本文全部]

やっちまった!


setup do
#ここにコントローラのコードを書いてしまった
end

write meaningful entry

Rails Insideってブログがあります。
その名の通りRuby on Rails情報が載ってるサイトです。
この度、外部の記事提供者を募集し始めるとのこと。
I'm Handing Rails Inside Over To.. You! - Rails Inside


下記、提供記事のガイドラインから引用です。
一般的なブログを書く心得として使えそう。

Some content guidelines:

* News, opinion pieces, event summaries, and link roundups all welcome.
* At least 3 paragraphs.
* At least 200 words. Ideally 220-280 for news, longer as necessary for tutorials or opinion pieces.
* At least one image - which we have the rights to run.. if you use a Creative Commons licensed image, please credit it appropriately.
* Nothing racist/profane/etc, sorry!
* Ensure that the first paragraph is in the 50~80 word range and summarizes (or at least properly introduces) the topic of the post. See existing posts for guidance.
* If something is more suited to RubyFlow or already exists on your own blog, post it on RubyFlow.
* Content should be new/fresh for Rails Inside initially, but you can post it to your own blog too afterwards, of course :-)

最初のパラグラフをサマリにする、ってのは理系論文スタイルですね。
学術論文のメディアとしての洗練され具合は面白いです。査読制度とか。

git commit --amendはpushしたらやっちゃダメ

commitに「やっぱり」をかけたい時、ありますよね。
そんな時はgit commit --amendです。直前のコミットにワークツリーの変更を後乗せして、さも元々そうだったかのように見せることができます。
さてそれをpushするときどうするか…。普通にやるとgitに怒られます。

そこで質問
How do I push amended commit to the remote git repo?

--forceをつければOKです。でも誰かが「やっぱり」前のコミットをベースに変更しているかもしれないから、やっちゃダメですって話。

I actually once pushed with --force to git.git repository and got scolded by Linus BIG TIME. It will create a lot of problems for other people. A simple answer is "don't do it".

because if someone already got your changes, then when they try to pull again, it might fail.


何にせよ、多くの場合、「やっぱり」はよくない結果を生みますね。あと--forceも。
意思決定、合意形成はどこに行っても大事ってことで。

タダで雇えるバーチャル師匠

ネット上の誰かを仮想メンターを「雇う」って話。

To recruit a virtual mentor, first find someone whose success and ideas you respect. Second, find literally everything that they’ve written. Third, find everything in video that they’ve done. Finally, find all of their products or apps or books and get them too. Once you’ve consumed everything that they’ve produced, setup a google alert for them and read anything new as it comes out

[意訳]
まず、成功していて考えがリスペクトできる人を探す。次に、彼らが書いたものを全部見つける。そんで動画も見る。製品、本とかアプリも全部ゲット。
彼らの作ったもの全部をこなしたら、グーグルのアラート(google readerとかすね)をセットして、新しく出るを速攻チェックできるようにして、全部読む。

Recruit virtual mentors

これはいい方法です。(一方的に)師事してしばらく経ってある程度吸収すると、気に入らないところが出てくる。そこで考えればいいわけです。それまでは自分の知識とか感覚とかをパワーフィーディングできます。

Rails 2.x.xでException Notifierが動かない時

Rails2.3.5アプリにException Notifierを入れました。

$ script/plugin install http://github.com/rails/exception_notification

諸々設定して起動したのですがこんなエラーが。
/var/lib/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:105:in `const_missing': uninitialized constant ApplicationController::ExceptionNotifiable (NameError)



調べてみると、Exception NotifierがRails 3に移行している影響みたいです。
Missing ExceptionNotifiable module with exception_notification plugin

なので、3系対応開始前のコミットを使えとのこと。特定のコミットを使うにはscript/pluginじゃないでgit submoduleを使います。
Git clone vs Git submodule
これで一つのリポジトリの中に他のリポジトリが持てます(言い方合ってますかね)。

素直にやってみます。

$ git submodule add git://github.com/rails/exception_notification.git vendor/plugins/exception_notification
$ cd vendor/plugins/exception_notification
$ git checkout -b rails2 e8b603e523c14f145da7b3a1729f5cc06eba2dd1
$ script/server -e production
=> Booting WEBrick
=> Rails 2.3.5 application starting on http://0.0.0.0:3000
** Erubis 2.6.5
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-01-29 17:56:33] INFO WEBrick 1.3.1
[2010-01-29 17:56:33] INFO ruby 1.8.7 (2009-06-12) [i486-linux]

動いた♪

Firefoxでいろいろ隠したい

まずはメニュー
Hide Menubar
そしてタブ
Hide Tabber
最後に全部
Hide GUI bars

Hide GUI barsが非常によい。

Fakerとfactory_girlで偽物大量生産

適当なデータを作るときのお供に。
factory_girlと組み合わせて便利でした。

これが

Factory.define :message do |f|
f.title Faker::Lorem.sentence
f.body Faker::Lorem.paragraph
end


こうなります!

>> y Factory.build :message
--- !ruby/object:Message
attributes:
created_at:
body: Quasi ab fuga reprehenderit quia. Nostrum laud...(以下略)
title: Alias dolor velit ut et vitae magnam aut non.
updated_at:
recipient_id:
sender_id:

適当なデータが入ってくれますねー
他にもメールアドレス、名前などいろいろFakeしてくれます。

実際はこんな風に使いました。

@a_to_b = Factory.create(:message, :sender_id => @Aさん.id, :recipient_id => @Bさん.id)
@c_to_d = Factory.create(:message, :sender_id => @Cさん.id, :recipient_id => @Dさん.id)


悪くないす。
http://rubyforge.org/projects/faker
Faker: Quick “Fake Data” Generation in Ruby

shoudaのマクロにブロックを渡すときの罠

shouldaのマクロを追加してActiveRecord::RecordNotFoundが起こるかチェックしてみたらどうだろう、と思っていろいろやってみて、こうなりました。

こう、呼んであげればと…。

should_raise_record_not_found {get :edit, :id => @なんか.id}


block.bind(self).callで悩んだ。
shouldメソッドに渡すブロックには違うbindingが与えられるので、わざわざselfのを渡しなおしてあげないといけないってことのようでした(たぶん)。
ちょっとしたブロックつきのマクロをたくさん作れるのは便利なんですが、このあたりがちょっと面倒ですね…。

zsh導入

以下を参考に入れました。
最初使ったときに対話式でいろいろ設定を促してくれるんで、助かりました。
特に変態的な使い方をしなくとも、もろもろbashより気が利いてると思います。viモードもbashより調子いい。
漢のzsh
zsh: Prompt Expansion
zshの基本的な使い方 1/3 「導入~基本設定」編
ANSI color codes

.zshrcです。

# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=100000
SAVEHIST=100000
setopt appendhistory autocd extendedglob notify auto_pushd correct
unsetopt beep nomatch
bindkey -v
# End of lines configured by zsh-newuser-install
# The following lines were added by compinstall
zstyle :compinstall filename '/home/fu/.zshrc'

autoload -Uz compinit
compinit
# End of lines added by compinstall

autoload colors
colors
SPROMPT="%B%{${bg[green]}%}%r ? %{${reset_color}%}%b n,y,a,e :"
PROMPT="%B%{${fg[green]}%}%n@%m %~% %(!.#.$) %{${reset_color}%}%b"
RPROMPT="%{${fg[magenta]}%}%*%{${reset_color}%}%"


autoload history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^r" history-incremental-search-backward
alias lv='lv -c'
alias ls='ls --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
export PATH=/var/lib/gems/1.8/bin:$PATH


右のプロンプトに時計が出るのはいいですよ。ふと見るとハマってたのに気がつくという。

CUIのユーザビリティって、ありますよね。

shouldaでlogin_requiedのテスト

shouldaです。
ログイン用のマクロを作った。

こういう書き方ができるのはいいすね。これはauthlogicですが、authlogic以外でも勿論できる。

context "ArticlesController" do
should_require_login :get, :new
should_require_login :post, :create
should_require_login :get, :edit
should_require_login :put, :update
should_require_login :delete, :destroy
end


でも、リダイレクト先でテストは適当すぎる…


余談ですが、ついにauthlogicがrestful_authenticationを追い越した。

redirect_to :back のテスト!!!

でっきたー
@request.envに適当なリファラを入れてあげればOK。
Ruby Nuggets: Testing redirect_to :back shortcut
適当すぎる

shouldaの結果を読みやすくするgemを作りました

shouldaでautotestしてると".FE"しか出ないのが嫌でした!なので、gemを作りました。

http://github.com/fujimura/speak_your_mind

実行結果が全部テストメソッド名で出るようにしました。例えば

context "Test" do
should 'success' do
assert true
end

should 'fail' do
assert false
end

should 'error' do
raise
end
end

を走らせると

E Test should error.
F Test should fail.
. Test should success.

と出てくれるようにしてあげました。
私はspecが全部字で出てくれないと心配になってしまうので、これで安心です。
元々自分用だったんですが、gemにしました。gemにすればどこでも使えるから。

中身はtest/unitの出力部分のラッパーです。コンソール用出力の部分でmediatorとか使われてて、コード追うのが大変でした。

Author

Fujimura Daisuke
http://fujimuradaisuke.com

Labels