2012/01/19
eneloopの違いまとめ。種類を調べた。比較した。
エネループが種類多すぎてよく分からないので調べてみた。エネループには種類が多すぎる。
気にするべきポイント
- エネループ世代別
- 発売時期によって異なる、市場には旧バージョンがあふれている
- 最新版はマイナーチェンジ版がおおい
- さらに種類が増えた
- 充電器との組み合わせ
- 充電器にも旧版新版がある。
(1)エネループには世代別に3種類ある。
最古版エネループ | 旧版エネループ | 最新版エネループ |
発売時期で細かい差異がある。互換性はある、性能も大きく変わらないので、神経質でなければ気にすることではない。
見分け方のポイントは回数。最新版と旧版は充電回数の表記が違う
1500回と書いてる物は古い。現行は1800回。
旧版の方が安い。だからその辺は随意に。次回からパナソニック版になる。だからまた新旧の差で混迷を極める。
- ポイント
- 1800回と書いてあったら最新版。それ以外は旧版。ただし旧版の方が安く買えることが多い。
(2)最新版エネループには3種類が充電容量別にある。
見た目でぱっと違いが分かる3種類。
3種類あります。
- eneloop
- eneloop lite
- eneloop pro
- eneloop
- 現行通常版
- lite
- 価格を下げたもの。その分容量少ない
- pro
- 容量を大きくした。その分値上がる
これらは、通常版をベースに用途に応じた使い分けが出来るようになっている。
これはそれぞれに単3・単4がある。
見た目での区別。
eneloop | eneloop-lite | eneloop pro |
---|---|---|
eneloop | eneloop-lite | eneloop pro |
---|---|---|
1900mAh | 950mAh | 2400mAh |
1800回 | 2000回 | 500回 |
基本のeneloop | eneloop lite Liteは容量50%ダウン。 その分安価。 繰り返し性能10%UP | eneloop pro Proは容量25%アップ、 その分高価 繰り返し性能75%ダウン USB出力で使うと便利そう |
用途別になっているので、用途が分からなければ通常版を買うのがよい。
(3)ただし色はアテにならない
限定カラーとかあるから、基本色以外の色はアテに出来ない。
基本色以外を買うと、色で区別できなくなるよ!
(4)マイナーチェンジ版のplus
特殊マイナーバージョンとしてのPlus
性能は通常のエネループと変わらない
eneloop plus は 通常のeneloopをより安全性を高めた商品。正直なはなし、存在価値が分からない。Appleみたいに従来品を廃止してEneloopを全部Plusに置き換えたら良いのに。
充電池についてのまとめ
- eneloop基本バージョン
- 1800回 1900mAh
- eneloop 旧バージョン
- 1500回
- eneloop 最古バージョン
- 1000回
- eneloop plus
- より安全性を高めた付加価値商品。
- eneloop lite
- 容量さげて、手軽に買える。廉価版
- eneloop pro
- 容量がほしい人向け。ただし充電回数少なめ。
(5)充電器について
充電器についても知っておく必要がある。
充電器も種類が多い。
(三洋電機カタログより)
これにさらに旧バージョンや特殊形状が存在する。
(6)エネループ充電器には標準充電器がある。
- NC-TGN01
- これがエネループの充電器の比較の基本
今のところこの型番を基準に考えればいいみたいですね。
(7)値段と機能の違い
NC-TGR01とNC-TGL01の違い。
(廉価版)
安い方を買ったときには、性能が50%ダウン、だから値段も50%ダウン。
- 充電時間が2倍以上かかる。
- 1本で充電できない。
- その分価格は安い(50%オフ)
充電時間は2倍時間がかかる、2本ペアになる、だから価格も50%オフ。
高い物はドコが違うのか
- 1本ごとに充電完了が分かるモニタ搭載。
- バッテリーチェッカーが一本分搭載。
- 3倍速充電対応。
高い価格帯の商品にがついています。*1
(8)急速・高速充電対応
3倍速と2倍速があるです
(ハイーチェッカ) |
これらは3倍速対応
「急速」充電対応
急速充電対応と書かれた物は基本的に2倍速。三倍速があるけれど「2倍速が急速充電器です。」
(9)エネループプロ充電器は?
エネループプロ充電器は通常の物です。色違い。型番はすべてNC-TGR01です。
(エネループプロ充電器) | (エネループプラス充電器) |
プラス専用とプロ用と書いてあるけど、通常のエネループ充電器と同じ型番です。
充電器のまとめ
廉価版=基本版 - 急速充電機能なし = 1000円 高価版=基本版+充電チェッカー + 一本単位での充電チェック 携帯版=基本版 の半分サイズ、充電は2本単位
プロ用やプラス専用はその色だけ。中身は同じらしい
エネループ買おうと思ったけどありすぎて迷う
ヨドバシカメラの店頭でも、店員に説明を受けている人が多い。僕も正直よく分からない。
- 鉄則
- 最新版のセットを買う。
ライトは安いけど充電時間かかりすぎて使えない。
最後に挿したのどれだっけ?
継ぎ足し充電ができるeneloopの特性上使い終わったら、とりあえず挿しておく。おわったら取り替えるとい
カジュアルな使い方が便利。
・充電しておく。
・取り出す。
・なんとなく不安だから充電しておく
・とりあえず満タンにしておく。
などのカジュアルな用途を満たすには、4本が個別に充電できて、充電済が一目で分かった方が良い。それもどれが充電済みで、まだかが一目で分かった方が便利。
なので充電済ライトが個別に光る物を選ぶべきです。
Amazonでは、デザインが似過ぎて分からない
Amazonの写真では、形が似ていて一目で区別がつかない。
- 充電回数
- 1800回が最新版
- 型番
- 充電器の型番で種類が分かる。
(11)エネループ一覧表
これだけ見ても分かるように,種類は数限りなく存在する。
しかも、三洋電機からパナソニックになったので、パナソニック版エネループとかあってもう、手がつけられない。
感想:エネループは。なんでこんなことになったのか。
ブランドイメージの確立には成功した。エネループは成功。ブランドの確立とコンセプトの確率には成功した。
でも、成長を維持するのに失敗している。
顧客ニーズに応えるコトがサービスではない。好例
ラインナップの迷走、コンセプトの迷走。増え続ける種類。
顧客ニーズに応えたつもりかもしれないけれど、顧客ニーズに応えることが正しくない好例だとおもう。顧客ニーズに応えたつもりだろうけど、むしろ分かりづらいラインナップ。色もわかりにくい。
迷走するラインナップ
Lite/Pro/Plusの区別に、バージョンの違いはもはや迷走と断言する。
唯一の救いは互換性が保たれていること。しかし互換性は電池そのものの形状と電圧基準のおかげであって、三洋電機関係ないので。
「手軽に使える」という当初コンセプトが「種類多すぎて、使い分けが大変」になって崩壊してるよね。。。
モバイルブースターとエネループの充電が一カ所ですむようにしてほしいです。Qiはちょっと初期投資多すぎて困るし。電力も無駄になりそう。携帯電話が対応してたら使うのにね。エネループは「捨てない」という新しいlifestyleの提案だった。その新しさを取り戻してほしいです。
エネループの魅力が死んでしまう。こんなにラインナップがあると管理が面倒で。エネループの魅力が死んでしまう。
ジョブズなら、「もっとわかりやすく、2種類にしろ」と言ったに違いない。
もっとシンプルにやりましょう。
AmazonのAA
もしよかったら踏んでください。オススメです。
eneloop3倍速対応急速充電器セット(単4形4本付)
感謝です。
AA踏んでくださった方!感謝です!!
徹夜でエネループ調べて、その甲斐がありました。お役に立ててうれしいです。
僕の徹夜が報われた気がします。
2012-01-20追記。
色で区別とか言われたので、色を適当に買うと、区別に使えないことを明記するなど。
2012-01-25追記
なんかたくさん買っていただいたみたいです。みなさんの優しさに感謝です。
ありがとうございます。
2012-01-26 追記
更にたくさんの人に買っていただいたみたいです!!!
皆さんのお役に立てて嬉しいです。みなさんの優しさに嬉しいです。
*1:ただし上記の三種類の機能が全部ついた物はないみたい
2012/01/18
Stringsコマンド:プログラム中で文字列として認識可能なものを全部表示してみる
stringsコマンドは、バイナリコンパイルされたバイナリを開き、ASCII文字列っぽいものがあれば、文字にして出力する。
バイナリディタで文字を探すなら、この方が速いかもしれない、バイナリ・アドレスは分からないけど、あるかないかはすぐ分かる
stringsコマンドやってみた
SQLiteのファイルを解析してみた。
わーい、CreateTableがいっぱい見える。
aliases.dbにつかう
postmapコマンドなどの、設定ファイルをバイナリに変換する系で、変換忘れてないか確認するのに使う。
takuya@debian00:~$ sudo strings /etc/aliases.db [sudo] password for takuya: root webmaster root usenet "|/usr/local/bin/catch " sort root security
LocalStroageが便利になる、JSON.stringfy
LocalStroageにオブジェクトを入れるには、キーバリューなので、ちょっとめんどくさい。シリアライズをどうするのか
JSON.stringifyを使ってシリアライズ
そのため、JSオブジェクトを扱いたい場合は、JSON.stringifyとJSON.parseを利用するなどして文字列に変換してから利用することをおすすめします。
// 配列をJSON.stringifyで文字列に変換してから保存 var ary = ["aaa", "bbb"]; localStorage.setItem("hoge", JSON.stringify(ary)); // 取り出した文字列をJSON.parseでJSオブジェクトに変換する JSON.parse(localStorage.getItem("hoge")); > ["aaa", "bbb"]http://d.hatena.ne.jp/pikotea/20101224/1293197750
JSONを取り出したりJSONにエンコするには
ブラウザ組込のJSONオブジェクトを使うと便利でしょうね
StorageEvent
Web Storage には、StorageEvent というイベントがあるそうです
// StorageEventを登録 window.addEventListener("storage", function(evt) { console.log("old:" + evt.oldValue + "/new:" + evt.newValue); }, false);http://d.hatena.ne.jp/pikotea/20101224/1293197750
WebStorageを使った瞬間にイベントが発生する。WebStrageに保存するタイミングで動作する方がテストが楽だし、コード簡潔になる。とくにGUIのクリックイベントが多発するようになると必須のイベントだと思う
参考資料
システムのRubyの更新:DebianのAPTでインストールされた物
debian の rubygemsパッケージを更新しようとしている。
- あるシステムでは。できる限りAptで管理するべきかもしれないし
- あるシステムでは、ユーザーごとにRuby環境を作るべきかもしれない
でもいろいろ考えるの面倒くさい。とりあえずシステムのrubygems環境を更新したらいいよね。
ってことでやってみた
とりあえずシステムのrubygemsを新しくする
gem update --system
apt の場合、--systemであまりに新しいものを入れると、互換性の問題に引掛かもしれないので、
自己責任でやれと言われる。
やります。
$ gem install rubygems-update $ update_rubygems
これで出来上がり。手早いですね。
ユーザーごとにRuby環境を作るには
rvmが一番楽。いろいろとやり方はあるんだし、gemのインストールとかいろいろ工夫してたんだけど、
RVMでもう大丈夫っぽい(ただしCygwin環境な人たちはCorei7以外でやらないように、ビルド時間が巨大です)
参考資料
http://d.hatena.ne.jp/r_kurain/20090725/1248523753
http://higelog.brassworks.jp/?p=244
cygwin だとこういうのを試したほうがいいかも。
JavaからjRubyのソースコードを読み込んで使う。
JavaからjRubyを起動すると、JavaにRubyインタプリタを組み込むことが出来る。
どうやるのかなと思ってたら。
evalしろや。ってことらしい。
まじEvalしとる。
package takuya.morioka; import java.io.*; import org.jruby.Ruby; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; public class RubySample { public static void main(String[] args) { Ruby ruby = Ruby.getDefaultInstance(); try { FileReader reader = new FileReader("test.rb"); IRubyObject obj = ruby.evalScript(reader, ""); #script コードの実行 System.out.println("Result: " + obj); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
RubyのクラスをJavaクラスとして使う
//Rubyのインタプリタを持ってくる。 Ruby ruby = Ruby.getDefaultInstance(); ThreadContext context = ruby.getCurrentContext(); try { FileReader reader = new FileReader("test.rb"); //ソースを読み込む ruby.evalScript(reader, ""); RubyClass rclass = ruby.getClass("MyDateTime"); IRubyObject robj = rclass.callMethod(context,"new"); IRubyObject obj = robj.callMethod(context,"getDateTime"); System.out.println("Result: " + obj); } catch (FileNotFoundException e) { e.printStackTrace(); }
実際に使う箇所
RubyClass rclass = ruby.getClass("MyDateTime");
使いどころ。難しい。
RubyはDSL的な処理が出来るので、Ruby書式で設定ファイル作らせて、Javaで読み込んで使うとか。
インタプリターパターンですよねぇ。使いどころは難しい。
参考資料
Windowsの自動ログイン設定
Windowsの自動ログイン設定はコマンドプロンプトから起動するのが手っ取り早い
controle userpasswords2
passwords の複数形に注意
これで起動すると
選択画面が出てきて
パスワード入力が必要のチェックを外して、OKを押す。
するとパスワード覚えさせるから、今のパスワードを確認のために入れてねって言われる。入力したら設定完了
LinuxのJOINコマンドがおもしろそうなので試してみた
JOINコマンドがあります。これは便利なのかもしれない。ファイルがそろっていることが前提ですけど
わかりやすい図があります。
Linuxコマンドでテキストデータを自在に操る - じっくりコトコト煮込んだみかん
やってみた。
シンプルで良いですね。
でも正直いえば、箱形選択が簡単にできるエディタ使ってたら用無しな気もする。
10,0000行とかなら使い勝手良さそうだけど、そのときはスクリプトでやるかも。
2012/01/17
MacのOpenコマンドのすすめ
Openコマンドは便利です。
alias opera="open /Applications/Opera.app"
とすればOperaがコマンドから起動します。
SpotLightで起動するより速いかもね、
Openは関連付けられたアプリを起動するので
open test.rb open test.xlsx
などとしてもちゃんと起動する。
もし関連付けられたアプリがないときは
テキストエディットで起動される。
はてなフォトライフにアップロードするスクリプト
何で今までやらなかった。
アップロードが楽ちんに
使い方
/usr/local/bin/fotolife *.png
はてなフォトライフにアップロードするスクリプト
#!/usr/bin/env ruby #!/usr/bin/env ruby require 'rubygems' require 'net/http' require 'wsse' require 'base64' require 'optparse' opt = OptionParser.new opt.on("-u","--url"){ $show_img_url = true } opt.parse!(ARGV) $KCODE='u' if ARGV.size < 1 or not ARGV.all?{|e| File.exist? e} then puts "usage: #{__FILE__} 画像ファイル名 ファイル名はタイトルになる。 タイトル指定したいときはファイル名を使えば良い。" exit 2 end ARGV.each{|e| f_name = e a = File.basename(f_name).split('.');a.pop title = a.join('.') content = Base64.encode64(open(f_name).read) xml = "<entry xmlns=http://purl.org/atom/ns >"+ "<title>#{title}</title>"+ "<content mode='base64' type='image/jpeg'>#{content}</content>"+ "</entry>" username, password = %w!hatena_id my_password! ##←ここにID/PWを書く http = Net::HTTP.start("f.hatena.ne.jp", 80) response = http.get('/atom',{'X-WSSE' => WSSE::header(username, password )}) response = http.post('/atom/post',xml, {'X-WSSE' => WSSE::header(username, password )}) response.body =~ /<hatena:syntax>([^<]+)<\/hatena:syntax>/ foto_id = $1 puts "[#{foto_id}](#{title})" unless $show_img_url if $show_img_url then user = foto_id.split(/:/)[2] f_id = foto_id.split(/:/)[3].gsub /j/, "" puts "<img src=http://cdn-ak.f.st-hatena.com/images/fotolife/t/#{user}/#{f_id[0,8]}/#{f_id}.jpg />" end }
アップロード
楽ちん。
Automatorと組み合わせて、ドラッグドロップで送信できてもいいかも。
2012/03/06改訂
- -u オプション
- IMGタグ生成
をつけた。-u なしだと、はてダ埋め込み用の専用タグになるようにした。
実行例
フォトライフは面倒くさいのです。ブラウザのアップロードから写真埋め込みまでがとても面倒。はてなダイアリに写真を載せるのがとても面倒だった。
これでとても簡単になった。
2012/01/16
オレオレDropBoxをrsyncで作る。
DropBoxは便利らしい。でも同期遅いし、アカウント必要だし。なにより手元に2TBのHDDが転がってる物を生かしたい
ファイル監視して、rsync起動
#!/usr/bin/env ipyw from System.IO import * import subprocess path = "C:\\Program Files\\MySync Suite\\Users\\User0001\\Album" fsw = FileSystemWatcher() fsw.Path = path def watcherhandler(*args): subprocess.call('rsync -avz --delete -e "ssh -i /home/takuya/.ssh/id_rsa -o StrictHostKeyChecking=no " {0} takuya@s1:~/casio '.format(path) ) fsw.Changed += watcherhandler fsw.Created += watcherhandler fsw.Deleted += watcherhandler fsw.Renamed += watcherhandler fsw.IncludeSubdirectories = True fsw.EnableRaisingEvents = True while(True):fsw.WaitForChanged(WatcherChangeTypes.All, -1)
ファイルディレクトリの変更を監視、変化に応じて、rsyncを起動してファイルを転送する。
- FileSystemWathcer
- 細かい説明は別エントリに書いた-----> ironpython で Windowsのフォルダを監視する。
rsync の細かいオプションは重要。
- -o StrictHostKeyChecking=no
- known_hostsにないホストだったらYES/NOだすかどうか→無視
- -i path/to/key
- id_rsaのキーファイル。WindowsのSYSTEMはフルアクセス(これは無条件でそうなる)でもほかユーザーから読めないこと必須。
- takuya@servername
- 転送先へのログイン名。そのままだとSYSTEMになってしまうので。
あとはこれをサービス登録して
cygrunsrv --install MysyncWatcher --path `cygpath -wa /home/takuya/bin/wacher.py` --chdir `cygpath -wa /home/takuya/bin/`
常駐しておけば、Mysync suiteで同期するたびにファイルがバックアップされる。
たったこれだけでも相当便利な気がする
NASで良いジャン?
ちがうんだよ。NASだと読み込み遅くて邪魔くさいんだよ。
なにより、ネットワークに左右されない。
ファイルが出来たタイミングで同期する。コレが重要。たとえば、「CDを取り込んだら転送。」「写真を取り込んだら転送」「ソースコード編集したら、送信」
ScanSnapとの組み合わせが理想的か。
ScanSnapと組み合わせてファイルと転送したり、ファイルを変換したり、メールに送ったりできるね。ScanSnapのソフトウェア更新を待たなくてよくなる。
応用範囲は幅広い。
eo Myポータルの請求書をスクレーピングした。DropBoxに明細PDF送ってほしいわ
「請求書出来ました、"ここ"にアクセスしてください。」そんなメールは要らない。おまえらもスクレーピングしてやる。
eoのMyポータルの請求内訳を直接取得する。だって、ロード長いし、クリック多くて面倒なんだもん。
require 'rubygems' require 'mechanize' m = Mechanize.new #ログインページ m.get 'https://my.eonet.jp/tctrpp/LoginAction.do' m.page.forms[0].fields[0].value= "eoログインID" m.page.forms[0].fields[1].value= "パスワード" m.page.forms[0].submit #初回ロード m.page.forms[0].action="/prtct/mp/mp.do" m.page.forms[0].submit #セッション登録 m.get 'https://my.eonet.jp/prtctp/MKA10V010Init.do?hyoujShubt=0' #ページ移動 m.get 'https://my.eonet.jp/prtct/mk/mka10/MKA10V010.jsp' body = m.page.search('div#contents') #保存 open('eo請求内訳.html',"w"){|f| f.write body}
これでOK.
請求書のWEB確認はめんどくさい。
各企業のWEB明細は、クリック多くて面倒だし、戻る禁止とか訳が分からない。たかが請求情報だけのために、どれだけ制御するんだろう。
請求データをメールで送ってくれれば良いのにな。直接開けるリンクすらCookie切れで頻繁にログインし直しになる。OAuthでRead権発行されれば、明細スクレーピングのポータルサイトが戦国時代になるのに。
eoはWEBアクセス手順が煩雑で
eoポータルはAjax/jQueryにparant.docmentにiframeといった、javascriptの新旧技術がてんこ盛りでカオスだった。あの設計はメンテできないだろう。だから、さらに5年は使われると思う。なのでこのスクレーピングも寿命は長いんじゃないかな。と
DropBoxにPDFを送ってほしい
DropBoxにPDFが届くとか、Evernoteに送信されるとかでも良いんだよ。
Windows Liveの書き込み権限をあげるから、ファイルを毎月置いてくれ。それだけいい。それで十分に感動できる。
せめて、毎月のデータくらいは簡単にアクセスできるようにしてほしいなぁ。
Windowsのフォルダを監視する。IronPython の使い方とサンプル
Windowsのフォルダを監視して、更新があったら取り込む。
というよくある処理。これを簡単にしたいなと思った。
Windowsのフォルダ監視は.NetFrameworkが楽ちん
.NetFrameworkが恐ろしくシンプルで簡単です。
from System.IO import * path = "C:\\Users\\takuya\\Desktop" fsw = FileSystemWatcher() fsw.Path = path def watcherhandler(self,*args): print args fsw.Changed += watcherhandler fsw.Created += watcherhandler fsw.Deleted += watcherhandler fsw.Renamed += watcherhandler fsw.EnableRaisingEvents = True while(True):fsw.WaitForChanged(WatcherChangeTypes.All, -1)
本当に、簡単です。
起動は
ipy sample_watcher.py
仕組み
.NetFramewokは、IronPythonから使える。
IronPythonはPython2.7を.netで実装し直したもの。2.7なら全機能が使える。
FileSystemWatcher は .net提供のライブラリ
IronPythonは
IronPhythonはCodePlexからダウンロードして使う。
ironpythonはインストーラーでもバイナリでもどちらでもおなじ。PATH通せば良い。
あとはipyコマンドで、インタラクティブシェルを起動すれば遊べる。
インストーラーなしで.netFrameWorkのスクリプトを書けるから、管理者権限無くてもプログラミング環境が入手できるのでウルトラ便利。
個人用途ならvbs使うよりオススメ。WindowForms作ったりさえも出来る。もちろんexe化も・・・
ironpythonからの.net クラス利用
名前空間と参照をインポートする。インポートは次のpythonコードになる。
import SystemIO.* from SystemIO import *
二つは微妙に違う。
import SystemIO.*の場合は
SystemIO.FileSystemWatcher()
でアクセス可能。
from SystemIO import * の場合
FileSystemWatcher()
でアクセス可能
このへんはPythonのimport と同じで、上手に融合してる。
クラスの初期化
FileSystemWatcher()
()をつけるだけ。newなどはしない。
これだけ知ってれば良い。
イベントハンドラの登録
def watcherhandler(self,*args): print args fsw.Changed += watcherhandler
演算子「+=」がイベントハンドラ登録になっている。
演算子「-=」がイベントハンドラ削除なのは、想像通りで直感的。
FileSystemWactherについて
使い方はシンプルで
- インスタンス化
- 監視パスを指定
- コールバックを登録
- 監視開始
の流れになる。ただし、マルチスレッドで使うので、監視を初めても、メインスレッドをロックしないのです。
代わりに、次のメソッドでイベントキュー待ち
fsw.WaitForChanged(WatcherChangeTypes.All, -1)
ずっと監視するなら、while(1)で無限ループ
while(True):fsw.WaitForChanged(WatcherChangeTypes.All, -1)
ファイルに変化があったらプロセス起動
.NetFrameworkでプロセス起動しても良いんだけど、せっかくpythonなので、
import subprocess subprocess('sh rsync.sh")
とかやるとうれしいかも。良いとこ取り!
詳しくは、MSDN見ろってことだけど、MSDNなんてドラクエ2のラストダンジョンなみに迷路だし、妙なエンカウント多い。記号も多いからなれるまで大変な感がある。
FTPでファイルが届くのを待つだけの仕事で
設定ファイルやら、ジョブネットが時間起動だったりして面倒だったし。
cronやタスクスケジューラーでファイルが届くのを待つ。そんな仕事を山ほどやりました。POLLモデルはどうも好きになれないけど、いちからこう言うスクリプトと書けるほど実力もなかった。悔しかった。でも今ならぱぱっと書けるようになった。正直うれしかった。
参考資料
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=5143&forum=7
http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx
2012/01/14
MacVim(mvim)をHomeBrewでインストールする。
brewでいれたMacvimがなんか動かないと思ってた。
macvimのインストール方法が間違ってて、やり方を見なおしたら動いた。
macvimのhomebrewインストール
macvimにも色々ある。なれないうちはhomebrewで簡単処理。
brew install macvim
MacVim.appが使えないと意味が無い。
アプリケーション・ディレクトリにMacVimを突っ込む。
takuya@air:~$ brew linkapps Linking /usr/local/Cellar/macvim/7.3-63/MacVim.app
これでリンクが作られる。
起動方法
このアプリで開くで選択できるよ
またはコンソールから
ターミナルでは
mvim
と叩けば起動できる。
インストールには
mkdir ~/Applications
が必要かもしれない
RefeコマンドでRubyDocを簡単に使える
ちょっとあれ、どうだったかなとか考えたときにRefeが便利
refeを使うとrubyのドキュメントを簡単に引ける。オフラインでも怖くない。
refeインスト
gem install refe
つかいかた
refe String
のようにクラス名を書く。
インスタンスメソッドについて詳しく知りたいときは
refe String#gsub
のように#gsub で指定する。
クラスメソッドなら
refe Time.now
のようにする。
Refeコマンドが化ける
原因は、文字コードの憶測が適当だってことで。NKFに任せれば良いし、ENV使うべきだし。
/Users/takuya/.rvm/gems/ruby-1.8.7-p352/gems/refe-0.8.0.3/lib/refe/searcher.rb
13 14 module ReFe 15 16 module Encoding 17 18 def adjust_encoding( str ) 19 return NKF.nkf('-w', str) if ENV["LANG”] =~ /UTF-8/ 20 if shift_jis_platform? 21 NKF.nkf('-Es', str) 22 else 23 str 24 end 25 end 26 27 def shift_jis_platform? 28 /mswin|mingw|cygwin|djgpp|vms/ === RUBY_PLATFORM 29 end 30 31 end 32
こんな感じで良いかな。
参考
Crontabの環境変数はどうなっているのか、調べる
Crontabの環境変数のポイントまとめ
- CRONの環境変数はCRON設定の先頭に記述します。
- Bashの環境変数と共有してないので注意。
- ただし、以下の変数はUNIXユーザーに通常存在する環境変数なので、使うことが出来る。
- HOME、SHELL、LOGNAME
- そのほかはCrontablにかく
Bash環境変数と共有するなら、Cronで実行するスクリプトに環境変数を定義するべき。
わかりやすい例。
例があったので見た方が速い。
http://blog.livedoor.jp/sasata299/archives/51279219.html
Crontabの記述例。
Q.ユーザー環境変数は引き継がれるの?
A.されない
Manページによると
・HOME、SHELL、LOGNAMEが設定される、HOMEはcron設定のファイルオーナーの環境変数が使われる。
manより抜粋
crontab の動作行は、環境変数の設定か cronコマンドのいずれかである。環境 変数の設定は以下の形式をとる: name = value た だし、等号 (=) 両側のスペースはなくても良い。 value 内部の (先頭では ない) スペース文字は、値の一部として name に与えられる。 value 文字列は 引 用符で括ってもよい (シングルクォートでもダブルクォートでも良いが、揃 っている必要がある)。こうすれば先頭や末尾の空白を値に渡すことができる。 いくつかの環境変数は cron(8) デーモンによって自動的に設定される。 SHELL は /bin/sh に設定され、 LOGNAME とHOME は /etc/passwd の crontab の所有 者 の行から設定される。 HOME と SHELL は crontab 内部の記述で変更できる 。 LOGNAME は変更できない。 crontab の動作行は、環境変数の設定か cronコマンドのいずれかである。環境 変数の設定は以下の形式をとる: name = value た だし、等号 (=) 両側のスペースはなくても良い。 value 内部の (先頭では ない) スペース文字は、値の一部として name に与えられる。 value 文字列は 引 用符で括ってもよい (シングルクォートでもダブルクォートでも良いが、揃 っている必要がある)。こうすれば先頭や末尾の空白を値に渡すことができる。 いくつかの環境変数は cron(8) デーモンによって自動的に設定される。 SHELL は /bin/sh に設定され、 LOGNAME とHOME は /etc/passwd の crontab の所有 者 の行から設定される。 HOME と SHELL は crontab 内部の記述で変更できる 。 LOGNAME は変更できない。http://www.80code.com/kb-ja/crontab.html
cronの環境変数など
ポイント
PATHとかRVM関連で必要。
HOMEとか重要、これはそのまま使える。
Crontabの曜日
dow(day of week) の 0, 7 は Sun です。
0, 1 , 2 , 3 , 4 , 5 , 6 ,7 日, 月、 火、 水、 木、金、 土、 日
mod 7 = 0 になるのが日曜です。
2012/01/13
su/sudo したときの環境変数が気になったので調べた。
sudo su したときの環境変数と、自分の環境変数がどうなってるのか知りたい。
sudo su -l したときの環境変数と sudo su の環境変数がどうなっているのか知りたい。
rvm で環境作ってると、環境変数を意識しておかないとgem install しても入ってなかったり。そんなことが起きて環境ぐちゃぐちゃになるのでちゃんと意識しておきたいと思った。
環境変数をリセットしてsu / sudo するには次の方法がある。
調べてみた。
とにかく調べてみるのが一番。
su したときと su -l したときの環境変数
左が su -l 、右が単純なsu
su と su -l では環境変数が異なる。うん、そうだよね。
su したときの環境変数 と takuya の環境変数
左がsu の環境変数 。右がtakuyaの環境変数
su だけだとtakuyaの環境変数が持ち込まれているのが分かる。
sudo su したときの環境変数と、自分の環境変数
左がsudo su の環境変数 。右がtakuyaの環境変数。
環境変数はまっさらになってる。
sudo su -l したときの環境変数と sudo su の環境変数
左がsudo su -l の環境変数 。右がsudo suの環境変数
pwdが違うのは、新しいシェルを起動したときにhomeへ移動したかどうかの違い
-l つけると新しいbashが起動するみたい。
比較しした結論。
su では環境変数はそのまま
su -l で環境変数がリセットされる。
sudoしたときは環境変数がリセットされる。(設定次第)
環境変数がリセットされるのは重要
とくに、rvmなどのユーザ固有ローカルパッケージを使っていて、システム環境を触るときに重要。
sudoしたときに環境変数を持ち越すかどうか
sudoしたとき環境変数がリセットされてるのは、次のsudoersファイルの設定の効果
sudoersの設定で環境変数をリセットして初期化して sudo しているのが分かる。
sudoersで環境変数をリセットを標準にする
Defaults env_reset,
を書いておけば基本的に環境変数リセット。
su -l の -l オプション
Macのmanには次のように書いてあった。
-l Simulate a full login. The environment is discarded except for HOME, SHELL, PATH, TERM, and USER. HOME and SHELL are modified as above. USER is set to the target login. PATH is set to ``/bin:/usr/bin''. TERM is imported from your current environment. The invoked shell is the target login's, and su will change directory to the target login's home directory.
su の -l オプションではなく "-" を使う
DebianのManには次のように書いてあった。
su はログインセッション中に別のユーザになるために用いる。 ユーザ名を指定せずに起動した場合、
デフォルトではスーパーユーザの ID に変更する。
オプション引数 - を用いると、 直接ログインした場合と同じ環境に初期化される。
というわけで、「su - 」でもおなじらしい
2012/01/12
JR西日本の運行情報を監視する。
JR西日本の遅延っぷりはナイスだ。JR東日本もナイスだ。両者は良い勝負。正直いってJR西の方がひどい。西は、JR東日本に比べるとシンプル路線。相互乗り入れもない。神戸〜京都でもシンプル。奈良なんてシンプルすぎるくらいだ。なのに遅れ続ける。もはや企業文化に原因があるのだろう。
遅延情報ページもCacheヘッダを送ってくるが、 if-modified-since を送付しても無視っぽい。いつも200okしか帰ってこない。そういう企業文化なんだろう。
というわけでJRを監視。
JR西の運行情報ページに30秒に一度アクセスして、前回と内容が変わっていればメールを送ることにした。
#!/usr/bin/env ruby $KCODE='u' def check_jr_kinki require 'rubygems' require 'mechanize' m = Mechanize.new m.get 'http://trafficinfo.westjr.co.jp/kinki.html' p = m.page title1 = p.search('div#contents_title').text.gsub(/\d+/,"") #=> "17:40 現在 近畿エリアの運行情報です。" title2 = p.search('div.time').text #=> "17:35更新" title3 = p.search('div.unkou').text #=> "【JR神戸線】 人身事故 振替輸送開始" body = p.search('div.eikyou_block').text return [title1,title2,title3,body] end def send_notify(title,body) require 'rubygems' require 'net/smtp' require 'base64' require 'tmail' mail = TMail::Mail.new mail.to = "takuya@localhost" mail.from = "takuya@localhost" mail.subject = title mail.date = Time.now mail.mime_version = "1.0" mail.body = body mail.set_content_type "text", "plain", {"charset" => "iso-2202-jp"} Net::SMTP.start("localhost","25","local",nil,nil,"plain") do |smtp| smtp.sendmail( mail.encoded, mail.from, mail.to) end end require 'rubygems' require 'daemons' Daemons.run_proc('jr_west_checker') do ret2 = [nil,nil,nil,nil] ret = check_jr_kinki loop do send_notify( ret[0..2].join('ー'), ret[3] ) if ( ret.zip(ret2).map{|i,j| i==j }.reject{|i| i==true}.size > 0 ) ret2 = ret if ( ret.zip(ret2).map{|i,j| i==j }.reject{|i| i==true}.size > 0 ) sleep 30 ret = check_jr_kinki end end
しかもDaemonsでサービス常駐させてやった。もう何も怖くない。
mechanize 本当に便利ですね。
2012-02-02追記
ブクマコメントを頂いたので返信。
「もはや企業文化に原因が」福知山線の事故がなければもう少し状況は違ってると思いますよ?/それよりも「30秒に1回運行情報にアクセス」とか病的に近い頻度だと思うのだけど。
そう?キャッシュヘッダだけ見に行っても、毎回 200 OKが返ってくるので、どうしようもないんだけど。一分に一回でもいいんだけど、電車が15−20秒単位で運行されてることを考えると、「電車まだ来ないかーっ」ってストレスから見ればたいしたことないとも思う。
何秒にするかは、相手の更新頻度と間隔を考えて見極めたらいいのであって、WEBページのScrapeのWait時間に正解はないかと思うし、病的と言われるとちょっと。。。。
特に、今日(2012-02-02)のような大雪の日、また台風の日は、JR運行情報は毎分更新がありえます。大量更新がある事故が、いつ起きるわからないので、アクセスしすぎとも言えないんじゃないかと思います。
むしろ、画像やCSSを読み込まないので、ブラウザよりは通信量もコネクションも少ない。ですし
(最後のこれ↑は、言い訳がましいですけど)
2012/01/09
RailsサーバーとApacheの連携まとめ
RailsとApacheの連携をアレコレやってみた。
現在候補は3つ
- Passenger
- Proxy
- fcgi/cgi
比較
比較の条件
- 設定がRailsディレクトリに収まるか。/etc/apache2や/etc/init.dに書くのは面倒だよね。
- インストールが簡単か。コマンド実行だけでいけるか
- 再起動がいるか
- 動作速度は?
手法 | 設定がRailsディレクトリに収まるか。 | インストールが簡単か。 | 再起動が不要か | 動作速度は | raisのエラー表示 |
passenger | x | x | x | ○ | ○ |
proxy | x | x | x | ○ | ○ |
cgi | ○ | ○ | ○ | x | x |
fcgi | x | ○ | x | ○ | x |
mod_proxyは.htaccessに設定書けない。しかも設定するたびにapaache reloadが必要。ってことで不便すぎたわ
cgiは遅い。でも設定がappディレクトリをそのままをアーカイブ出来るので良いし、ドコでも動くし。素敵だわ。
fcgiは速いけど、reloadしまくりって感じだった。
passenger はインストール面倒だし。
Apacheと連携ならpassengerは悪くない選択肢。でも可搬性がなぁ。でも、nginxをApacheの代わりに使うと、貴重なグローバルIPの80番を浪費するし、もどかしぃぃ。
一度動いちゃうと楽だから、passengerは悪くない。でも内部的にproxyしてるってのがイヤですね。cgiはエラーがInternalServerErrorにマッピングされるので・・・あぁもうどれも微妙・・・passengerは悪くない選択肢。でもインストールが。設定が
500 internal server error
CGI/FCGIだとRailsエラーがCGIの500エラーになる。なので、Railsエラーが見られない。開発中はちょっと困る。でも本番運用ならむしろ歓(?)
そもそもRailのサーバーは
2.3系からRack経由になってる。
Rackって?
Rackがあればどうなるの
Rackが抽象化レイヤを提供してくれるので、CGI/Fcgiでも何でも来い。
サポートされてるのは次の物。
- Mongrel
- EventedMongrel
- SwiftipliedMongrel -
- WEBrick
- FCGI
- CGI
- SCGI
- LiteSpeed
- Thin
http://rack.rubyforge.org/doc/
つまり、RaisはRackが抽象化レイヤの恩恵を受けるので、MongrelでもThinでもなんでもいいし、CGIでも良いんですね。
納得でした
apacheでやることが主眼だから、mongorel使えとか、thinの方が速いとかそういう話題には触れてないです。
Railsをmod_proxy でApacheと動かす。
railsとApacheの連携でよく紹介されてたのがmod_proxyを使う方法proxyだからApacheと連携してるとは言いがたいんだけど。まぁApacheとURLを共有できるからある意味連携かな。
railsサーバーを起動してApacheが受付になってRailsにリクエストする方式。
- railsの起動
- apacheの起動
- proxy/httpの設定
が必要になる。
mod_proxyは apache2.2ではいくつかのサブモジュールに分割されてる。
proxy 経由でHTTPへ転送するには proxy httpが必要
mod_proxy はproxyを使うよってことで
mod_proxy_http は proxy 先へのプロトコルに httpを使うよ
mod_proxy_ajp は proxy 先のプロトコルに ajpを使うよってことで。
インストール
debianの場合は、apacheモジュールのインストールはとても楽
a2enmod proxy a2enmod proxy_http service apache2 reload
Apacheの設定を理解するにはDebianを使うことを勧めす。httpd.confをちまちま読むCentOSスタイルだとドコの設定がどうなってるかが見通し悪くて学習には向かない。Debianスタイルは管理も楽だし、学習にも向いてる。オススメ
railsの起動
localhost に起動する。
rails server -b localhost
proxyの設定
ProxyPass /book http://localhost:3000/ ProxyPassReverse /book http://localhost:3000/
このように書くと
192.168.1.210/bookへのアクセスは mod_proxy_http経由で http://localhost:3000へ転送される。
railsの自動起動設定
しかしこの場合欠点がある。railsの自動起動が出来ない。めんどくさーい
rubyのdaemonsを使えば良い
daemonsを使ってinitスクリプトとして動くようにして、自動起動に登録すれば良い。
my_app_init.rb
#!/usr/bin/env ruby require "rubygems" require "daemons" Dir.chdir "path/to/my/app” Daemons.run(“rails server -b 192.168.2.1")
これで作って。
cp my_app_init.rb /etc/init.d/ rccnonf
とでもやって、起動時に実行されるように登録すれば良い。centosならchkconfig かな
proxyって色々考えること多いからいっこで終わりませんね。
Apacheの設定のプロになってきた気がする。
RailsをPassengerモードで動かす。
RailsをApache+Passengerで動かす。
Passengerって?
RailsもつかってるRackをApacheに組み込んじゃう感じ。
mod_rackを使えるように、mod_proxyと組み合わせて内部的にrailsプロキシしちゃう。そんな感じ
aptインストール
apt-get で入ったよ。でも動かなかった。。理由は。gem依存モジュールがaptパッケージの想定違うことによるみたい。
手動で環境作る手順
- gem パッケージでインストール
- apacheのapxでモジュールとしてコンパイル
- apacheにdynamic share object (so)として組み込み
- rails環境作る
- Passengerでrails起動
この手順がpassenger-install-apache2-module コマンドだけに集約される。えらい。
手動インストール
gemから。
gem update --system gem install passenger passenger-install-apache2-module
aptで入れたパッケージは動かなかったので。
rvm環境とかあるときは注意してね
画面の指示に従う。
画面の指示が詳細でわかりやすい。こういう気配りいいよね
指示画面のキャプチャがつぶれて見えないので。
The Apache 2 module was successfully installed. Please edit your Apache configuration file, and add these lines: LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.11/ext/apache2/mod_passenger.so PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.11 PassengerRuby /usr/bin/ruby1.8
実際の設定
実際に設定した。
ドキュメントルートでPassengerを動かす場合
/etc/apache2/sites-enabled/air.example.jp
<VirtualHost *:80> DocumentRoot /var/www/air.example.jp/rails/book/public ServerName air.example.jp RailsEnv development <Directory /var/www/air.example.jp/rails/book/public> AllowOverride all Options -MultiViews </Directory> </VirtualHost>
/etc/apache2/mods-enabled/passenger.load
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-3.0.11/ext/apache2/mod_passenger.so
/etc/apache2/mods-enabled/passenger.conf
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-3.0.11 PassengerRuby /usr/bin/ruby1.8
ドキュメントルート以外を使う場合
ドキュメント以外のディレクトリにRailsを入れて、ディレクトリを別にする場合
<VirtualHost *:80> DocumentRoot /var/www/air.example.jp ServerName air.example.jp RailsEnv development RailsBaseURI /rails/book/public <Directory /var/www/air.example.jp/rails/book/public> AllowOverride all Options -MultiViews </Directory> </VirtualHost>
簡単ですね。
ここまで簡単なら、自分専用に作っておいても問題ないかなーって思う。
PushionPassenger
のPhusionっての名前がすきになれない.PHPの守護神(スホンシン)パッチを思い出して・・・
この自己主張しすぎなハングルが嫌いなんだけど、これを思い出していや。関係ないのに。
passenger を見送った理由
でも、まだまだめんどくさい。コンパイルとか設定管理とか。
ユーザー管理周りがちょっと面倒
本家ドキュメントに以下の通り、ユーザー環境について書いてある。
8.1. User switching (security)
There is a problem that plagues most PHP web hosts, namely the fact that all PHP applications are run in the same user context as the web server. So for example, Joe’s PHP application will be able to read Jane’s PHP application’s passwords. This is obviously undesirable on many servers.
Phusion Passenger solves this problem by implementing user switching. A Rails application is started as the owner of the file config/environment.rb, and a Rack application is started as the owner of the file config.ru. So if /home/webapps/foo/config/environment.rb is owned by joe, then Phusion Passenger will launch the corresponding Rails application as joe as well.
This behavior is the default, and you don’t need to configure anything. But there are things that you should keep in mind:
The owner of environment.rb/config.ru must have read access to the application’s root directory, and read/write access to the application’s logs directory.
This feature is only available if Apache is started by root. This is the case on most Apache installations.
Under no circumstances will applications be run as root. If environment.rb/config.ru is owned as root or by an unknown user, then the Rails/Rack application will run as the user specified by PassengerDefaultUser and PassengerDefaultGroup.
User switching can be disabled with the PassengerUserSwitching option.
http://www.modrails.com/documentation/Users%20guide%20Apache.html#conflicting_apache_modules
日本語でOK
mod_phpにもプロセスはApacheがオーナーになるので、ファイルのパーミッションが甘い。Joeの740のファイルはJameのPHPから読めてしまう。apacheがプロセスだからだ
passengerはこのような問題を解決するために、PassengerDefaultUserをhttpdオプションに使います。云々
phpではこのような問題を解決するためにsuphpやらexeccgiを使うんですがね。。。実際使ってるホスティングは結構ある。
ってわけで、passengerでホスティングができるかもってタイトルは釣りっぽい、最初この人に思い切り釣られた悔しい。→ホスティングサービスでもRailsが利用できるようになるかも、な「Passenger」
passengerの動作原理
Phusion Passenger could create a new Ruby process, which will then load the Rails application along with the entire Rails framework. This process will then enter an request handling main loop.
Phusion Passenger calls fork(), but not exec().
Phusion Passenger will first create a so-called ApplicationSpawner server process. This process loads the entire Rails application along with the Rails framework, by loading environment.rb. Then, whenever Phusion Passenger needs a new worker process
http://www.modrails.com/documentation/Users%20guide%20Apache.html#spawning_methods_explained
適当にそれっぽい所を抜き出した。間違ってたらゴメン。
passengerはrailsをロードしてそれを、forkしてWokerを作る。Workerを作ってHTTPリクエストをハンドリングする。
つまり、ApacheのPre-forkっぽいことをPassenger内部でさらにやってる様子。ってことでApacheが起動したらPassengerのプロセスツリーもまとめて起動されるってことらしい。
プロセスツリーを見ればもう少しわかりやすい
passengerは確かに便利。一度インストールすると、無意識的に使える。だけど、Apacheを使ったシビアな設定には耐えられないかも・・・というちょっとした地雷予感がしたのでこの技術は枯れるまでスルーするかも
せめてAptGetで一発で入ってすぐ使えたらなぁ。。。apt-get のパッケージ動かなかったんで。。。
2012/01/08
railsをCGIモードで動かす。
Rack経由でfcgiで動くのなら、cgiでも動くんじゃね?
ruby on railsをCGIで動かす方が、開発時は便利そうだ。CGIで動かしてみる。
あっさり動く
これあっさり動くねぇ。
背景
fcgiだとキャッシュされすぎるので、開発には向いてないと判断。
そもそも、railsのアプリを動かすのに、ポート指定したり、自動起動設定したり、プロキシ入れたり面倒なんだよ。phpみたいにファイル置くだけで動いてほしい。
passengerとかは、一度動くと便利。だけど、インストール面倒だった。cgi最高
実験環境
- debian squeeze
- apache2.x
- ruby1.8.7
- rails3.1
で実験中
apache でcgiを有効にする。
railsが動かしたいディレクトリでcgiが動くように設定。たとえば以下の通り。
<Directory path/to/my/app> AllowOverride all Options ExecCGI FollowSymLinks </Directory>
.htaccessを設定する
RewriteEngine ON RewriteBase /path/to/my/app/public/ RewriteRule ^.+$ dispatch.cgi [QSA,L] AddHandler cgi-script .cgi
fcgiとほとんど同じです。
dispatch.cgiを作る
ファイル名は名前は何でも良いん。.htaccessに指定した名前であれば良い。
#!/usr/bin/ruby require 'rubygems' require 'cgi' require '../config/environment' class Rack::PathInfoRewriter def initialize(app) @app = app end def call(env) env.delete('SCRIPT_NAME') parts = env['REQUEST_URI'].split('?') env['PATH_INFO'] = parts[0] #env['PATH_INFO'] = env["PATH_INFO"].sub(%r"^/book", "") env['QUERY_STRING'] = parts[1].to_s @app.call(env) end end Rack::Handler::CGI.run Rack::PathInfoRewriter.new(Book::Application)
これもfcgiとほとんど同じ。
これだけ。
cgiが動くだけでいい。なんだコレ便利。
railsディレクトリだけを入れてるだけで良いですね。.htaccessをpublicに入れてればそれでいいですね。
一応環境確認のための virtualhost 設定
virtualhost 設定はこんな感じ。
<VirtualHost *:80> DocumentRoot /var/www/air.example.jp ServerName air.example.jp RailsEnv development RailsBaseURI /rails/book/public Alias /book/ /var/www/air.example.jp/rails/book/public/ <Directory /var/www/air.example.jp/rails/book/public> AllowOverride all Options ExecCGI FollowSymLinks Options -MultiViews </Directory> </VirtualHost>
一部passengerの設定が混じってるけど気にしない。
Rackが対応してればRailsのベースは何でもいいみたい
rackで抽象化されているので、Railsはなんでもいいや。動作速度も大事だけど。。。。
railsの魅力は、開発速度だよね?
ITシステムにおいて一番大事なのはコスト。コストの中では一番高い物は何か。プログラムの実行時間でも、待ち時間でも、ない。
実行速度よりも大事なものがある。簡単なデプロイ?、いいや開発時の人件費。人的コストだよね。だから、簡単にコピーして移動できる方が良い。railsは開発サーバー内蔵なのでその点が楽。であれば、コピーして簡単に動かせる方が良い。PHPとかほかのシステムもカラムなら、proxyよりCGIが手軽に管理できて良いと思ったり。
rails をapache+fcgiで動かす。
Railsのために、ポート開けたり、リバースプロキシするのが面倒だし。PHPと同じようにファイル展開するだけで動いたら良いのに。
やってみたら動く。
調べたら動くことが分かった。
下準備
sudo aptitude install libapache2-mod-fcgid sudo aptitude install libfcgi-dev sudo gem install fcgi
apacheにfcgiを入れてないときは、fcgiを入れる。rails持ってないときはrailsも入れてね。
実験環境
rails3.1
ruby 1.8.7
apache2
debian squeeze
そうですね。ポイントはrails3.1です。
設定の流れ
- fastcgiが動くように
- railsが起動してるappディレクトリを準備
- public ディレクトリに.htaccessを設定
- .htaccess でmod_rewrite + fcgi起動を設定。
railsディレクトリの準備
rails new bookapp rails generate home index rails server -b 127.0.0.1
くらいですかね。ここまでやって起動確認はやっておくと後で切り分けが楽。
.htaccessを準備する。
public/.htaccess に用意します。
AddHandler fastcgi-script .fcgi RewriteEngine ON RewriteBase /book/ RewriteRule ^.+$ dispatch.cgi [QSA,L]
上で指定したdispatch.cgi
実際にRailsを起動する dispatch.fcgiをrubyで
fcgiでrailsを起動するためのdispatch.rb
#!/usr/bin/ruby require 'rubygems'#ruby 1.8 require 'fcgi'# ruby1.8 require '../config/environment’ #ruby1.8 class Rack::PathInfoRewriter def initialize(app) @app = app end def call(env) env.delete('SCRIPT_NAME') parts = env['REQUEST_URI'].split('?') env['PATH_INFO'] = parts[0] #必要に応じてPATH_INFOを書き換える #env['PATH_INFO'] = env["PATH_INFO"].sub(%r^/path/to/my/rails/public", "") env['QUERY_STRING'] = parts[1].to_s @app.call(env) end end Rack::Handler::FastCGI.run Rack::PathInfoRewriter.new(YOURAPPNAME::Application)
PATH_INFOは、Railsを展開したいディレクトリに応じて適当に切り詰めてください。
apacheの再起動。
fcgiが設定済みなら特に再起動不要。展開に失敗したときは必ずreloadする。
fastCGIの注意点
ruby設定ミスったりrailsにエラーがあると、再起動が必要です。
fastCGIはなぜFAST(速)なのか。
それはキャッシュするからだ。mod_fcgi + ruby の場合、rubyのスクリプトファイルを読み込んでキャッシュしてる。
ファイルキャッシュは、OSレイヤでやってる。fcgiはさらにバイナリキャッシュをする。バイナリはrubyスクリプトが実行可能形バイナリに変換されたもの
つまり、単純にfcgiを使ってると、 apache reload を頻繁にやらないと、バイナリが更新されない。
逆に、バイナリキャッシュをやめると、ファイルの更新が速反映されるが、Rubyの実行バイナリへの変換が遅いので、fcgiの恩恵にあずかれない。
ってことで、、、、
fcgiは enviroment => product 専用。
dev環境で使うには、、、開発中は頻繁にファイル更新がル。ファイル更新するとバイナリキャッシュがあるので色々めんどくさい。
バイナリキャッシュの恩恵に預かれない。なのでfcgiを使うことすら無駄。ちょっと考えれば分かることだった。お疲れ様オレ。
参考資料
>Linuxなら素直にPassengerを使いましょう。もしくはmongrel(+mod_proxy(_balancer))で。
http://okwave.jp/qa/q5201582.html
どの辺が素直なんだか。。。これは嘘なのです。相変わらず、ドヤ顔のOKWAVEはむかつく。
Rails 3 is built on top of Rack and Rack provides a FastCGI handler.
http://rack.rubyforge.org/doc/
http://rack.rubyforge.org/doc/Rack/Handler/FastCGI.html
http://stackoverflow.com/questions/3296206/rails-3-and-fcgi
コレが正しい回答です。
railsは3.1の今でもfcgiで動きます。
そもそも、CGIやFastCGI駆動は今は推奨されていないみたいです。
(というか、RailsでFastCGIを使うというのはどこで入手された情報でしょう?)
http://okwave.jp/qa/q5201582.html
上のちょっとドヤ顔の回答がむかついたのです。だからfcgiで動かした。
「非推奨はドコに書いてあった?」本家にはドキュメントが見当たらない。
OKWaveは第三者がみて間違ってるよと、添削したくても指摘する機能が無いので、どうしても記事が洗練されない。そのくせ、疑問点に対する回答して書かれてて、もっともらしく見えるので問題。
ちゃんとした参考資料
2012/01/06
html5のW3C FileAPIについて、調べてまとめた。
html5のファイルAPIについて調べた。http://www.w3.org/TR/FileAPI/ を読みながら、メモ。やっぱり本家ドキュメントは頼りになるのね。
FileAPIはなにか
- ローカルファイルにアクセスできる。
- アクセスできるファイルはinput で指定された物だけ。
使い方
input に files タイプを指定するとFileAPIの対象になる。
<input type=files >
filesタイプの読み込み方
file = document.forms[0].elements[0].files[0]
このように、<input type=files/>へJS経由でアクセスできる。
input type=filesの項目は、複数ファイルの配列になっている。FileListオブジェクト呼ぶ
FileList オブジェクト
通常の配列みたいなオブジェクトして定義されている。つまり配列だと思っておけば良い。
files = document.forms[0].elements[0].files file.length files[0] files.item(0)
File。FileListの中に入ってるオブジェクト
input type=filesでユーザーが指定したファイルのオブジェクトが入っている。
File/FileListは、Iteratorパターンの関係にあるの
Fileオブジェクトでとれる物。
- ファイル名
- サイズ
- 最終更新日
files = document.forms[0].elements[0].files file = files[0] file.name // => "test.xls" files.lastmodifideDate // => "" files.size // => 1234567
ただし、内容読み込みは出来ない。
なぜか?
input type=fileで、ブラウザがファイルを読み込んでたら遅いジャン
だったらどうするの?
ローカルファイルすら非同期で読み込みます。
つまり?
ローカルは http:// https://のような file:// のScheme空間だと認知しておけば良い。
非同期で読み込むって?
XHRみたいに読み込めば良いんだよ。
new XmlHttp()のかわりに、new FileReader()する
何度も言うけど、非同期だからね!!
reader = new FileReader() file = document.forms[0].elements[0].files[0] reader.readAsText(file, 'UTF-8')#このあとはEvent処理に任せるよ!
非同期なんだから、Event処理を書いとかないとしょうが無い。
reader = new FileReader() reader.onload = function(evt){} //読み込み完了したら呼ばれる。 reader.onprogress = function(evt){} //ファイル読み込み中に呼ばれる。 reader.onerror = function(ev){} //エラー時に呼ばれる。
イベントにはどんな種類があるの?
Filereaderが持ってるイベントはこんなのがある
ハンドラ名 | イベント |
---|---|
onloadstart | loadstart |
onprogress | progress |
onabort | abort |
onerror | error |
onload | load |
onloadend | loadend |
イベントは以上です。
ぐだぐだ言わずに、ファイル読めりゃ良いんだよ
僕らはファイルを読み込みたいだけなんだ。
reader = new FileReader() file = document.forms[0].elements[0].files[0] reader.readAsText(file, 'UTF-8')#このあとはEvent処理に任せるよ! ///しばらく待つ。 reader.readyState //これが2になれば読み込みおわり while(reader.readyState!=2){ } //ファイルの中身を見る reader.result
readyStateとか見覚えあるよね
そうXHRみたいなもんなんだよ。
つまり
比較してみよう
データ | オブジェクト | |
Ajax | URL:アドレス | Xmlhttp |
FileAPI | Fileオブジェクト | FileReader |
対で覚えるとイメージしやすいみたい。
何で非同期になってるのよ。
ファイル読み込み程度で、ほかのJSの動作をストップさせるともったいない。だからマルチスレッドで動くようにファイル読み込みを別スレッドにしてる。HTMLを読み込んでDOMを構築するときにIMGやCSSを非同期に読み込むでしょ?あれと同じことをローカルファイルでもやってる。
ってことみたい
シンプルに、覚えよう。
次の原理として覚えることにした。
ローカルファイルはfile://スキーマ。http://スキーマと同じ扱いを受ける
絶対に同期できないの?
もちろん出来る。
XMLHTTPに同期通信が用意されているように、ファイルにも同期が用意されている。それが FileReaderSync
全部非同期で良いジャン?
いや、WebWorkersでプログラマがスレッド作れるから、スレッド同期処理はあった方が良い。
部分的にファイル読込できないの?
HTTPはファイルの部分取得が出来る、FileAPIは出来ないの?
もちろん出来る。File#sliceがそれ。
まとめ
HTTPとおなじ扱いのFILEとして定義されている。
同期・非同期、部分読み込みがあるのです。やっぱHTTPと同じだよね。Fileだからといっても、思想は何も変わらない。オブジェクトが変わるだけ。
ところで、読み込んだファイルをどう使うの?
画像をインラインに埋め込む記述を覚えていますか?
<img src="data:123456yjgbvd”/>
ファイルAPIで読み込んだファイル内容は、
<img src=“blob:123456yjgbvd”/>
と書き込み、使うことが出来る。
data: だと base64エンコードが必要だからめんどくさいけど、blogならバイナリそのままで楽ちん。
これをblob: プロトコルと呼びます。
講釈は良いから、使い方を
説明多くてすいません。こうやります。
var file = document.getElementById('file').files[0]; if(file){ blobURLref = window.URL.createObjectURL(file); myimg.src = blobURLref; }
1:window.URL.createObjectURL() にファイルを渡すと blob:xxxxxのURLが帰ってきます。
2:blob:のURLをimg.srcに埋め込めば終わり。
簡単ですね。
参考資料
W3Cだけでかなりおなかいっぱいになれる。