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.
So I save the time cached in the cache itself.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::Base | |
helper_method :count_something | |
def count_something | |
cache_of_today "count-of-something" do | |
Something.count | |
end | |
end | |
def cache_of_today(key, &block) | |
cached = Rails.cache.read key | |
if !cached || cached[:created_at] < 1.day.ago | |
Rails.cache.write key, :created_at => Time.now, :value => block.call | |
cached = Rails.cache.read key | |
end | |
cached[:value] | |
end | |
end |
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.
2. Add lines below to your config/deploy.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
after 'deploy' do | |
run "crontab -r && crontab #{File.join(current_path, 'cron')}" | |
end |
that's all. crontab on production server will be refreshed after every deployment.
Labels:
capistrano,
crontab,
deployment
新しいの5個だけ残してあとは消す
Rubyで書こうとしましたが、間違いでした。
Unixすばらしい。
Unixすばらしい。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ls -t1|awk '{if(/f/ && nlines++ >= 5) print $1;}'|xargs rm |
'now loading' for Rails3 & jQuery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Set passed background-image to form type=submit just before ajax request was submitted. | |
// reset with ajax:complete. | |
// options: | |
// loadingImage: background-image | |
// loadingText: text | |
jQuery.fn.swapBackgroundToLoading = function(options){ | |
$(this).live('ajax:before', function(){ | |
var submit = $(this).find('input[type=submit]') | |
var text = submit.val(); | |
var backgroundImage = submit.css('background-image'); | |
// set loading | |
submit.val(options.loadingText || ''); | |
submit.css('background-image', 'url(' + loadingImagePath + ')'); | |
$(this).one('ajax:complete', function(){ | |
// reset | |
submit.css('background-image', backgroundImage); | |
submit.val(text); | |
}); | |
}); | |
}; |
Labels:
javascript,
jQuery,
Rails,
Rails3
rails + passengerでbasic認証
こんな感じでを追加してあげればOK。
LocationディレクティブはDirectoryディレクティブとは違ってウェブ空間に対する設定を行うので、/adminとか相対URLで指定できると。
.htpasswdの場所はホームディレクトリ以外がいいような…。
こちらを参考にしました!
Slicehost Forum - Passenger and htaccess, multiple login prompts
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にできるのですが、ディレクトリ内一括でやっちゃたいのでちょっと工夫しました。
備忘もかねて投稿。
ただ、erb.html.erbとかいうファイル名があったらおかしくなっちゃいます。
Hamlが動けばZen Codingいらず。
Haml同梱のhtml2hamlってコマンドでerbをhamlにできるのですが、ディレクトリ内一括でやっちゃたいのでちょっと工夫しました。
備忘もかねて投稿。
ruby -e "Dir.glob('*.erb'){|erb|system \"html2haml #{erb} #{erb.sub('erb', 'haml')}\"}"
ただ、erb.html.erbとかいうファイル名があったらおかしくなっちゃいます。
「開発者のキャリアプラン」は会社にとって損なだけ?
「アーキテクト」や「マネジメント」を目指すべきとされるキャリアプランに対して「ただいいものを作りたい」って答えると…上司が嫌な顔をする。そんなの無視するか、じゃなきゃ辞めちまえ、という反論に対して…
そう、誰かが辞めることは会社とって損害だと。
Weblogs Forum - Do Career Plans for Developers Actually Damage an Organisation?
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を返す
ううむ…空集合の全てって一体何だ?
そして、安易なソリューション。
Enumerable - Rubyリファレンスマニュアル
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リファレンスマニュアル
Labels:
ruby
live with no boundaries
jQueryでは.bind()でイベントハンドラを登録できます。
Ajax Requestで帰ってきたエレメントにもイベントハンドラをくっつけてあげたいので、.ready()以外にもajaxCompleteでglobalなcallbackをつけてあげました。
すると、Ajax Requestごとに、イベントハンドラが増えるじゃないですか。
調べてみると、.live()ってメソッドで重複なしのイベントハンドラ登録ができるみたい。.bind()から.live()に書き換えたら、無事重複は無くなりました。
Global callback for Ajax calls in JQuery
.live()はこちらで発見
.live() – jQuery API
Ajax Events
Ajax callbackについてはこちら。
ちなみにprototype.jsで同じ事をやるならこうかしら
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
});
Labels:
javascript,
jQuery,
prototype.js
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
=> [コメント本文全部]
Labels:
javascript,
jQuery,
ruby
write meaningful entry
Rails Insideってブログがあります。
その名の通りRuby on Rails情報が載ってるサイトです。
この度、外部の記事提供者を募集し始めるとのこと。
I'm Handing Rails Inside Over To.. You! - 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です。でも誰かが「やっぱり」前のコミットをベースに変更しているかもしれないから、やっちゃダメですって話。
何にせよ、多くの場合、「やっぱり」はよくない結果を生みますね。あと--forceも。
意思決定、合意形成はどこに行っても大事ってことで。
そんな時は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も。
意思決定、合意形成はどこに行っても大事ってことで。
Labels:
git
タダで雇えるバーチャル師匠
ネット上の誰かを仮想メンターを「雇う」って話。
Recruit virtual mentors
これはいい方法です。(一方的に)師事してしばらく経ってある程度吸収すると、気に入らないところが出てくる。そこで考えればいいわけです。それまでは自分の知識とか感覚とかをパワーフィーディングできます。
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
これはいい方法です。(一方的に)師事してしばらく経ってある程度吸収すると、気に入らないところが出てくる。そこで考えればいいわけです。それまでは自分の知識とか感覚とかをパワーフィーディングできます。
Labels:
life
Rails 2.x.xでException Notifierが動かない時
Rails2.3.5アプリにException Notifierを入れました。
諸々設定して起動したのですがこんなエラーが。
調べてみると、Exception NotifierがRails 3に移行している影響みたいです。
Missing ExceptionNotifiable module with exception_notification plugin
なので、3系対応開始前のコミットを使えとのこと。特定のコミットを使うにはscript/pluginじゃないでgit submoduleを使います。
Git clone vs Git submodule
これで一つのリポジトリの中に他のリポジトリが持てます(言い方合ってますかね)。
素直にやってみます。
動いた♪
$ 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]
動いた♪
Labels:
exception_notifier,
git,
Rails
Fakerとfactory_girlで偽物大量生産
適当なデータを作るときのお供に。
factory_girlと組み合わせて便利でした。
これが
こうなります!
適当なデータが入ってくれますねー
他にもメールアドレス、名前などいろいろFakeしてくれます。
実際はこんな風に使いました。
悪くないす。
http://rubyforge.org/projects/faker
Faker: Quick “Fake Data” Generation in Ruby
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
Labels:
factory_girl,
ruby,
testing
shoudaのマクロにブロックを渡すときの罠
shouldaのマクロを追加してActiveRecord::RecordNotFoundが起こるかチェックしてみたらどうだろう、と思っていろいろやってみて、こうなりました。
こう、呼んであげればと…。
block.bind(self).callで悩んだ。
shouldメソッドに渡すブロックには違うbindingが与えられるので、わざわざselfのを渡しなおしてあげないといけないってことのようでした(たぶん)。
ちょっとしたブロックつきのマクロをたくさん作れるのは便利なんですが、このあたりがちょっと面倒ですね…。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module RecordNotFoundMacros | |
def should_raise_record_not_found(&block) | |
should "raise 'Record not Found'" do | |
assert_raise(ActiveRecord::RecordNotFound) {block.bind(self).call} | |
end | |
end | |
end |
こう、呼んであげればと…。
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です。
右のプロンプトに時計が出るのはいいですよ。ふと見るとハマってたのに気がつくという。
CUIのユーザビリティって、ありますよね。
最初使ったときに対話式でいろいろ設定を促してくれるんで、助かりました。
特に変態的な使い方をしなくとも、もろもろ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以外でも勿論できる。
でも、リダイレクト先でテストは適当すぎる…
余談ですが、ついにauthlogicがrestful_authenticationを追い越した。
ログイン用のマクロを作った。
こういう書き方ができるのはいいすね。これは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
でも、リダイレクト先でテストは適当すぎる…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Test::Unit::TestCase | |
def self.should_require_login(http_method, method) | |
should "require login wth #{http_method.to_s.upcase} :#{method}" do | |
raise "http verb(#{http_method} is not my cup of tea)" unless [:put, :get, :post, :delete].include? http_method.to_sym | |
if UserSession.find | |
UserSession.find.destroy | |
end | |
eval(http_method.to_s + "(\"#{method}\")") | |
assert_redirected_to new_user_session_path | |
end | |
end | |
end |
余談ですが、ついにauthlogicがrestful_authenticationを追い越した。
shouldaの結果を読みやすくするgemを作りました
shouldaでautotestしてると".FE"しか出ないのが嫌でした!なので、gemを作りました。
http://github.com/fujimura/speak_your_mind
実行結果が全部テストメソッド名で出るようにしました。例えば
を走らせると
と出てくれるようにしてあげました。
私はspecが全部字で出てくれないと心配になってしまうので、これで安心です。
元々自分用だったんですが、gemにしました。gemにすればどこでも使えるから。
中身はtest/unitの出力部分のラッパーです。コンソール用出力の部分でmediatorとか使われてて、コード追うのが大変でした。
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とか使われてて、コード追うのが大変でした。
Subscribe to:
Posts (Atom)
Author
Labels
- actionmailer (2)
- ActionView (2)
- activerecord (5)
- Ajax (1)
- apache (2)
- authlogic (2)
- awk (2)
- bash (4)
- block (1)
- cache (1)
- capistrano (1)
- crontab (1)
- Debian (1)
- deployment (1)
- design (2)
- design pattern (1)
- exception_notifier (1)
- factory_girl (2)
- firefox (1)
- flash (1)
- git (2)
- haml (1)
- html (1)
- javascript (5)
- jQuery (3)
- life (2)
- linux (3)
- lisp (2)
- mail (1)
- migration (1)
- mysql (2)
- Passenger (2)
- prototype.js (1)
- Rails (26)
- Rails3 (1)
- rake (1)
- restful_authentication (2)
- Rspec (3)
- ruby (10)
- rubygems (1)
- screen (1)
- script/console (1)
- Security (1)
- shouda (1)
- shoulda (3)
- subversion (2)
- sudo (1)
- tdd (1)
- testing (4)
- thunderbird (1)
- UI (1)
- unix (1)
- vim (3)
- work (1)
- xargs (1)
- xss (1)
- zsh (1)