throw :life #=> ThreadError : "uncaught throw `life' in thread 0x854b6a8"
スローライフの意味がやっとわかった。@IRC by mayuki さん
throw :life #=> ThreadError : "uncaught throw `life' in thread 0x854b6a8"
スローライフの意味がやっとわかった。@IRC by mayuki さん
ずっと collect を使ってきたんだけど、マイノリティなのか。
今日 Symbol#to_proc 関連で map をよく見かけたから、map ってなんだっけーとか思いつつリファレンスをひいたら、あら不思議、collect のシノニムだった。IRC でそんなこと言ってたら「collect ってむしろなんだよ」的で驚いた。
map のほうが短くていいからこれからは map
にしようかと思いつつ、やっぱどうも map に慣れないいやそれは当たり前だけど。
そもそもなんで collect を使い始めたんだろう。謎だ。リファレンスマニュアルで map より上にあるからだろうか。
あーそうだ。一応忘れないように印象を書いておいてみる。ちなみに俺は数学がわからんちんな坊やなので、map が写像だとかってのは微塵も知りませんでした。いやもだめすぎなんですが、その辺を考慮してください (謎)。
map ってなんか戻り値が予想できない感じがする。配列の各要素にブロックを適用する (脳内での map のイメージは適用だった)、までは名前から分かるのだけれど、そのあとどうやって返ってくるのかが直感的にわからなかった。
対して collect は、集めて配列にするみたいなことが名前からわかるので戻り値は直感的だった。ついでに配列のメソッドにブロックを与えている時点でブロックを適用する感じを醸し出していたので、動作が予想できる感じ。
書くなら断然 map のほうが楽だなぁ……
ちなみに collect, find, select を使ってる。find_all じゃなくてなぜか select, detect じゃなくてなぜか find。この場合 find を detect にして語尾を統一すべきか。
マイノリティじゃないかも。
Rubyist Magazine - Rubyist Hotlinks 【第 1 回】 最初は map はなかったみたいだ。だから collect のほうが上にあるのか。
weblogin.rb, 名前失敗したけどもういいや。
そのうち忘れるので使い方をめもる。
@cgi.header
を使うことを前提にしてる。
api_keys = { "Flickr" => { "api_key" => "Flickr70c55b82e10021ffaaapi_key6", "secret" => "Flickrdf5secret3" }, "TypeKey" => "fsakfsTypeKeyafasAPI" }
require "weblogin.rb" @cgi = CGI.new WebLogin.open(@cgi, api_keys) do |login| begin case login.auth when :login # login したときの処理 # DB にユーザ ID とユーザ情報を保存したり end rescue WebLogin::NoActionError => e puts @cgi.header("type" => "text/plain") puts login.services # 有効なサービスの配列 end end
上のようなのを認証スクリプトとしておいとく。このサイトだと /login.rb がコレ。ログインスクリプトの query_string が logout だったらセッションを破棄してリファラにリダイレクトする。ちょっとアレ。
/login.rb/Flickr?return_path= のようなリクエストをすると Flickr にリダイレクトして認証させる。認証されるとコールバック (Flickr の対応する API key のコールバックには http://example.com/login.rb/Flickr/callback のように指定しておく) にリダイレクトされるので、セッションに情報をセットして、return_path にリダイレクトする。
login.auth は、path_info に何も指定されていなかったりすると NoActionError を投げる。
require "weblogin.rb" @cgi = CGI.new WebLogin.open(@cgi, api_keys) do |login| if login.service # login している場合 login.service #=> "Flickr" login.id #=> "25514198@N00" login.user_name #=> "cho45" login.profile_uri #=> "http://www.flickr.com/photos/25514198@N00/" login.icon #=> "http://static.flickr.com/23/buddyicons/25514198@N00.jpg" login.full_name #=> "Hiroh Satoh" else # login していない場合 # id その他上記メソッドは全て nil end end
いまいち気持ち悪いんだけどどうにもこうにもわからんのでこんな感じ。ブロックをとっているのはセッションファイルを確実に閉じるため。fcgi 環境で死ぬことがあったのでこういうことやってる。
WebLogin クラスは、それ以下にある、サービス名に対応するクラスをインスタンス化してメソッドを呼び出す。例えば /login.rb/Flickr?return_path=somepath の場合、WebLogin::Flickr.new(@cgi, @session, @api_keys["Flickr"]).auth
が呼ばれる。
各サービス名の auth
メソッドはサービスの認証画面にリダイレクトする。サービスは /login.rb/Flickr/callback にリダイレクトする。
callback が指定されている場合、インスタンス化されたサービスクラスの callback メソッドを呼ぶ。callback メソッドはユーザ情報をまとめて Hash
にして返す。WebLogin
はその Hash
をセッションに保存して、最初に指定された return_path にリダイレクトする。
いろいろアレなことが思い浮かんだけどあとで考えよう。
new
にブロックって一般的じゃないんじゃ?という指摘をうけたので open
にした。確かに new
にブロックは微妙だった。