いくつか調べ物をしていてiOS 6 のSafariでファイル画像アップロードができることをやっと知りました。これで responsive なサイトを作る敷居は一つ下がった様に感じます。
これまでiOSで画像アップロードができないためだけにモバイルアプリを制作していた会社も少なくないのではないかと思うと、仕様変更がちょっとあるだけでいままでの努力がなんだったんだと泣き寝入りをせざるを得ないのはちょっと儚さを感じます…。
Thursday, 20 December 2012
Wednesday, 19 December 2012
私は16歳で高校を卒業してプログラムをしています。就職過程に一石
これは私本人の話ではないのですが、最近こんな人の記事を読みました。
http://jarredsumner.com/
私は16歳で高校を卒業してプログラムをしています。
履歴書を会社に送るよりも会社の人たちが来ていそうなミートアップイベントに参加して人と直接話しをしたよっていう話を書いています。
こんな投稿でも、100社に履歴書を送って面接で断られまくってという無意味な精神修行過程をもっと有意義な過程に昇華する一石になればと思います。
以下本人のサイトから抜粋です。
http://jarredsumner.com/
私は16歳で高校を卒業してプログラムをしています。
履歴書を会社に送るよりも会社の人たちが来ていそうなミートアップイベントに参加して人と直接話しをしたよっていう話を書いています。
こんな投稿でも、100社に履歴書を送って面接で断られまくってという無意味な精神修行過程をもっと有意義な過程に昇華する一石になればと思います。
以下本人のサイトから抜粋です。
If you’re an engineer, go to meetups hosted or attended by employees of the company you want to work for. In the Bay Area, there’s SFRuby, AirBnB Tech Talks, GitHub Drinkups, and numerous more. Usually, several technical recruiters attend who really want to hire engineers. Talk to them as a human being, and they’ll treat you like one.
Tuesday, 18 December 2012
Riak link syntax
key-valueストアのRiakではREST APIを標準で提供していますが、そのリンクを辿るには次のようにcurlなどでクエリを出します。
http://localhost:8091/riak/bucket/key/bucket,key,keep
例えばスパゲッティーペペロンチーノのレシピを書いてその写真をアップロードしたとすると、
http://localhost:8091/riak/recipes/spaghetti-peperoncino/photos,_,0
でリンクした写真のリストを見れます。最後のkeepのフラッグは写真の情報だけを見たいときは0にして、写真にたどり着くまでの過程にあったオブジェクトのデータも取得したいときは1にします。
http://localhost:8091/riak/bucket/key/bucket,key,keep
例えばスパゲッティーペペロンチーノのレシピを書いてその写真をアップロードしたとすると、
http://localhost:8091/riak/recipes/spaghetti-peperoncino/photos,_,0
でリンクした写真のリストを見れます。最後のkeepのフラッグは写真の情報だけを見たいときは0にして、写真にたどり着くまでの過程にあったオブジェクトのデータも取得したいときは1にします。
Monday, 17 December 2012
Ruby CI tools
最近一度プルリクエストをしたGitHubのコードに問題がある事が分かりました。多分自分が書いたコードではなくて依存しているgemが使っているAPIの仕様が変わったのではないかと思います。テストを書く事を提案してみようかどうか、どこまでプロジェクトにコミットするのかなど判断にまだ迷っています。
そんな視点を持ちつつなんとはなしにSlimのGithubレポジトリを眺めていると、Travis CI以外にも二つコードの状態を示していそうなバッジがついていました。少し調べてみると、一つは異存しているgemの状態をチェックするGemnasiumというツールでした。もう一つはCode ClimateというクラスファイルごとにCode Smellなどの観点からコードの健全性を見せてくれるツールでした。
目先、GemnasiumとTravis CIがとても使えそうですが、そもそもどこまでコミットできるかという判断が解決していないですね…。
そんな視点を持ちつつなんとはなしにSlimのGithubレポジトリを眺めていると、Travis CI以外にも二つコードの状態を示していそうなバッジがついていました。少し調べてみると、一つは異存しているgemの状態をチェックするGemnasiumというツールでした。もう一つはCode ClimateというクラスファイルごとにCode Smellなどの観点からコードの健全性を見せてくれるツールでした。
目先、GemnasiumとTravis CIがとても使えそうですが、そもそもどこまでコミットできるかという判断が解決していないですね…。
Saturday, 15 December 2012
Mongoidを使ってRSpecでテストした時にFactoryGirlでバリデーションエラーが無くならない
Mongoidを使ってアプリケーションを作っていて、RSpecでテストした時にFactoryGirlでバリデーションエラーが無くならないという事がありました。
一時的にtestの環境ではヴァリデーションをスキップするという方法でしのいでいたのですが、実はspec_helperにDBのコレクションをbefore(:each)のタイミングでドロップするという設定が必要だという事でした。これを実行してみると、問題無くバリデーションエラーがとれました。mongoid-rspecのドキュメンテーションにもこんな事は書いていなかったと思うし、ドキュメントの読み方が悪いのでしょうか…。
http://adventuresincoding.com/2012/05/how-to-configure-cucumber-and-rspec-to-work-with-mongoid-30
database_clearnerのgemを導入したタイミングのどこかで自動でテストの時にデータベースのコレクションを削除してくれるスクリプトも導入されるのかと思ったらそんなことは無い様ですね…。
一時的にtestの環境ではヴァリデーションをスキップするという方法でしのいでいたのですが、実はspec_helperにDBのコレクションをbefore(:each)のタイミングでドロップするという設定が必要だという事でした。これを実行してみると、問題無くバリデーションエラーがとれました。mongoid-rspecのドキュメンテーションにもこんな事は書いていなかったと思うし、ドキュメントの読み方が悪いのでしょうか…。
http://adventuresincoding.com/2012/05/how-to-configure-cucumber-and-rspec-to-work-with-mongoid-30
database_clearnerのgemを導入したタイミングのどこかで自動でテストの時にデータベースのコレクションを削除してくれるスクリプトも導入されるのかと思ったらそんなことは無い様ですね…。
プログラミング関連書籍譲ります
読み終わった書籍を交換するBookMoochというサービスを暫く利用しているのですが、数冊プログラミングに関わる書籍を加えておきました。興味のある方は"BookMooch request"をもらえれば送ります。
http://bookmooch.com/m/inventory/taro
Friday, 14 December 2012
Ruby on Rails AntiPatterns (3) このシリーズはこれで終わりです
Saleh, T.とPytel, C.著の"Rails AntiPattern"から幾つか私が参考になった箇所を少しずつ書いていきます。
validates_uniqueness_of :product_number, allow_nil: true
としていたのですが、モデルのインスタンスを新規保存・更新するとエラーも出ないのに、何故かDBのデータが更新されません???。暫く迷っているうちにふとindexの時に
index( {model_number: 1}, {unique: true} )
と書いた事に思い当たりました。DBがロールバックした事実をmongoidの方でユーザに報せる機構が内容です。ActiveRecordでもDBのレベルでの一意性のチェックなどはしないのが良いプラクティスだそうです。SQLデータベースでもこの辺りの実装は異なるらしいので互換性の実装が難しいのでしょうね。それとももっと他の所に問題があるのでしょうか。もっとDBの実装を理解しないと問題の本質が分からないです(残念ですが)。MongoDBでも例えばクラウドサービスのMongoHQなどでは若干仕様を変えている可能性はありますね…。
クラウドのファイルストレージサービスが推奨されています。現時点で代表的なサービスはS3ですね。
これはモデルにコードを記述して、
class Post < ActiveRecord::Base
def send_summary_report_to_admin
### Here comes actual codes...
end
end
rake taskには
namespace :send_summary_report_to_admin
task search: :environment do
Post.send_summary_report_to_admin
end
end
と記述すると、他のモデルと同じようにrake spec:models でテストできます。
ちなみにAntiPatternではないですが、他の人が書いたライブラリを利用する際は下の事を参照にすると良いとの事です。
T: Test テストでカバーされているか?
A: Activity ユーザに使われているか?
M: Maturity 実際にある程度の期間動いているか?
テストでカバーされていないライブラリにはテストを書くという貢献の仕方もOSSの世界なのであり得るそうですが、人が作ったコードにテストを書くという行為はちょっと勇気が要りますね。メンテナンスの責任も勿論大きくなりますし…。実際ある文献によるとプログラミングの50%はメンテナンスに割かれているそうです。
テストはできるだけ自分で書いた全ての行をカバーするべきである、それができない時は最低限ブロックのレベルでテストを書くべきだという基準を耳にします。責任のあるコードを書くのは大変ですね。例としてmongoidのコードを見てみると、実際のコードとテストコードの割合は約2:1。大体これぐらいが良いプラクティスの目安なのでしょうか…?
ちなみにちなみにネットワークのレスポンスはFakeWebというgemで、ファイル読み書きはFileUtils::NoWriteでモック・スタッブできるそうなので、ここにもテストを書かない口実は無さそうです…。
{
"error": {
"message": できません
}
}
などとなっているのはAPIのコンシューマとしては不便です。レスポンスコードはW3のサイトに記載されています。ざくっと見たらコードの数はそんなに多くないので、対応するのは難しくなさそうです。
HTTPステータスコードはコントローラで下のように返します。
respond_to |format|
format.json {
render json: @post.errors, status: :unprocessable_entity
}
end
RailsでのHTTPレスポンスコードとシンボルのマッピングは下のサイトにあります。
http://www.codyfauser.com/2008/7/4/rails-http-status-code-to-symbol-mapping
def index
@posts = Post.all
respond_to do |format|
format.html
format.xml { render xml: @posts}
end
end
を
def index
@posts = Post.all
respond_with(@posts)
end
と書けるそうです。
何故scaffoldでもこちらの方法でコードを生成しないのかは少し不思議です。確かにこのメソッドを使うとコントローラのコードを見ただけではxmlでサービスを提供しているのか、jsonのレスポンスも生成されるのか分からないですね。これは必要に応じて使い分けでしょうか。ウェブアプリケーションの中で統一してしまって、全てのレスポンスはxmlとjsonで返すというような指針を決めてしまえばresponderを使った方が無駄が無いかもしれないですね。
AntiPattern: 何故かデータベースに保存されていない…
これは最近暫く悩んだ問題です。MongoDBをMongoidを使っていたのですが、モデルのバリデーションのところでvalidates_uniqueness_of :product_number, allow_nil: true
としていたのですが、モデルのインスタンスを新規保存・更新するとエラーも出ないのに、何故かDBのデータが更新されません???。暫く迷っているうちにふとindexの時に
index( {model_number: 1}, {unique: true} )
と書いた事に思い当たりました。DBがロールバックした事実をmongoidの方でユーザに報せる機構が内容です。ActiveRecordでもDBのレベルでの一意性のチェックなどはしないのが良いプラクティスだそうです。SQLデータベースでもこの辺りの実装は異なるらしいので互換性の実装が難しいのでしょうね。それとももっと他の所に問題があるのでしょうか。もっとDBの実装を理解しないと問題の本質が分からないです(残念ですが)。MongoDBでも例えばクラウドサービスのMongoHQなどでは若干仕様を変えている可能性はありますね…。
AntiPattern: アセットをアプリケーションサーバのファイルシステムに保存する
例えばユーザがアップロードした画像や音楽などのファイルをアプリケーションサーバのファイルシステムに保存すると、サーバ移行やデプロイの際に無駄に作業が増えてしまうことが多い様です。クラウドのファイルストレージサービスが推奨されています。現時点で代表的なサービスはS3ですね。
AntiPattern: テストされていないrake tasks
rakeのタスクはプロジェクトルートでrake spec raketasksなどとしてテストを走らせる事ができないため、テストでカバーされない事が多い様です。これはモデルにコードを記述して、
class Post < ActiveRecord::Base
def send_summary_report_to_admin
### Here comes actual codes...
end
end
rake taskには
namespace :send_summary_report_to_admin
task search: :environment do
Post.send_summary_report_to_admin
end
end
と記述すると、他のモデルと同じようにrake spec:models でテストできます。
ちなみにAntiPatternではないですが、他の人が書いたライブラリを利用する際は下の事を参照にすると良いとの事です。
T: Test テストでカバーされているか?
A: Activity ユーザに使われているか?
M: Maturity 実際にある程度の期間動いているか?
テストでカバーされていないライブラリにはテストを書くという貢献の仕方もOSSの世界なのであり得るそうですが、人が作ったコードにテストを書くという行為はちょっと勇気が要りますね。メンテナンスの責任も勿論大きくなりますし…。実際ある文献によるとプログラミングの50%はメンテナンスに割かれているそうです。
テストはできるだけ自分で書いた全ての行をカバーするべきである、それができない時は最低限ブロックのレベルでテストを書くべきだという基準を耳にします。責任のあるコードを書くのは大変ですね。例としてmongoidのコードを見てみると、実際のコードとテストコードの割合は約2:1。大体これぐらいが良いプラクティスの目安なのでしょうか…?
ちなみにちなみにネットワークのレスポンスはFakeWebというgemで、ファイル読み書きはFileUtils::NoWriteでモック・スタッブできるそうなので、ここにもテストを書かない口実は無さそうです…。
AntiPattern: レスポンスが200OKなのにbodyはエラーですと言っている…
これはHTTP APIを提供しない限り許されるのかもしれませんが、レスポンスコート200を返しながら.jsonのレスポンスは{
"error": {
"message": できません
}
}
などとなっているのはAPIのコンシューマとしては不便です。レスポンスコードはW3のサイトに記載されています。ざくっと見たらコードの数はそんなに多くないので、対応するのは難しくなさそうです。
HTTPステータスコードはコントローラで下のように返します。
respond_to |format|
format.json {
render json: @post.errors, status: :unprocessable_entity
}
end
RailsでのHTTPレスポンスコードとシンボルのマッピングは下のサイトにあります。
http://www.codyfauser.com/2008/7/4/rails-http-status-code-to-symbol-mapping
AntiPattern: respond_to do |format| x 3 x methods.count
コントローラのメソッド毎にそれぞれhtmlとxmlとjsonでのレスポンスの挙動が書かれていています。Rails3で導入されたresponderを使えば例えばindexはdef index
@posts = Post.all
respond_to do |format|
format.html
format.xml { render xml: @posts}
end
end
を
def index
@posts = Post.all
respond_with(@posts)
end
と書けるそうです。
何故scaffoldでもこちらの方法でコードを生成しないのかは少し不思議です。確かにこのメソッドを使うとコントローラのコードを見ただけではxmlでサービスを提供しているのか、jsonのレスポンスも生成されるのか分からないですね。これは必要に応じて使い分けでしょうか。ウェブアプリケーションの中で統一してしまって、全てのレスポンスはxmlとjsonで返すというような指針を決めてしまえばresponderを使った方が無駄が無いかもしれないですね。
Thursday, 13 December 2012
iPad (3rd Generation) WiFi model needs a new owner
The iPad has been sold. Thank you for your interestes.
An iPad needs a new owner for 35,000 yen.
The iPad is 3rd Generation WiFi model (no mobile phone network), with Retina Display, 64 GB storage capacity, Apple Care+ covered until April 2014.
I have used the iPad always with Belkin's case, thus I see very little scratch.
You can find more information on Apple's website:
Preferably I would like to hand over the iPad in person, but I can also ship it to a remote location (within Japan).
Let me know if you have questions.
My contact details are
Taro Murao
phone: 090-1951-6892
email: taro.murao@gmail.com
Ruby on Rails AntiPatterns (2)
Saleh, T.とPytel, C.著の"Rails AntiPattern"から幾つか私が参考になった箇所を少しずつ書いていきます。
デフォルトのCRUDにコントローラのメソッドを追加する際にも例えばconfig/routes.rbの中で
resources :orders do
collection do
post :shipping
post :billing
end
end
とすると下のようなパスが作成されます。
/orders/new
/orders/shipping
/orders/billing
/orders/1
これを書き直して
resources :orders do
members do
post :shipping
post :billing
end
end
とすると下のようにもっとRESTfulな下のようなパスをつくってくれます。
/orders/new
/orders/1/shipping
/orders/1/billing
私も以前に作ったショッピングカートのルートをリファクタリングしないと駄目です…。
ユーザとアプリケーションの信頼を確保するために正確なエラー表示が必要です。サーバサイドのエラーは管理者に報告して、ユーザサイドのエラー(例えばメールアドレスが違うなど)はユーザにその旨を伝えると同時に、New Relicなどのログシステムを使って管理者に随時報告するのが筋な様です。
エラーをキャッチする際にもメソッドにエラーの際はnilを返すようにして do_this rescue nilとするのは無責任なので、メソッドの中で的確なエラーをキャッチして報告する仕組みにする必要があります。
例えばメールを送信する場合はまず
config.action_mailer.raise_delivery_errors = true
にします。
Net::HTTPでは下のようにエラーが下のように定義されている様なので、
SMTP_SERVER_ERRORS = [TimeoutError,
IOError,
Net::SMTPUnknownError,
Net::SMTPServerBusy,
Net::SMTPAuthenticationError]
SMTP_CLIENT_ERRORS = [Net::SMTPFatalError,
Net::SMTPSyntaxError]
管理者のログシステムとしてHoptoadを使用した場合、コントローラでは
と書く事ができるらしいです。
なんでもかんでもbegin/rescueしたら良い訳でも無く、例えばメールアドレスの誤入力など例外ではなく、通常の行動として予想できる内容はActiveRecordのバリデーション機能などを使用してレスポンスを返すのが的確な挙動です。
もう一つの問題としては、大きなプロセスの仕事があります。この場合、対処方法の一つとしてはプロセスをキューに押し込んでしまい、バックグラウンドで仕事をしてもらい順々にこなしてもらうというものです。ライブラリとしてはdelayed_jobというのとRescueというgemがあるそうです。delayed_jobはSQLを、RescueはRedisを使ってキューを管理するそうです。
ちなみにeventmachineなどconcurrencyライブラリもありますが、大きな仕事の場合は同時にさばく意味が少ないので、外部APIから情報を引っ張ってくるなど待ち時間が発生して処理に時間がかかる仕事と、プロセスの処理自体に計算の時間がかかるなどの仕事はそれぞれ異なるストラテジーでさばく必要がある様ですね。
AntiPattern: RESTfulでないアプリケーション
状況が許す限りscaffoldの状態に近いルーティングに保つのが良いプラクティスの様です。デフォルトのCRUDにコントローラのメソッドを追加する際にも例えばconfig/routes.rbの中で
resources :orders do
collection do
post :shipping
post :billing
end
end
とすると下のようなパスが作成されます。
/orders/new
/orders/shipping
/orders/billing
/orders/1
これを書き直して
resources :orders do
members do
post :shipping
post :billing
end
end
とすると下のようにもっとRESTfulな下のようなパスをつくってくれます。
/orders/new
/orders/1/shipping
/orders/1/billing
私も以前に作ったショッピングカートのルートをリファクタリングしないと駄目です…。
AntiPattern: 何故か500ページが表示される
ユーザがボタンをクリックして何故か知らないけど500ページが表示されたり、トップページにリダイレクトされてエラーメッセージも表示されないなどのサイトが多いらしいです(耳が痛い…)。ユーザとアプリケーションの信頼を確保するために正確なエラー表示が必要です。サーバサイドのエラーは管理者に報告して、ユーザサイドのエラー(例えばメールアドレスが違うなど)はユーザにその旨を伝えると同時に、New Relicなどのログシステムを使って管理者に随時報告するのが筋な様です。
エラーをキャッチする際にもメソッドにエラーの際はnilを返すようにして do_this rescue nilとするのは無責任なので、メソッドの中で的確なエラーをキャッチして報告する仕組みにする必要があります。
例えばメールを送信する場合はまず
config.action_mailer.raise_delivery_errors = true
にします。
Net::HTTPでは下のようにエラーが下のように定義されている様なので、
SMTP_SERVER_ERRORS = [TimeoutError,
IOError,
Net::SMTPUnknownError,
Net::SMTPServerBusy,
Net::SMTPAuthenticationError]
SMTP_CLIENT_ERRORS = [Net::SMTPFatalError,
Net::SMTPSyntaxError]
管理者のログシステムとしてHoptoadを使用した場合、コントローラでは
と書く事ができるらしいです。
なんでもかんでもbegin/rescueしたら良い訳でも無く、例えばメールアドレスの誤入力など例外ではなく、通常の行動として予想できる内容はActiveRecordのバリデーション機能などを使用してレスポンスを返すのが的確な挙動です。
AntiPattern: 長いレスポンス待ち
問題の一つは、外部サービスを使っている場合(例えば外部サーバのSMTPを使ってメールを送信する場合)サーバからのレスポンスが遅い場合があります。デフォルトではNet::HTTPのタイムアウトは30秒に設定されているそうですが、これを3秒に設定するという対処方法があります。もう一つの問題としては、大きなプロセスの仕事があります。この場合、対処方法の一つとしてはプロセスをキューに押し込んでしまい、バックグラウンドで仕事をしてもらい順々にこなしてもらうというものです。ライブラリとしてはdelayed_jobというのとRescueというgemがあるそうです。delayed_jobはSQLを、RescueはRedisを使ってキューを管理するそうです。
ちなみにeventmachineなどconcurrencyライブラリもありますが、大きな仕事の場合は同時にさばく意味が少ないので、外部APIから情報を引っ張ってくるなど待ち時間が発生して処理に時間がかかる仕事と、プロセスの処理自体に計算の時間がかかるなどの仕事はそれぞれ異なるストラテジーでさばく必要がある様ですね。
Wednesday, 12 December 2012
Ruby on Rails AntiPatterns (1)
Saleh, T.とPytel, C.著の"Rails AntiPattern"から幾つか私が参考になった箇所を少しずつ書いていきます。
クラスを分ける、モジュールを使う、callbackを使うなどORM自体で搭載されている機能は使用するという解決策を。
@posts = Post.where(status: "published", order: "number_visited DESC").limit(10)
とするよりも
モデルの中で
class Post
scope :tops, where(status: "published", order: "number_visited DESC").limit(10)
end
とすれば
@posts = Post.tops
だけですみます。これはテストを書く際にも
before(:each)
published_posts = create(:posts)
Post.stub(:where){published_posts}
tops_posts = published_posts.take(10)
published_posts.stub(:limit).with(10) {top_posts}
end
などというスタッブ・モックチェーンを書かなくても済みます。テストを書く際にメソッドチェーンはしんどい…。"Don't ask codes but tell what to do."というような言葉もありましたが、やはりTDDのプラクティスをうまく実行すればしんどいコードを書かなくても済みそうですね。
こうやっていくとだんだんとスパゲッティーになっていくので、こういう書き方は一切辞めて下のように is_guest? is_manager? などと役割役割の名前でauthorizationを実装します。また、役割もデータベースに保存しないでコンスタントとしてハードコードしてしまいます。
多くの場合、役割をデータベーすに保存するのはメリットが少ないそうです。
AntiPattern: Fat Models
"Fat Model, Skinny Controller"という言葉は聞きますが、too fat modelはそもそもコードが読めなくなるし、Railsのパターン以前にOOPやもっと足下の理念から外れてしまいます。クラスを分ける、モジュールを使う、callbackを使うなどORM自体で搭載されている機能は使用するという解決策を。
AntiPattern: ながーいSQLチェーン
例えば人気のある記事トップ10を引っ張って来る時にコントローラの中で、@posts = Post.where(status: "published", order: "number_visited DESC").limit(10)
とするよりも
モデルの中で
class Post
scope :tops, where(status: "published", order: "number_visited DESC").limit(10)
end
とすれば
@posts = Post.tops
だけですみます。これはテストを書く際にも
before(:each)
published_posts = create(:posts)
Post.stub(:where){published_posts}
tops_posts = published_posts.take(10)
published_posts.stub(:limit).with(10) {top_posts}
end
などというスタッブ・モックチェーンを書かなくても済みます。テストを書く際にメソッドチェーンはしんどい…。"Don't ask codes but tell what to do."というような言葉もありましたが、やはりTDDのプラクティスをうまく実行すればしんどいコードを書かなくても済みそうですね。
AntiPattern: 入り組んだユーザ権限処理(authorization)
authorizationの実装を下の様にするケースが多いそうです。こうやっていくとだんだんとスパゲッティーになっていくので、こういう書き方は一切辞めて下のように is_guest? is_manager? などと役割役割の名前でauthorizationを実装します。また、役割もデータベースに保存しないでコンスタントとしてハードコードしてしまいます。
多くの場合、役割をデータベーすに保存するのはメリットが少ないそうです。
Monday, 10 December 2012
ActiveRecord #count, #length, #size
データベースのクエリを使ってできる事はRubyで書かないのが一つのパフォーマンスを向上するキーになるのは当然ですが、勿論それにはデータベースのクエリやORMのコマンドを知らないといけないですね。
limit(num)などは明らかにORMっぽいコマンドなので分かりやすいのですが、最近になってようやくORM使用の際の#count, #length, #sizeの相違についての記事を読みました。結論でActiveRecordでは#countはSQLでCOUNTを出します。#lengthはSQLでは処理されないので、一度配列としてデータを取ってきてRubyとして配列の長さを数えます。#sizeについては、既に配列としてデータを取ってきているオブジェクトに対しては配列の長さを返し、まだクエリのProcで残っているものに対してはCOUNTを発効してくれる便利な関数です。
こういう事を知らないでいつの間にか無駄なデータ転送を強いるコマンドを闇雲に走らせている可能性は冷や汗ですね…。
ちなみに私が最近メインで使っているmongoidでも#countはMongoDBのcountを発効してくれ様です。
limit(num)などは明らかにORMっぽいコマンドなので分かりやすいのですが、最近になってようやくORM使用の際の#count, #length, #sizeの相違についての記事を読みました。結論でActiveRecordでは#countはSQLでCOUNTを出します。#lengthはSQLでは処理されないので、一度配列としてデータを取ってきてRubyとして配列の長さを数えます。#sizeについては、既に配列としてデータを取ってきているオブジェクトに対しては配列の長さを返し、まだクエリのProcで残っているものに対してはCOUNTを発効してくれる便利な関数です。
こういう事を知らないでいつの間にか無駄なデータ転送を強いるコマンドを闇雲に走らせている可能性は冷や汗ですね…。
ちなみに私が最近メインで使っているmongoidでも#countはMongoDBのcountを発効してくれ様です。
Saturday, 8 December 2012
Ruby on Rails 人の失敗から学ぶ
私の経験としては失敗からは学ぶ事がとても多い様に感じます。自分で失敗すると印象が強く残るからでしょうか?でも人の失敗を観察する機会でも学びが多い様に感じます。これは自分の失敗と人の失敗を重ね合わせるというプロセスを勝手に頭の中でしているのでしょうか?
Saleh, T & Pytel, C著 "Rails AntiPattern"という本を読みました。興味深く、おもしろく、苦い内容でした。
デザインパターンの書籍は見る機会が多いのですが、AntiPatternというのは面白く感じました。成功例を並べられても正直面白くないですが、人の失敗を例に挙げて解説してくれるのはとても興味深く面白く感じました。
少しずつ学んだ事を記事に書いてはいきたいと思います。
Saleh, T & Pytel, C著 "Rails AntiPattern"という本を読みました。興味深く、おもしろく、苦い内容でした。
デザインパターンの書籍は見る機会が多いのですが、AntiPatternというのは面白く感じました。成功例を並べられても正直面白くないですが、人の失敗を例に挙げて解説してくれるのはとても興味深く面白く感じました。
少しずつ学んだ事を記事に書いてはいきたいと思います。
Friday, 7 December 2012
Ruby Array#each_sliceメソッド
配列を4つごとに区切った後で更にその4つを.eachで繰り返したいということは多くあるのではないでしょうか?
RoRでの実装はeach_sliceを使ってこうしました(slimを使ったviewのテンプレートです)。
- @products.each_slice(4) do |products|
ul
- products.each do |product|
li= product.name
これで
ul
li
li
li
li
ul
li
li
li
li
ul
li
li
と続くHTMLを作れます。
RoRでの実装はeach_sliceを使ってこうしました(slimを使ったviewのテンプレートです)。
- @products.each_slice(4) do |products|
ul
- products.each do |product|
li= product.name
これで
ul
li
li
li
li
ul
li
li
li
li
ul
li
li
と続くHTMLを作れます。
Wednesday, 5 December 2012
Array#eachでまとめてメソッド定義
例えばユーザ認証で
class User
ROLES = %w(contributor manager admin)
attr_accessor :role
def is_contributor?
self.role == "contributor"
end
def is_manager?
self.role == "manager"
end
def is_admin
self.role == "admin"
end
end
user = User.new
user.role = "contributor"
user.is_admin? #--> false
user.is_contributor? #--> true
というコードを簡略にして
class User
ROLES = %w(contributor manager admin)
attr_accessor :role
ROLES.each do |role|
define_method "is_#{role}?" do
self.role == role
end
end
end
とリファクタリングできます。
Tuesday, 4 December 2012
フリーランス仕事サイト
それで最近登録してみたのですが、やはり仕事の量も質もかなり良く感じます。Stack Overflowが運営するCareers 2.0も良い仕事がありそうですが、こちらはどちらかというとパーマネントのポジションがほとんどのようです。Elanceはプロジェクトベースの仕事がメインで掲載されています。
ちなみにスキルチェックのテストもあり、私はRailsのテストを受けたのですがやっと”可”のスコアでした。Rubyのテストは全然だめでした。こんなレベルではまだ技術者とも呼べませんね…。トップ5%とかいうひとのスコアを見ると、歴然と差があるなあと感じます。まだまだこれからですね。
Monday, 3 December 2012
viewでcontent_forを使うか、ヘルパーメソッドを使うか?
最近 Rails の viewで
<% content_for :title do "Title" end %>
として
<%= yield :title %>
とすれば yieldされた場所にcontents_for の内容が返ってくる事を知りました。テンプレートでcontents_for で定義した内容をlayoutの例えば<title>とか<meta name="description" contents="">などに使えそうです。
ヘルパーを使うのとどちらが良いのかと考えた時、ロジックとしてはコントローラから渡されたコンテンツをviewの中でcontents_forとしたほうが奇麗だと思います。
しかしコードが重複しがちな所があるので、やはり使い分けが必要でしょうか。取りあえずはできるだけcontents_for / yieldで書く方向性で。
<% content_for :title do "Title" end %>
として
<%= yield :title %>
とすれば yieldされた場所にcontents_for の内容が返ってくる事を知りました。テンプレートでcontents_for で定義した内容をlayoutの例えば<title>とか<meta name="description" contents="">などに使えそうです。
ヘルパーを使うのとどちらが良いのかと考えた時、ロジックとしてはコントローラから渡されたコンテンツをviewの中でcontents_forとしたほうが奇麗だと思います。
しかしコードが重複しがちな所があるので、やはり使い分けが必要でしょうか。取りあえずはできるだけcontents_for / yieldで書く方向性で。
Friday, 30 November 2012
Herokuのスタックに独自のシェルコマンドを導入する
Herokuではgemでパックされていないシェルコマンドは使えないと思っていました。
が、最近buildpackでgit push でスタックを作成する時に
が、最近buildpackでgit push でスタックを作成する時に
$ heroku create myapp --buildpack https://github.com/heroku/heroku-buildpack-ruby
としてカスタムのbuildpackを指定する事により、カスタムのシェルコマンドを導入する事ができます。あとはRubyの中で `command`です。buildpackについては下に記事があります。
シェルで使い慣れているあれやこれやのコマンドをHerokuにデプロイしたアプリケーションでもつかえるようになります。ただここまで来ると自分でクラウドアプリケーションサーバであるHerokuではなくVPSなど自分でサーバの環境から構築するのとどちらが良いのか微妙なラインになってきますね…。
Wednesday, 28 November 2012
Caching implementation on RoR
今作っているRuby on Railsでアプリケーションをキャシングをするのに、調べ物をあれこれと。
アプリケーションはHeroku上で動かすのですが、Herokuのドキュメント上にはアプリケーションが再起動する際にはコンパイル後に保存されたディスク上のデータは消えるので、ディスクキャッシュは使えないそうです。なのでHerokuのおすすめとしてはmemcachedを使う事。
ということで、今回はHerokuのプラグインであるMemcacheを使ってキャッシュしてみました。キャッシュの方法は下の3つ。
- ページキャッシュ --> アプリケーションのレイアウトを流用した404や500ページを使用したいのでカスタムでページを作ってページキャッシュ。データも大きくないし、消えてしまっても特に問題無いのでディスクキャッシュで。これは単純に
caches_page :action_name
と書くだけです。
- アクションキャッシュ --> sitemap.xmlをデータベースからデータを引っ張ってきて作成しているので、これをアクションキャッシュで保存。データベースが大きくなる予定なので、botが来る度にxmlを生成しているとパフォーアンスの低下に繋がる可能性が高いです。検索botたちが訪問する頻度はそんなに高くないだろうと思うので、3日で賞味期限が切れる様に設定。多分これで良いと思います…。これも同じくコントローラの最初で
caches_action :action_name, expires_in: 3.days
と記述するだけ。
- 外部API --> ショッピングモールが提供するAPIから商品の情報を引っ張ってきているのですが、このレスポンスがかなり時間がかかっている様です(20個ぐらいの商品情報を引っ張って来るのに2秒近く)。これは取りあえずAPIのデータのみをmemcachedに保存。まずは賞味期限8時間ぐらいで動かしてみます。コントローラ上でmemcacheを使用して幾つかのviewでもキャッシュしたデータを利用できる様にします。製品ごとに販売できる商品を製品のキャッシュデータをデータベースの中のidとupdated_atのタイムスタンプ、それに'buyable'の文字列を付与したインデックスで管理します。
@buyables = Rails.cache.fetch([@product, 'buyables'], expires_in: 8.hours) { @product.buyables }
アプリケーションはHeroku上で動かすのですが、Herokuのドキュメント上にはアプリケーションが再起動する際にはコンパイル後に保存されたディスク上のデータは消えるので、ディスクキャッシュは使えないそうです。なのでHerokuのおすすめとしてはmemcachedを使う事。
ということで、今回はHerokuのプラグインであるMemcacheを使ってキャッシュしてみました。キャッシュの方法は下の3つ。
- ページキャッシュ --> アプリケーションのレイアウトを流用した404や500ページを使用したいのでカスタムでページを作ってページキャッシュ。データも大きくないし、消えてしまっても特に問題無いのでディスクキャッシュで。これは単純に
caches_page :action_name
と書くだけです。
- アクションキャッシュ --> sitemap.xmlをデータベースからデータを引っ張ってきて作成しているので、これをアクションキャッシュで保存。データベースが大きくなる予定なので、botが来る度にxmlを生成しているとパフォーアンスの低下に繋がる可能性が高いです。検索botたちが訪問する頻度はそんなに高くないだろうと思うので、3日で賞味期限が切れる様に設定。多分これで良いと思います…。これも同じくコントローラの最初で
caches_action :action_name, expires_in: 3.days
と記述するだけ。
- 外部API --> ショッピングモールが提供するAPIから商品の情報を引っ張ってきているのですが、このレスポンスがかなり時間がかかっている様です(20個ぐらいの商品情報を引っ張って来るのに2秒近く)。これは取りあえずAPIのデータのみをmemcachedに保存。まずは賞味期限8時間ぐらいで動かしてみます。コントローラ上でmemcacheを使用して幾つかのviewでもキャッシュしたデータを利用できる様にします。製品ごとに販売できる商品を製品のキャッシュデータをデータベースの中のidとupdated_atのタイムスタンプ、それに'buyable'の文字列を付与したインデックスで管理します。
@buyables = Rails.cache.fetch([@product, 'buyables'], expires_in: 8.hours) { @product.buyables }
Monday, 26 November 2012
Ruby block, Proc, lambdaについてやっと調べてみました。
ずっと分からないと感じていたRubyのclosureについて調べてみました。
まずProcオブジェクトは手続きを記述したコードブロックを保存したオブジェクトです。これだけだとただの無名関数ですが、Procはその中にその時の周りの変数の状態なども保存できる事から、closureになるのでしょう(PHPのある日本語マニュアルページでは”無名関数はクロージャとも呼ばれ”と書いてあるけど…)。
例えば
x = 0
foo = Proc.new {return x}
foo.call
とすると
=>0
が返ってきます。しかし、
foo = Proc.new {return x}
x = 0
foo.call
とすると
NameError: undefined local variable or method `x' for main:Object
とエラーが出ます。Proc.newした時にあったKernelにくっついたxメソッドの返り値を参照しているのでしょう。ここで => 0が返って来ないのがclosureと無名関数の違いなのではないでしょうか?
Rubyでは変数の明示的削除はできないらしいですが、例えば
x = 0
foo = Proc.new {return x}
x.delete
x = 0
foo.call
などとできると
NameError: undefined local variable or method `x' for main:Object
のエラーが返ってくると思います。
closureの使い途として考えられるのは例えばDBにクエリを送る際にメソッドチェーンにして遅延評価し、DBのIOを少なくする事でしょうか。
例えばPostモデルがあった時に
@post = Post.has_image.sort_by_date.first
そのままコードを読めば、has_imageメソッドでまずPostのオブジェクトの配列を作って取得し、その後でソートして、その一番最初のオブジェクトを取得するとなります。が、本当にこんな事をしていればサービスとして破綻してしまいますね(破綻しなくても無駄が多すぎて許せないという人もいるのでしょうか…)。
ここはActiveRecordやその他のORMではProcを使用してsort_by_dateの部分までクエリを作ってしまってfirstで初めてPostのオブジェクトを返すという事にしているのでは(まだActiveRecordのコードは読んだ事が無いのですが、これは次の課題です)?
誰かこの文を読んでclosure理解の役に立つと良いですね…。それともやっぱり分かりにくい文になったかな…。
まずProcオブジェクトは手続きを記述したコードブロックを保存したオブジェクトです。これだけだとただの無名関数ですが、Procはその中にその時の周りの変数の状態なども保存できる事から、closureになるのでしょう(PHPのある日本語マニュアルページでは”無名関数はクロージャとも呼ばれ”と書いてあるけど…)。
例えば
x = 0
foo = Proc.new {return x}
foo.call
とすると
=>0
が返ってきます。しかし、
foo = Proc.new {return x}
x = 0
foo.call
とすると
NameError: undefined local variable or method `x' for main:Object
とエラーが出ます。Proc.newした時にあったKernelにくっついたxメソッドの返り値を参照しているのでしょう。ここで => 0が返って来ないのがclosureと無名関数の違いなのではないでしょうか?
Rubyでは変数の明示的削除はできないらしいですが、例えば
x = 0
foo = Proc.new {return x}
x.delete
x = 0
foo.call
などとできると
NameError: undefined local variable or method `x' for main:Object
のエラーが返ってくると思います。
closureの使い途として考えられるのは例えばDBにクエリを送る際にメソッドチェーンにして遅延評価し、DBのIOを少なくする事でしょうか。
例えばPostモデルがあった時に
@post = Post.has_image.sort_by_date.first
そのままコードを読めば、has_imageメソッドでまずPostのオブジェクトの配列を作って取得し、その後でソートして、その一番最初のオブジェクトを取得するとなります。が、本当にこんな事をしていればサービスとして破綻してしまいますね(破綻しなくても無駄が多すぎて許せないという人もいるのでしょうか…)。
ここはActiveRecordやその他のORMではProcを使用してsort_by_dateの部分までクエリを作ってしまってfirstで初めてPostのオブジェクトを返すという事にしているのでは(まだActiveRecordのコードは読んだ事が無いのですが、これは次の課題です)?
誰かこの文を読んでclosure理解の役に立つと良いですね…。それともやっぱり分かりにくい文になったかな…。
Friday, 23 November 2012
TCP/IPを今更調べてみました
とある会社のCTOと話をした時にTCP/IPの事を訊かれた事を思い出し、今更ですがO'Reilly本を基礎にして調べてみました。
プロトコルのレイヤーとしては
4. Application Layer
ウェブサーバ、メールサーバ、ファイルサーバなどなどのサービス、またその上に載っているアプリケーションのレイヤー。
3. Host-to-Host Transport Layer
Transport Control Protocol (TCP)とUser Datagram Protocol (UDP)などが属する。データをしかるべきポート番号に送ったり、データの送受信を確認したりする。
2. Internet Layer
Internet Protocol (IP)やInternet Control Message Protocol (ICMP)がここに属する。データグラムのサイズを調整したり、IPアドレススキームを解決したりする。RouterはInternet LayerとNetwork Access Layerのみ使用。その上のレイヤーはHostとHostの間で使用する。
1. Network Access Layer
EthernetのアドレスとIPアドレスの対応を取るなど。
と分類するのが一番すっきりするという説があります。
ちなみにTCP/IP protocol suiteの名前は歴史的なもので、別にUDP/ARPとかでも良かったのではないかと思います。TCP/IPは確かにキャッチーだけど、歴史的な遺産をそのまま使うのは余り好きじゃないですね。TCP/IP Protocol Suiteと同等の用語であるInternet Protocol Suite (IPS)の方を使おうか…。でもそれだと他の人と話が合わなくなりそうだし…。
と分類するのが一番すっきりするという説があります。
ちなみにTCP/IP protocol suiteの名前は歴史的なもので、別にUDP/ARPとかでも良かったのではないかと思います。TCP/IPは確かにキャッチーだけど、歴史的な遺産をそのまま使うのは余り好きじゃないですね。TCP/IP Protocol Suiteと同等の用語であるInternet Protocol Suite (IPS)の方を使おうか…。でもそれだと他の人と話が合わなくなりそうだし…。
Thursday, 22 November 2012
Never run when you can walk.
最近こんなフレーズの一部を聞きました。
日々仕事に追われて、すぐに使えるプラグインや関数を探すのに追われているのは私だけでしょうか?"A bad ride is better than a good runNever run if you can walk . . .. . . never walk when you can stand . . .. . . never stand when you can sit . . .. . . never sit when you can lie down.Any fool can be uncomfortable in the field,"
プロダクションの現場で走らなければいけない時はいつでも来るので、走らなくてよい時間を使ってもっと根本の例えば言語のコードを読む事や、OOをもっと理解する、ネットワークの基礎を知るなどやっておく事がありそうです。
私も歩く事を勉強し直しです。
下の記事にもう少し詳しい説明があります。元はカナダの軍隊のオフィシャルでないコード らしいですね。
http://answers.google.com/answers/threadview?id=259247
Tuesday, 20 November 2012
Twitter Bootstrapで素早くUI開発
Twitter Bootstrapを今作っているウェブアプリケーションに導入しています。
Twitter Bootstrapはグリッドやテンプレート、マルチデバイスサポートのレイアウトやボタン、またGlyphiconsも無料で使える契約をTwitterがしてくれています。
CSSエンジンのLess、HTMLの構造などを調べればかなり速く、フレキシブルなUI の構築ができます。Railsでも使えるgemが出ていますし、多分他のウェブ開発フレームワークでも使えるようにしてくれている人がいると思います。
Twitter Bootstrapはグリッドやテンプレート、マルチデバイスサポートのレイアウトやボタン、またGlyphiconsも無料で使える契約をTwitterがしてくれています。
CSSエンジンのLess、HTMLの構造などを調べればかなり速く、フレキシブルなUI の構築ができます。Railsでも使えるgemが出ていますし、多分他のウェブ開発フレームワークでも使えるようにしてくれている人がいると思います。
Friday, 16 November 2012
Vimでファイルを保存する時に現在のファイルのフォルダを取得
Vimでファイルを保存する時に現在のファイルのフォルダを取得するのに少し困っていると、下の記事を見つけました。
結論は
:w %:p:h/FILENAME
で現在編集中のファイルがあるフォルダに新しくファイルを保存できます。
vで選択したファイルの一部を別ファイルに保存する際などに便利です。
なお、%が現在のファイルを返し、:p (path) がそのフルパスを返します。そして:h (head of path)でそのフォルダを返します。
Thursday, 15 November 2012
TextmateからVimに切り替えます
今までコマンドやショートカットを憶えられないからという理由でGUIのテキストエディターであるTextmateを使ってきましたが、もっとコードを書く効率を上げたい動機が切迫してきたのでVimに切り替えます。
だんだんと、調べ物をしている時間や実験でコードを書いている時間の方がプロダクションのプログラムを書いているよりも圧倒的に多くなってきました。で、実際もっともっと調べものをする時間を増やしたいので、できるだけ書く時間を短くしたいと感じています。ので、一つの手段としてVimを導入する事にしました。
チュートリアルで出てきたコマンドは下の通り。
第1章
そういえばHTMLを勉強し始めた2年半前にはMac標準のテキストエディタでは使いにくかったのでTextWranglerを使い始め、CodaがいいよっていうことでCodaにZenCodingを入れて使いました。Railsを使い始めた1年前ぐらいの段階でTextmateを紹介してもらい、今やっとVimに移行です。さて、使いこなせるかな…。
だんだんと、調べ物をしている時間や実験でコードを書いている時間の方がプロダクションのプログラムを書いているよりも圧倒的に多くなってきました。で、実際もっともっと調べものをする時間を増やしたいので、できるだけ書く時間を短くしたいと感じています。ので、一つの手段としてVimを導入する事にしました。
$ vimtutorでチュートリアルが走るので、同じく初めての方はここから始めてみてください。 チュートリアルは全部で7章あります。チュートリアルの内容はあくまで覚えようとするのではなく実際にやってみて体で覚えていくようにとのことです。なんだか職人っぽいん学習方法ですね。
チュートリアルで出てきたコマンドは下の通り。
第1章
- h --> 左へカーソル移動
- j --> 下へカーソル移動
- k --> 上へカーソル移動
- l --> 右へカーソル移動
- :q! --> vimの終了 (quit)
- x --> カーソルの下の文字を削除
- i --> テキストを挿入 (insert)
- A --> 行の最後にテキストを挿入 (Append)
- :wq --> ファイルをセーブして終了
第2章
- dw --> 次のワードまで削除 (delete)
- d$ --> 行の終わりまで削除
- d + motionでいろいろな削除ができる。motionの例は下のとおり
- 0 --> 行の先頭に移動
- w --> 次のワードの先頭に移動 (word)
- e --> 次のワードの最後に移動 (end of word?)
- $ --> 行の最後に移動
- d + number + motion --> numberで指定しただけ削除が行える(例えば d10wなど)
- dd --> 一行削除
- u --> 元に戻す (undo)
- p --> 張りつけ(paste)
- r --> カーソルの下の文字を置換 (replace)
- c --> 文字の置換 (change)。例えば c10 で現在のカーソル一から10文字を削除して文字列を挿入(insertモード)。
第4章
- CTL-G --> 現在のファイルの情報と現在のカーソルの位置情報を表示
- G --> ファイルの一番最後へ移動 (Go?)
- gg --> ファイルの先頭へ移動
- number + G --> number行目へ移動
- / --> 検索。/文字列のように使用。nで次の候補を検索、Nで前の候補を検索。
- ? --> /とは反対の方向に検索
- CTL-O --> 前にいたカーソルの位置に移動
- CTL-I --> 次のカーソル位置に移動
- % --> 対応する括弧に移動 ({[()
- :s/old/new --> "old"を"new"で置換 (substitute)(最初の候補だけ置換される)
- :#,#s/old/new --> #で指定した行の間の文字列を置換
- :s/old/new/g --> 行内の全ての候補を置換
- :%s/old/new/g --> ファイル全部の文字列置換
- :%s/old/new/gc --> 上の動作をそれぞれの候補ごとに対話式で置換
第5章
- :! cmd --> シェルコマンドを実行。例えば :!ls など
- v motion --> 文字列を選択 (visual selection)。選択した文字列に対してもコマンドを実行できる (例えば:w FILENAME 選択した部分のみをファイルに保存)
- :r FILENAME --> ファイルの内容を現在のドキュメントに挿入 (read?)
- :r !cmd --> シェルコマンドの返り値を現在のドキュメントに挿入。例えば :r !ls など
第6章
- o --> 現在のカーソル位置の下に新しい行を挿入してinsertモードに移る 。Oでカーソルの位置に行を挿入
- R motion --> 現在のカーソル位置から motion で指定しただけ文字列を削除し、insertモードに移行<ESC>で編集を終了。(Replace)
- y --> 文字列をコピー (yank)。vで文字列を選択してyでコピー。
- :set ic --> 文字列検索時に大文字、小文字を区別しない (ignore case)
- :set noic --> 文字列検索時に大文字、小文字を区別
- :set hls --> 検索候補の文字列全てをハイライトする (highlight search)
- :set nohld --> hlsを解除
第7章
- :help --> ヘルプを表示
- CTL-W s --> 上下に画面を割って新しいウィンドウを作成
- CTL-W v --> 左右に画面を割って新しいウィンドウを作成
- CTL-W CTL-W --> ウィンドウを移動
- CTL-D --> 候補のコマンドを表示。例えば :e CTL-Dで"e"で始まるコマンドの候補を表示<TAB>で次の候補に移動
ドキュメント外
:e FILENAME --> ファイルを開いて編集 (edit)
そういえばHTMLを勉強し始めた2年半前にはMac標準のテキストエディタでは使いにくかったのでTextWranglerを使い始め、CodaがいいよっていうことでCodaにZenCodingを入れて使いました。Railsを使い始めた1年前ぐらいの段階でTextmateを紹介してもらい、今やっとVimに移行です。さて、使いこなせるかな…。
Tuesday, 13 November 2012
Monday, 12 November 2012
Scala/Clojure/Ruby勉強会 報告 (cont.) #ujmben2012
勉強会に参加して、Rubyの遅延処理が2.0からEnumerable#lazyに実装されるということ(Scalaなどと比べるとそんなにlazyではないという議論になりましたが…)。あとScalaとClojure、Rubyの違いなどを聞いてきました。Clojureのアトミックなスレッドオペレーション(言葉が正しいか???)は特にインパクトがありました…。
まだまだ分からない事が多かったので、個人的にはScalaは分散処理をする必要があるときはおもしろい選択肢。Clojureは言語の仕様がかなり数学的に考えられていて面白いです。単体のマシンで走らせるプログラムにはとても面白そうという印象です。RubyはRailsを使っていると開発が速いので放せないですね。memoize処理の書き方もとてもシンプルで個性的。
まだまだ分からない事が多かったので、個人的にはScalaは分散処理をする必要があるときはおもしろい選択肢。Clojureは言語の仕様がかなり数学的に考えられていて面白いです。単体のマシンで走らせるプログラムにはとても面白そうという印象です。RubyはRailsを使っていると開発が速いので放せないですね。memoize処理の書き方もとてもシンプルで個性的。
Saturday, 10 November 2012
Scala/Clojure/Ruby勉強会 #ujmben2012
Scala/Clojure/Ruby勉強会に参加してきました。
http://kokucheese.com/event/index/57145/
言語ではなくハートで話す感じのこんなイベント私はとても好きです。とても刺激になりました。勉強会の後でもいろいろ調べものしないと…ですね。来年もまた参加したいです。
http://kokucheese.com/event/index/57145/
言語ではなくハートで話す感じのこんなイベント私はとても好きです。とても刺激になりました。勉強会の後でもいろいろ調べものしないと…ですね。来年もまた参加したいです。
Google Calendarのイベントを拾ってFacebookページに投稿するアプリケーション
Google Calendarで管理しているイベントを前日に拾ってFacebookページに投稿するアプリケーションを作りました。コードはMITライセンスでGitHub上で公開しています。
ちょっとセッティングが面倒ですが使ってみてくださいね。セッティングにはある程度のRubyの開発環境とHerokuが使える事が前提です…。まだまだ開発者が使う事を前提としたアプリケーションですね…。
フィードバックもお待ちしてます。
Thursday, 8 November 2012
RailsとRubyのエラーハンドリングの違い
ウェブアプリケーションを作っていると
if !object.method
do_this
else
do_that
end
という方法でユーザを誘導する習慣が付いていますが、Rubyで組み込みやデスクトップアプリケーションなどを開発する際には下のようにする人が多いのではないでしょうか?
begin
do_this
do_that
rescue
error_handling_method($!)
end
こうしておいて
def do_this
raise 'Specific error message' if !some_method
end
などとそれぞれのメソッドの中でRuntime errorを発生させれば最後のrescueの所でまとめてエラーを処理できるので便利でした。例えばSTDOUTに表示させるとか、ログにまとめるとか、メールでエラーを報告するなどなど。
ちなみにRSpecではこのサイトに書いてある通り
it "should raise" do
expect{Object.non_existent_message}.to raise_error(NameError) end
とすればテストが書けます。
Railsでも同じようにエラーの処理はできると思いますが、通常begin, rescue, endは使わないですね。ディベロッパー向けのAPI以外では、ウェブアプリケーションはエラーメッセージは極力詳細は出さない事もセキュリティー上大切なのでこのような設計になるのでしょうね。例外が発生したら多くの場合シンプルにbreakして500を返しますもんね…。ウェブサービスでもREST APIを作る人はもっと複雑なエラーハンドリングを開発しているんでしょうね。お疲れさまです。
if !object.method
do_this
else
do_that
end
という方法でユーザを誘導する習慣が付いていますが、Rubyで組み込みやデスクトップアプリケーションなどを開発する際には下のようにする人が多いのではないでしょうか?
begin
do_this
do_that
rescue
error_handling_method($!)
end
こうしておいて
def do_this
raise 'Specific error message' if !some_method
end
などとそれぞれのメソッドの中でRuntime errorを発生させれば最後のrescueの所でまとめてエラーを処理できるので便利でした。例えばSTDOUTに表示させるとか、ログにまとめるとか、メールでエラーを報告するなどなど。
ちなみにRSpecではこのサイトに書いてある通り
it "should raise" do
expect{Object.non_existent_message}.to raise_error(NameError) end
とすればテストが書けます。
Railsでも同じようにエラーの処理はできると思いますが、通常begin, rescue, endは使わないですね。ディベロッパー向けのAPI以外では、ウェブアプリケーションはエラーメッセージは極力詳細は出さない事もセキュリティー上大切なのでこのような設計になるのでしょうね。例外が発生したら多くの場合シンプルにbreakして500を返しますもんね…。ウェブサービスでもREST APIを作る人はもっと複雑なエラーハンドリングを開発しているんでしょうね。お疲れさまです。
Tuesday, 6 November 2012
RubyのTimeクラスオブジェクトをRFC3339に変換
Google Calendar API(v2)を使っていて、時間のクエリをRFC3339フォーマットにしてくださいということが書いてありましたが、RubyのTimeクラスにはrfc3339メソッドがありません。
このサイトに書いてあるにはRSSではRFC3339は標準なので、RubyではRFC3339フォーマットに時間を変化するのは#xmlschemaで提供されているそうです。
irb > Time.now.xmlschema
で変換できました。
※後で教えてもらったのですが、DateTimeクラスだとrfc3339メソッドがあるみたいです。ちなみにDateTimeクラスを用いると例えば下のコマンドで次の日の00:00時をRFC3339フォーマットのString形式で返してくれます。
Date.today.next.to_time.to_datetime.to_s
このサイトに書いてあるにはRSSではRFC3339は標準なので、RubyではRFC3339フォーマットに時間を変化するのは#xmlschemaで提供されているそうです。
irb > Time.now.xmlschema
で変換できました。
※後で教えてもらったのですが、DateTimeクラスだとrfc3339メソッドがあるみたいです。ちなみにDateTimeクラスを用いると例えば下のコマンドで次の日の00:00時をRFC3339フォーマットのString形式で返してくれます。
Date.today.next.to_time.to_datetime.to_s
Saturday, 3 November 2012
Jiro Dreams of Sushi (ドキュメンタリー映画)
Jiro Dreams of Sushiというドキュメンタリー映画を観ました。じろうさんは、人によっては極端な仕事の仕方だという事を言う人も多い様ですが、私としては多くの会社で仕事をしている人より妥当な生き方をしているように感じました。
Friday, 2 November 2012
Stackoverflow使い始めてみてます
ちなみに最初の発言は見事にモデレータによって削除されました。Twitterで直接訊いてみたところ、なんでも私のは答えではなくコメントとして入れるべき内容だったそうです。ただコメントはある程度reputationというユーザの信頼度の数値が溜まらないとできないそうです。まあ初心者はまだまだ修行してくださいという事でしょうね。Githubといい、stackoverflowといい、コミュニティーのルールを学のも結構大変ですね…。
モデレータは何も分からない人への質問にもしっかり答えてくれる姿勢がありがたいです。meta stackoverflowというstackoverflow自体に関するディスカッションの場も公開で運営されていて面白いです。
Wednesday, 31 October 2012
Google Docs スプレッドシートでコンテンツを管理できるウェブサイト構築
今回Googleだと多くの人が使っているし、新たにアカウント・パスワードを取得しなくても良い、またやはりGoogle Docsのツールはかなり考えられて作られているので便利であるということから、コミュニティー運営のサイトの一部をGoogle Docsの上でコンテンツ管理ができる様に制作しました(ちなみにお問い合わせフォームの問い合わせ管理もGoogle Groupsを活用です)。
実装にはサイトの中のどの部分をGoogle Docsで管理できる様にするかを決めて、あとは対象のGoogle Docsを公開してREST APIでjsonデータを引っ張ってくるだけです。
それなりにコンセプトは面白いのですが、ログインの為に新しいアカウントが必要無い・データの管理が楽だという理由ではむしろ自前で普通にデータベースを構築してシンプルなインターフェースを作り、OAuthでGoogleのアカウントを使ってユーザにログインしてもらった方が良さそうですね。
今回はまたちょっと失敗なアイデアでした。データベースを自前で構築しない・コミュニティーによる管理が楽な画期的なアイデアだと思ったのですが、ちょっと残念です。まあどれだけ手間がかかるとか、実際に動かしてみた時の利便性は実際に経験してみないと分からないので、やってみて良かったです。
実装にはサイトの中のどの部分をGoogle Docsで管理できる様にするかを決めて、あとは対象のGoogle Docsを公開してREST APIでjsonデータを引っ張ってくるだけです。
それなりにコンセプトは面白いのですが、ログインの為に新しいアカウントが必要無い・データの管理が楽だという理由ではむしろ自前で普通にデータベースを構築してシンプルなインターフェースを作り、OAuthでGoogleのアカウントを使ってユーザにログインしてもらった方が良さそうですね。
今回はまたちょっと失敗なアイデアでした。データベースを自前で構築しない・コミュニティーによる管理が楽な画期的なアイデアだと思ったのですが、ちょっと残念です。まあどれだけ手間がかかるとか、実際に動かしてみた時の利便性は実際に経験してみないと分からないので、やってみて良かったです。
Monday, 29 October 2012
SinatraとRSpecで開発(ちょっとしんどい)
ここ2日程SinatraとRSpecを使って、1ページウェブサイトの制作をしていました。
Sinatraはとてもシンプルなのが好きで使っているのですが、少しやる事が複雑になると一つずつrequireを追加していく必要があります。フォームを設置する、外部APIを使用する、テストを書くという程度の制作になればSinatraではなくてRailsにしたほうがかなり時間を抑えて開発できるのではないでしょうか。小さな規模のサイトなのにかなり時間がかかりました。
例えばURLのパースにはURIを使い、外部APIを使うにはNet:HTTPを使い、メールの送信にはPonyかMailなどのgemを使用、viewのヘルパーもデフォルトでは便利なものが多くないので、Sinatra_moreのgemを引っ張ってくるという具合です。RSpecのテストをする際にもデフォルトではassignsやrender_templateなどの何気なく使用しているマッチャーも無く、カスタマイズが必要でした。メールの送信もあまりマニュアルが整備されていないgemを使う必要があり、コードを読みにいったりする必要がありました。
今回はいかにRoRが皆に支持されていろんな便利なツールを実装しているか知る良い機会になりました。それはそれでありがたい経験です。
Sinatraはとてもシンプルなのが好きで使っているのですが、少しやる事が複雑になると一つずつrequireを追加していく必要があります。フォームを設置する、外部APIを使用する、テストを書くという程度の制作になればSinatraではなくてRailsにしたほうがかなり時間を抑えて開発できるのではないでしょうか。小さな規模のサイトなのにかなり時間がかかりました。
例えばURLのパースにはURIを使い、外部APIを使うにはNet:HTTPを使い、メールの送信にはPonyかMailなどのgemを使用、viewのヘルパーもデフォルトでは便利なものが多くないので、Sinatra_moreのgemを引っ張ってくるという具合です。RSpecのテストをする際にもデフォルトではassignsやrender_templateなどの何気なく使用しているマッチャーも無く、カスタマイズが必要でした。メールの送信もあまりマニュアルが整備されていないgemを使う必要があり、コードを読みにいったりする必要がありました。
今回はいかにRoRが皆に支持されていろんな便利なツールを実装しているか知る良い機会になりました。それはそれでありがたい経験です。
Friday, 26 October 2012
Google API Spreadsheetからjsonでデータを取得
Google API Spreadsheetからjsonでデータを取得しようとしてGoogleのドキュメントを見ていたのですが、なかなかドキュメントが見つかりませんでした。json形式でスプレッドシートの内容を取って来れる仕様は無くなってしまう方向なのかもしれませんね。下にjson形式でデータを取ってくる方法が書いてありました。
http://datatables.net/forums/discussion/5611/how-to-grab-datatables-data-from-a-google-spreadsheet/p1
現在jsonc形式もxmlもサポートされていないようです。Google Data API のjsonはパースすると$tなどなんだかわけの分からないキーを打たないといけないので、なんだか気持ちが悪いです。Google Calendarではjsonc形式が使えて、こちらはもっと人間フレンドリーなデータ構造になっていました。
http://datatables.net/forums/discussion/5611/how-to-grab-datatables-data-from-a-google-spreadsheet/p1
現在jsonc形式もxmlもサポートされていないようです。Google Data API のjsonはパースすると$tなどなんだかわけの分からないキーを打たないといけないので、なんだか気持ちが悪いです。Google Calendarではjsonc形式が使えて、こちらはもっと人間フレンドリーなデータ構造になっていました。
Wednesday, 24 October 2012
Railsでたくさんページがあるサイトを作る時はパーツをwidget化すると便利ではないでしょうか?
apotomoというwidgetを表示するgemがありました。ページがたくさんあるサイトはサイドバーに幾つかのページで共通のwidgetがあるのが一般的ではないでしょうか?
できるだけコードを少なくして手間を少なくするのはプログラマーの一般的習性かと思います。viewのお掃除には勿論Railsのサブレイアウトを使う手段がありますが同時に、レイアウト間で共通に使用するアイテムはwidget化してしまうのも一つの手段です。
使い方は制作者のサイトにスクリーンキャストがあるので、見せてもらいました。
以下、全く本文とは関係無いトピックです。一つのスクリーンキャストを見終わった時に全然関係無いLinuxのスクリーンキャスト作成ツールを紹介するスクリーンキャストが出てきたのですが、このスクリーンキャストがまたスイートです。テック系でこんなスイートなスクリーンキャストを見る事ができるのは素晴らしいアイデアですね。ノックアウトという感じです…。
できるだけコードを少なくして手間を少なくするのはプログラマーの一般的習性かと思います。viewのお掃除には勿論Railsのサブレイアウトを使う手段がありますが同時に、レイアウト間で共通に使用するアイテムはwidget化してしまうのも一つの手段です。
使い方は制作者のサイトにスクリーンキャストがあるので、見せてもらいました。
以下、全く本文とは関係無いトピックです。一つのスクリーンキャストを見終わった時に全然関係無いLinuxのスクリーンキャスト作成ツールを紹介するスクリーンキャストが出てきたのですが、このスクリーンキャストがまたスイートです。テック系でこんなスイートなスクリーンキャストを見る事ができるのは素晴らしいアイデアですね。ノックアウトという感じです…。
Monday, 22 October 2012
pry gem
pryというgemを今更ですが発見しました。**nixシステムのシェルみたいにrubyプロジェクトのフォルダやファイルを行ったり来たりしてクラスやメソッドを見れる助けをするライブラリのようです。https://vimeo.com/26391171にテンポ良く機能を紹介してくれるスクリーンキャストがあります。
pryでは例えば
pry(main) > require "hello_world"
pry(main) > ls HelloWorld
と打てばHelloWorldクラスのメソッドや変数を見せてくれます。また、
pry(main) > cd HelloWorld
と打てばHelloWorldクラスにcdしてくれるような挙動になり、
pry(HelloWorld) > ls
でHelloWorldクラスのメソッドや変数が見れます。また、
pry(HelloWorld) > show-method say_helloとすればメソッドのコードとファイルの場所が見れます。デバッグの時、テキストエディタの検索機能を駆使しなくても目的のコードに簡単にたどり着けそうです。
pryでは例えば
pry(main) > require "hello_world"
pry(main) > ls HelloWorld
と打てばHelloWorldクラスのメソッドや変数を見せてくれます。また、
pry(main) > cd HelloWorld
と打てばHelloWorldクラスにcdしてくれるような挙動になり、
pry(HelloWorld) > ls
でHelloWorldクラスのメソッドや変数が見れます。また、
pry(HelloWorld) > show-method say_helloとすればメソッドのコードとファイルの場所が見れます。デバッグの時、テキストエディタの検索機能を駆使しなくても目的のコードに簡単にたどり着けそうです。
Thursday, 18 October 2012
sass 便利です
css extensionのsassをこれまた最近仕事で使う事になったのですが、便利ですし、おもしろいです。
sassでは変数が使えるので、ローカルファイルでいろいろ変数を使い回したり、グローバル変数を設定して@importで設定ファイルを読み込んだりと使い方ができます。ただRubyで使用する場合など、変数の設定はrequireでは読み込めないので、@importする必要があるようです。これはちょっと不便ですが…
OOPのようにcssを使う方法としてsassが使えます。
@extendがどちらかというと継承に使えるツールで、一番下のレイヤーcssを作っていく際など、下の様にまずプロトタイプを作ってクラスにさせて作成するというような事ができます。
%layer
width: 100%
#header, #contents, #footer
@extend %layer
機能追加をする Ruby でいうモジュールのような機能はミックスインで利用できます。例えばclearfixやしましまビジュアルをある要素に追加したいという場合はまずミックスインを定義してそれを要素にインクルードします。ミックスインの定義は下の様にします。
=clearfix
*zoom: 1
&:after
content: "."
display: block
clear: both
height: 0
visibility: hidden
このミックスインをインクルードしたい要素にインクルードします。
#header, #contents, #footer
+clearfix
以上が私としてはレイアウトの定義に使えるツールだったのですが、色や背景画像などのテーマを作成するにはどうしたら良いかと暫く悩んだのですが、結局関数の定義の機能を使用する事にしました。他に良いアイデアがあれば教えてほしいですね…
関数の定義は@functionを使って'whiteTheme'と'blackTheme'テーマのパーツ毎に引き出してくる形にしました。
@function themeParts( $scope, $theme: blackTheme )
$base_bg_color = #000
$base_font_color = #fff
@if $theme == whiteTheme
$base_bg_color = #fff
$base_font_color = #000
@if scope == base_bg_color
@return $base_bg_color
@if scope == base_font_color
@return $base_font_color
以上がテーマのパーツを選んでくる関数のベースで、これを実際のテーマに入れていきます。ここで@eachを使います。
@each $theme in blackTheme, whiteTheme
body.#{$theme}
background: themeParts(base_bg_color, $theme)
color: themeParts(base_font_color, $theme)
これでsassをコンパイルした時にbody.blackThemeとbody.whiteThemeのそれぞれのcssが作成されて、テーマ分けができます。随時背景画像やネストされたクラスなど同様に登録していきます。
sassは素のcssよりかなり機能が充実しているので、技に溺れて不要なツールを使いすぎてしまう可能性があるのですが、ちゃんと使えばかなりすっきりしたコードにリファクタリングできると思います。
皆さん楽しくsassを使ってみてください。
sassでは変数が使えるので、ローカルファイルでいろいろ変数を使い回したり、グローバル変数を設定して@importで設定ファイルを読み込んだりと使い方ができます。ただRubyで使用する場合など、変数の設定はrequireでは読み込めないので、@importする必要があるようです。これはちょっと不便ですが…
OOPのようにcssを使う方法としてsassが使えます。
@extendがどちらかというと継承に使えるツールで、一番下のレイヤーcssを作っていく際など、下の様にまずプロトタイプを作ってクラスにさせて作成するというような事ができます。
%layer
width: 100%
#header, #contents, #footer
@extend %layer
機能追加をする Ruby でいうモジュールのような機能はミックスインで利用できます。例えばclearfixやしましまビジュアルをある要素に追加したいという場合はまずミックスインを定義してそれを要素にインクルードします。ミックスインの定義は下の様にします。
=clearfix
*zoom: 1
&:after
content: "."
display: block
clear: both
height: 0
visibility: hidden
このミックスインをインクルードしたい要素にインクルードします。
#header, #contents, #footer
+clearfix
以上が私としてはレイアウトの定義に使えるツールだったのですが、色や背景画像などのテーマを作成するにはどうしたら良いかと暫く悩んだのですが、結局関数の定義の機能を使用する事にしました。他に良いアイデアがあれば教えてほしいですね…
関数の定義は@functionを使って'whiteTheme'と'blackTheme'テーマのパーツ毎に引き出してくる形にしました。
@function themeParts( $scope, $theme: blackTheme )
$base_bg_color = #000
$base_font_color = #fff
@if $theme == whiteTheme
$base_bg_color = #fff
$base_font_color = #000
@if scope == base_bg_color
@return $base_bg_color
@if scope == base_font_color
@return $base_font_color
以上がテーマのパーツを選んでくる関数のベースで、これを実際のテーマに入れていきます。ここで@eachを使います。
@each $theme in blackTheme, whiteTheme
body.#{$theme}
background: themeParts(base_bg_color, $theme)
color: themeParts(base_font_color, $theme)
これでsassをコンパイルした時にbody.blackThemeとbody.whiteThemeのそれぞれのcssが作成されて、テーマ分けができます。随時背景画像やネストされたクラスなど同様に登録していきます。
sassは素のcssよりかなり機能が充実しているので、技に溺れて不要なツールを使いすぎてしまう可能性があるのですが、ちゃんと使えばかなりすっきりしたコードにリファクタリングできると思います。
皆さん楽しくsassを使ってみてください。
Tuesday, 16 October 2012
slim コメント方法
最近 Ruby テンプレートエンジンの slim を仕事で使い始めました。便利なのですが、困った事が一つありました。コメントをどうするか?です。
勿論本家マニュアルにはコメントの方法は書いてあるのですが、どうもうまくいきません。困って無量井さんに訊いたところ、コメントの "/" もインデント処理が有効という事でした。ということは
/ Comment
p Lorem ipsum
p dolor sit amet
とすると / Comment 以下の行が全部コメントになってしまいます。なので、コメント以下の行を有効にしようとすると下のようにしないといけないという事でした。
/ Comment
p Lorem ipsum
p dolor sit amet
そんな些細な事は本家のマニュアルには書いていないし…。困った方の参考になれば幸いです。
勿論本家マニュアルにはコメントの方法は書いてあるのですが、どうもうまくいきません。困って無量井さんに訊いたところ、コメントの "/" もインデント処理が有効という事でした。ということは
/ Comment
p Lorem ipsum
p dolor sit amet
とすると / Comment 以下の行が全部コメントになってしまいます。なので、コメント以下の行を有効にしようとすると下のようにしないといけないという事でした。
/ Comment
p Lorem ipsum
p dolor sit amet
そんな些細な事は本家のマニュアルには書いていないし…。困った方の参考になれば幸いです。
Saturday, 6 October 2012
mongoid/MongHQ/Heroku設定
mongoid(3.1.0)/MongHQ/Heroku設定で少しはまりました。
Herokuのドキュメント上ではmongoid.ymlのファイルは下のように設定するのがおすすめと書かれていました。
このまま設定しようとするとうまく動きません。調べてみるとこれはyamlファイルのインデントの問題でした。下記のようにインデントを直すとうまくDBが繋がりました。
Heroku の上のドキュメントは多分多くの人が参照するので、MongoHQにドキュメントを修正するようにお願いして修正するという解答が来たのですが、今日の時点ではまだ修正されていない様ですね…。まあみんな忙しいですからね…。
Herokuのドキュメント上ではmongoid.ymlのファイルは下のように設定するのがおすすめと書かれていました。
production:
sessions:
default:
uri: <%= ENV['MONGOHQ_URL'] %>
options:
skip_version_check: true
safe: true
このまま設定しようとするとうまく動きません。調べてみるとこれはyamlファイルのインデントの問題でした。下記のようにインデントを直すとうまくDBが繋がりました。
production:
sessions:
default:
uri: <%= ENV['MONGOHQ_URL'] %>
options:
skip_version_check: true
safe: true
Heroku の上のドキュメントは多分多くの人が参照するので、MongoHQにドキュメントを修正するようにお願いして修正するという解答が来たのですが、今日の時点ではまだ修正されていない様ですね…。まあみんな忙しいですからね…。
Friday, 5 October 2012
S3で静的ウェブサイト提供
3時間ほど前にAWSから"Amazon S3 Support for Web Page Redirects"というタイトルでメールが届きました。
なんでもS3で提供する静的ウェブサイトにリダイレクトの機能が追加されたとか。そもそも静的ウェブサイトをS3上で構築できるとは知らなかったです。わざわざHeroku+Sinatraで構築などしなくても良かったんですね…。S3上ならほぼ費用はほぼ無料に近いのではないでしょうか?
ただS3にはスピードには懸念があるので検証は必要ですね。
なんでもS3で提供する静的ウェブサイトにリダイレクトの機能が追加されたとか。そもそも静的ウェブサイトをS3上で構築できるとは知らなかったです。わざわざHeroku+Sinatraで構築などしなくても良かったんですね…。S3上ならほぼ費用はほぼ無料に近いのではないでしょうか?
ただS3にはスピードには懸念があるので検証は必要ですね。
さよならは新しい関係にこんにちは
ひたすら自分が納得できる仕事を追求したかったため、先月末で約1年間一緒に仕事をしてきたクライエントから離れました。最後まで刺激的な人たちと楽しく仕事ができました。この人たちはもっともっとビジネスで成功してほしいです。
リスクは大きいですが、私は安全な方法を取るよりは自分に嘘をつかないで現在考えられるベストな生き方をしていきたいと思います。現在はやりたかった事を試行錯誤しながらどんどん試しているところです。
さよならは新しい関係にこんにちは、になれば良いなと思います。
リスクは大きいですが、私は安全な方法を取るよりは自分に嘘をつかないで現在考えられるベストな生き方をしていきたいと思います。現在はやりたかった事を試行錯誤しながらどんどん試しているところです。
さよならは新しい関係にこんにちは、になれば良いなと思います。
OS X ハードディスクを初期状態に戻す
当初デザインの仕事が多くなると思いiMac 27インチを購入したのですが、結局RoRやRubyがメインの仕事になり、大きなスクリーンが必要である作業が最近ほぼ皆無になりました。ほとんど使わないで机の上に置いておくのはもったいないので、誰かに買取ってもらう事にしました。
日本でも日本語で中古品を個人で自分の責任で売買できるサービスというのは私はこれまで全然見つからなくて、英語で運営されているコミュニティー上で話が決まりました。TaSJ
さて、マックのHDDを初期状態に戻す方法ですが、まずiTunesStoreからマシンの登録削除をしておいた方が便利です。そのためにはiTunesを起動してStore(日本語のメニューの名前が分かりません…)メニューから"Deauthorize this computer"を選択。Appleのサイト(ここは英語)にも勿論ガイドはあります。
後は基本はアップルのサイトにあるリカバリーの機能を使います。データのバックアップを取った後、コンピュータを再起動してoptionキーを押しているとブートに使用するディスクを選択する画面が出てきます。
ここでリカバリーディスクを選択してブートし、まずHDDの内容を削除します。私はセキュリティー機能を使用してHDDにランダムな情報を3回ぐらい書き込む削除方法を選択したためにデータの削除だけで11時間かかりました。このリカバリーディスクにはOSのデータが入っているのでしょうか?リカバリーディスクの内容は削除できないようなので、結構便利に使用できます。さすが考えられているなと思います。
HDDの内容の削除を行うと、次にOSXを再インストールボタンでOSXを入れ直します。インストールができたらCommand + Qを押して設定せずに終了すると次回起動した時に初期設定のムービーが流れます。
日本でも日本語で中古品を個人で自分の責任で売買できるサービスというのは私はこれまで全然見つからなくて、英語で運営されているコミュニティー上で話が決まりました。TaSJ
さて、マックのHDDを初期状態に戻す方法ですが、まずiTunesStoreからマシンの登録削除をしておいた方が便利です。そのためにはiTunesを起動してStore(日本語のメニューの名前が分かりません…)メニューから"Deauthorize this computer"を選択。Appleのサイト(ここは英語)にも勿論ガイドはあります。
後は基本はアップルのサイトにあるリカバリーの機能を使います。データのバックアップを取った後、コンピュータを再起動してoptionキーを押しているとブートに使用するディスクを選択する画面が出てきます。
ここでリカバリーディスクを選択してブートし、まずHDDの内容を削除します。私はセキュリティー機能を使用してHDDにランダムな情報を3回ぐらい書き込む削除方法を選択したためにデータの削除だけで11時間かかりました。このリカバリーディスクにはOSのデータが入っているのでしょうか?リカバリーディスクの内容は削除できないようなので、結構便利に使用できます。さすが考えられているなと思います。
HDDの内容の削除を行うと、次にOSXを再インストールボタンでOSXを入れ直します。インストールができたらCommand + Qを押して設定せずに終了すると次回起動した時に初期設定のムービーが流れます。
Thursday, 27 September 2012
EC2 バックアップをRuby のAWS SDKとHerokuを用いて構築
EC2が運用ベースに乗ってきたので日ごとのバックアップ環境を構築しました。こんな方法もあるのだという参考にしてください。
バックアップスクリプトはAmazonが提供しているRubyのAWS SDKを用いて作成。これはgem が提供されているので、Gemfileに
gem 'aws-sdk'
の一行を書くだけで利用できます。
毎日一度バックアップスクリプトを動作させて、7日分のバックアップを取っておく内容です。バックアップスクリプトはローカルに置くと恒常的に実行できないのでHerokuを利用させてもらいました(こんな使い方はHerokuもあまりありがたくないでしょうけど、利用するリソールは限りなくゼロに近いので許してください)。Herokuのweb workerを0にして毎日1回実行するSchedulerを登録。Herokuの無料利用枠に収まると思います。
自動バックアップツールはAmazonが提供してくれていると便利なのですが、見つかりませんでした。他にバックアップスクリプトを書いている人はいるのですが、やはり自分の環境にカスタマイズするとなると結局手間なので、使い慣れたRubyとAWS SDKの組み合わせを利用しました。
質問がある方は気軽に連絡してもらえば歓迎です。
バックアップスクリプトはAmazonが提供しているRubyのAWS SDKを用いて作成。これはgem が提供されているので、Gemfileに
gem 'aws-sdk'
の一行を書くだけで利用できます。
毎日一度バックアップスクリプトを動作させて、7日分のバックアップを取っておく内容です。バックアップスクリプトはローカルに置くと恒常的に実行できないのでHerokuを利用させてもらいました(こんな使い方はHerokuもあまりありがたくないでしょうけど、利用するリソールは限りなくゼロに近いので許してください)。Herokuのweb workerを0にして毎日1回実行するSchedulerを登録。Herokuの無料利用枠に収まると思います。
自動バックアップツールはAmazonが提供してくれていると便利なのですが、見つかりませんでした。他にバックアップスクリプトを書いている人はいるのですが、やはり自分の環境にカスタマイズするとなると結局手間なので、使い慣れたRubyとAWS SDKの組み合わせを利用しました。
質問がある方は気軽に連絡してもらえば歓迎です。
Thursday, 20 September 2012
Apache mod_rewrite 文法
Apacheの設置で、www有りと無しのURIが同一のドキュメントを参照するためにmod_rewriteの設定をしていました。Google で検索すればこの類いのhowtoはいくらでも出て来るのですが、例えば下のようなコードを見てもむしろ[NC]って何?%1って何?などなど疑問は増すばかり。Apacheのドキュメントにあたってみました。
"PCRE regular-expression"という言葉が出てきて調べたところこれは"Perl Compatible Regular Expressions"のことでした。ただ文章の書き方が妙に厳密なので嫌な予感がしたのですが、やはり形式言語の類いの話がでてきました。この辺りのフィールドは定義が大切なので、一つの単語の定義を調べるのにリンクを辿り、更にそのリンクの中に分からない使い方の言葉がいくつか出てきてそれぞれリンクを辿って調べていくというとても面倒なリーディングになってしまいました。ただ形式言語とかメタ言語とか、それぞれ面白そうなので始めてしまったらはまりそうだなと思います。プログラムを書いたりサーバの構築・運用をする際にこのようなエンジニアリングとサイエンスの狭間で仕事をするのは個人的にとても面白く感じます。
ここで例えば [NC] はcase insensitiveのフラッグだとか[L]はここでrewriteの書き換えをストップするとか、[R]は強制的に外部リダイレクトさせるとか書いた方がこのブログの読者(がいれば)には役に立つかもしれないのですが、個人的にはそれぞれがApache本家のサイトに当たって楽しんでほしいです。専門知識に乏しい私は最初の30分は1行読み進むごとにいやになって、その後の2時間ぐらいは楽しめました。
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301]
"PCRE regular-expression"という言葉が出てきて調べたところこれは"Perl Compatible Regular Expressions"のことでした。ただ文章の書き方が妙に厳密なので嫌な予感がしたのですが、やはり形式言語の類いの話がでてきました。この辺りのフィールドは定義が大切なので、一つの単語の定義を調べるのにリンクを辿り、更にそのリンクの中に分からない使い方の言葉がいくつか出てきてそれぞれリンクを辿って調べていくというとても面倒なリーディングになってしまいました。ただ形式言語とかメタ言語とか、それぞれ面白そうなので始めてしまったらはまりそうだなと思います。プログラムを書いたりサーバの構築・運用をする際にこのようなエンジニアリングとサイエンスの狭間で仕事をするのは個人的にとても面白く感じます。
ここで例えば [NC] はcase insensitiveのフラッグだとか[L]はここでrewriteの書き換えをストップするとか、[R]は強制的に外部リダイレクトさせるとか書いた方がこのブログの読者(がいれば)には役に立つかもしれないのですが、個人的にはそれぞれがApache本家のサイトに当たって楽しんでほしいです。専門知識に乏しい私は最初の30分は1行読み進むごとにいやになって、その後の2時間ぐらいは楽しめました。
Tuesday, 18 September 2012
Google Map API を使ってフロント開発
久しぶりにRailsを使ってフロント開発です。Google Maps APIを使用した地図上に会社の位置を表示する内容です。
コントローラのコードは1行だけで
class MyController < ApplicationController
def map
@companies = Company.all
end
end
モデルも今回は大して触りません。
あとはひたすらテンプレートとJavaScriptの編集作業です。
Google Maps APIはバージョン3になってかなりできることの範囲が広がったようで、特にRails用のプラグインなど使用しなくても大きな幅でカスタマイズが可能です。ただコマーシャルユースの場合はライセンスが必要で、社内利用のサイトだとサービスに問い合わせると、USD$11,000 for 250,000 page views per yearという返事が返ってきました。安くはありませんね。
Google Mapsは独自の google.maps.event.addListener などのメソッドを提供していて、その挙動と一つづつ試しながらなので、一進一退のゆっくり作業です。ちょっと面倒…。jQueryと組み合わせてゆっくりゆっくり開発です。
マーカーのDOMを取得できないという質問がウェブにあり、これは大変そうだなと思ったのですが、
marker = new google.maps.Marker({
position: m_position,
id: "8iu3afluh"
});
google.maps.event.addListener(marker, "click", function() {
alert(this.id);
});
などとすれば設定したマーカーの id: 8iu3afluh が返って来るので、とにかくこれで問題無さそうです。
コントローラのコードは1行だけで
class MyController < ApplicationController
def map
@companies = Company.all
end
end
モデルも今回は大して触りません。
あとはひたすらテンプレートとJavaScriptの編集作業です。
Google Maps APIはバージョン3になってかなりできることの範囲が広がったようで、特にRails用のプラグインなど使用しなくても大きな幅でカスタマイズが可能です。ただコマーシャルユースの場合はライセンスが必要で、社内利用のサイトだとサービスに問い合わせると、USD$11,000 for 250,000 page views per yearという返事が返ってきました。安くはありませんね。
Google Mapsは独自の google.maps.event.addListener などのメソッドを提供していて、その挙動と一つづつ試しながらなので、一進一退のゆっくり作業です。ちょっと面倒…。jQueryと組み合わせてゆっくりゆっくり開発です。
マーカーのDOMを取得できないという質問がウェブにあり、これは大変そうだなと思ったのですが、
marker = new google.maps.Marker({
position: m_position,
id: "8iu3afluh"
});
google.maps.event.addListener(marker, "click", function() {
alert(this.id);
});
などとすれば設定したマーカーの id: 8iu3afluh が返って来るので、とにかくこれで問題無さそうです。
Saturday, 15 September 2012
TextMate 日本語化
今まで日本語がほとんど必要なかったのでTextMateで日本語タイピングできる様にしていなかったのですが、ふと思いついて日本語を打てる様にしました。今更ですが…。
hetima.com
から CJKInput20061110.zip をダウンロードして解凍、CJK-Input.tmplugin を /Applications/TextMate/Contents/PlugIns/ に移動。
TextMateを再起動すれば日本語が打てる様になってました。
プラグインを開発してくださってありがとうございます。
Friday, 14 September 2012
BDDとTDDはどう違うのか?
以前BDDとTDDはどう違うのか?という質問をされてうまく答えられませんでした。
現在私がBDDで好きだなと思い、TDDと異なると思うのは、BDDはとにかくまずプログラムに何をさせたいかを伝えることです。
暫くRoRとBDDで実践をしていて、決済のAPIを導入することがありました。最初はAPIの仕組みを調べてAPI指定のコマンドを直接コントローラに記述する形で、例えば
gateway = | PaypalApi::Billing.gateway
setup_purchase = gateway.setup_purchase
if setup_purchase.success?
redirect_to gateway.redirect_url_for(setup_purchase.token)
else
redirect_to somewhere-else, notice: "transaction failure"
end
などとしていたのですが、これだとテスト用APIのモックやスタッブを書くのがとても面倒。BDDではこのアプローチをやめて、とにかくAPIの仕様など気にしなくてプログラムに何をさせたいか書く事から始めるとすっきりします。例えばモデルのインスタンスを@orderにしている場合、
if @order.setup_purchase
redirect_to gateway_url
else
redirect_to somewhere-else, notice: "transaction failure"
end
としてモデルの中で実際にsetup_purchaseのコードを書きます。こうするとコードもテストコードも整理しやすくなります。
ただ実際はコントローラからtokenなどのpostリクエストの部分をモデルに渡す必要があるところで後でメソッドに引数を追加する必要など私の場合は出てきましたが。
現在私がBDDで好きだなと思い、TDDと異なると思うのは、BDDはとにかくまずプログラムに何をさせたいかを伝えることです。
暫くRoRとBDDで実践をしていて、決済のAPIを導入することがありました。最初はAPIの仕組みを調べてAPI指定のコマンドを直接コントローラに記述する形で、例えば
gateway = | PaypalApi::Billing.gateway
setup_purchase = gateway.setup_purchase
if setup_purchase.success?
redirect_to gateway.redirect_url_for(setup_purchase.token)
else
redirect_to somewhere-else, notice: "transaction failure"
end
などとしていたのですが、これだとテスト用APIのモックやスタッブを書くのがとても面倒。BDDではこのアプローチをやめて、とにかくAPIの仕様など気にしなくてプログラムに何をさせたいか書く事から始めるとすっきりします。例えばモデルのインスタンスを@orderにしている場合、
if @order.setup_purchase
redirect_to gateway_url
else
redirect_to somewhere-else, notice: "transaction failure"
end
としてモデルの中で実際にsetup_purchaseのコードを書きます。こうするとコードもテストコードも整理しやすくなります。
ただ実際はコントローラからtokenなどのpostリクエストの部分をモデルに渡す必要があるところで後でメソッドに引数を追加する必要など私の場合は出てきましたが。
Thursday, 13 September 2012
iPhone 5 の価格設定って良いですね
アメリカのApple Storeで表示されている価格は16 GBのモデルで199ドル。SIMフリーのものであれば世界中どこに行っても使えますしね。今までのiPhoneは5万円するなどそんな電話、ばからしくて買う気になれませんでした。iPod touchと同じぐらいの価格であれば購入する意義を見いだせますね。
Wednesday, 5 September 2012
ロリポップがRubyウェブアプリケーションクラウドサービスを始めたみたいです
先ほどロリポップからDMが入り、Rubyウェブアプリケーションクラウドサービスの宣伝が届きました。
http://sqale.jp/
Heroku はAWSのサーバを使っているけど日本のサーバは使えなかったので、ダウンロードのスピードがネックでした。その点ロリポップは日本のサーバを使っているのでしょうか?スピードが改善できてあと、ツールもしっかりしているか、試してみる価値はあるかなという気がします。
http://sqale.jp/
Heroku はAWSのサーバを使っているけど日本のサーバは使えなかったので、ダウンロードのスピードがネックでした。その点ロリポップは日本のサーバを使っているのでしょうか?スピードが改善できてあと、ツールもしっかりしているか、試してみる価値はあるかなという気がします。
Thursday, 23 August 2012
Contact From 7 コンバージョントラッキングの方法
WordpressのプラグインであるContact Form 7のコンバージョンをとる設定をする必要がありました。
他の業者さんに頼むとこれはPHPを触らないといけないので結構費用がかかるとのこと。自分で調べると、とてもとても簡単でした。
参考にした記事はこちら --> http://www.seo-blogs.biz/2009/12/03/1291/
要はお問い合わせフォームの送信が成功したときに表示するメッセージをJavaScriptでページのリダイレクトをするコードをHTMLに吐き出すということですね。リダイレクトしたページでコンバージョンを設定する。以上。
同じくWordpressのプラグインであるSubscribe2のコンバージョンもJavaScriptの挿入で済ませました(確かにJavaScriptをオフにしている人のコンバージョンは?という疑問は残りますが…)。Subscribe2の方は、メッセージの類いはPHPコードにハードコーディングされていたので、プラグインの更新は面倒ですね…
他の業者さんに頼むとこれはPHPを触らないといけないので結構費用がかかるとのこと。自分で調べると、とてもとても簡単でした。
参考にした記事はこちら --> http://www.seo-blogs.biz/2009/12/03/1291/
要はお問い合わせフォームの送信が成功したときに表示するメッセージをJavaScriptでページのリダイレクトをするコードをHTMLに吐き出すということですね。リダイレクトしたページでコンバージョンを設定する。以上。
同じくWordpressのプラグインであるSubscribe2のコンバージョンもJavaScriptの挿入で済ませました(確かにJavaScriptをオフにしている人のコンバージョンは?という疑問は残りますが…)。Subscribe2の方は、メッセージの類いはPHPコードにハードコーディングされていたので、プラグインの更新は面倒ですね…
Wednesday, 22 August 2012
人は見掛けによらないか?
“人は見掛けによらない”という言葉がありますが、私は多いに見掛けによると思います。
例えば良い車に乗っているとか良い服を着ているなどの様子を見れば、その人がビジネスに成功しているもしくは、成功している人の家族であるなどなど、大枠の検討はつきます。
しかし、例えば“成功している人”の内面はどうかとなったときはどうでしょうか?いろんなケースがありますからね。ただそれも見た目に出ると思います。そのようなものを見たい時は服装や車ではなく、目の輝きや身のこなしなどもっとデリケートな部分に顕われてきます。
これもうまく利用すればフィルターに使えるかもしれませんね。
例えば良い車に乗っているとか良い服を着ているなどの様子を見れば、その人がビジネスに成功しているもしくは、成功している人の家族であるなどなど、大枠の検討はつきます。
しかし、例えば“成功している人”の内面はどうかとなったときはどうでしょうか?いろんなケースがありますからね。ただそれも見た目に出ると思います。そのようなものを見たい時は服装や車ではなく、目の輝きや身のこなしなどもっとデリケートな部分に顕われてきます。
これもうまく利用すればフィルターに使えるかもしれませんね。
Tuesday, 21 August 2012
[2012年夏休み] 日本にもどってきて
ヨーロッパから戻ってきて数日たちましたが、時差の解消には水に潜れば良いという知り合いのアドバイスのおかげもあってか時差ボケも解消しているようです。ヨーロッパから東アジアに移動する方向の時差はちょっと面倒でしたね。
日曜日には仕事をしないことにしていることと、家族がまだヨーロッパにいることからのんびりとスターバックスに座って外を眺めていました。はっと今頃気がついたのは車が道の左側を走っていることです。いや、日本に帰ってきましたね。ポーランドで借りたレンタカーはギアシフトが右側にあったことと、それ以上にリバースへのシフトが力をかなり入れないとできなかったこともあり、ちょっと当ててしまいました。すみませんでした…
私は日本ではまだまだ社会に馴染めずにいます。(女性は基本的にとても好きですが、アジア系は一般的にあまり惹かれないし…)。血の関係の深い人をはじめとして、周りの人とかなり価値観が合わないために四苦八苦します。道で歩いていて西欧系やいろんな色が交じった家族を見るとやはり親近感を感じて、むしろ外人オブセッション的状態になっている節もあります。
前回ホーチミンから関空への飛行機に乗った時には、日本独特の公の乗り物の中では静かにしないといけない 雰囲気の中で(大げさに言うと)気が狂いそうでした。今回は日本とか白人とかそれぞれの国の文化などという枠に縛られないで、ただ一個人としてそんな社会やそれらに反応している自分を見つめれば良いのだということを意識します。
2013年の夏にはシベリア列車でヨーロッパに移動しようという(予定)ですが、今年も1年チャレンジです。明らかな課題もいくつか見えてきていますし。
日曜日には仕事をしないことにしていることと、家族がまだヨーロッパにいることからのんびりとスターバックスに座って外を眺めていました。はっと今頃気がついたのは車が道の左側を走っていることです。いや、日本に帰ってきましたね。ポーランドで借りたレンタカーはギアシフトが右側にあったことと、それ以上にリバースへのシフトが力をかなり入れないとできなかったこともあり、ちょっと当ててしまいました。すみませんでした…
私は日本ではまだまだ社会に馴染めずにいます。(女性は基本的にとても好きですが、アジア系は一般的にあまり惹かれないし…)。血の関係の深い人をはじめとして、周りの人とかなり価値観が合わないために四苦八苦します。道で歩いていて西欧系やいろんな色が交じった家族を見るとやはり親近感を感じて、むしろ外人オブセッション的状態になっている節もあります。
前回ホーチミンから関空への飛行機に乗った時には、日本独特の公の乗り物の中では静かにしないといけない 雰囲気の中で(大げさに言うと)気が狂いそうでした。今回は日本とか白人とかそれぞれの国の文化などという枠に縛られないで、ただ一個人としてそんな社会やそれらに反応している自分を見つめれば良いのだということを意識します。
2013年の夏にはシベリア列車でヨーロッパに移動しようという(予定)ですが、今年も1年チャレンジです。明らかな課題もいくつか見えてきていますし。
Monday, 20 August 2012
New Old bike has arrive our house/office
A friend of mine gave me a bike. I made a first ride from Rokko Island to Takarazuka. It took about 1.5 hrs, a bit more than I expected, but was a nice ride because it was a relatively brisk evening. It was particularly cool on the island bridge.
シンガーソングライター Asa (Asha)に最近はまっています
ここ数日久しぶりに開いたシンガーソングライター Asa (Asha)の曲を何回か聴いています。彼女の曲は私は好きです。迫力があると感じます。日本のiTunes Store でも曲を聴けます。--> http://itunes.apple.com/jp/album/asa-asha-asha/id276447813?l=jp
"Jailor"より
I'm a prisoner, you are prisoner, too, Mr. Jailor.
You suppress me. You oppress me. But you are also victim, too, Mr. Jailor.
英語以外の歌に触れる機会は少ないですが、私はやはり母語で歌っているときの方が、何を言っているか分からないけど迫力がある気がします。この人は両親がナイジェリア人でフランスで生まれたそうです。Mother tongue はヨルバという言葉らしいです。(日本では”母国語”という言葉はポピュラーですが、”母語”というのは余り目・耳にしないですね)
こんな歌を作って歌うことを仕事にできるのもとても良いですね。
"Jailor"より
I'm a prisoner, you are prisoner, too, Mr. Jailor.
You suppress me. You oppress me. But you are also victim, too, Mr. Jailor.
英語以外の歌に触れる機会は少ないですが、私はやはり母語で歌っているときの方が、何を言っているか分からないけど迫力がある気がします。この人は両親がナイジェリア人でフランスで生まれたそうです。Mother tongue はヨルバという言葉らしいです。(日本では”母国語”という言葉はポピュラーですが、”母語”というのは余り目・耳にしないですね)
こんな歌を作って歌うことを仕事にできるのもとても良いですね。
[2012年夏休み] Warszawa
今回のポーランドは結局Warszawaで最後です。
これまで夏らしい暑い日が続いていたのですが、
一変してだいぶん寒くなりました。
Frederic Chopin 空港からポーランドを出て、ムーミンの待つヘルシンキ空港へ。
Sunday, 19 August 2012
ドキュメンタリー映画 The Perfect Cappuccino
The Perfect Cappuccinoというドキュメンタリー映画を見つけました。
映画の内容はカプチーノが大好きな女性がなぜイタリアでは良いカプチーノにたくさん巡り会えるのに自分が住んでいるアメリカではほぼ皆無なのかという疑問から始まり、カプチーノに関わる歴史や経済などいろいろ探すものです。
普段私は大きなもの、小さなものに全宇宙と同じ深みがあることに不思議さを感じ、どのようにしてそうなっているのか知りたく思っています。
この世界、あらゆるものに深淵は見出されます。カプチーノについてもこのフィルム以上に様々角度からもっともっと深く調べていくことができるでしょう。おもしろく、不思議です。
いつものことですが、 アメリカのiTunes Storeではレンタルできますが日本のiTunes Storeではアクセスできないので、日本でこの映画をみるにはちょっとした努力が必要です。日本でドキュメンタリー映画が全然パブリシティーを得ないのは何時もながら残念です。
映画の内容はカプチーノが大好きな女性がなぜイタリアでは良いカプチーノにたくさん巡り会えるのに自分が住んでいるアメリカではほぼ皆無なのかという疑問から始まり、カプチーノに関わる歴史や経済などいろいろ探すものです。
普段私は大きなもの、小さなものに全宇宙と同じ深みがあることに不思議さを感じ、どのようにしてそうなっているのか知りたく思っています。
この世界、あらゆるものに深淵は見出されます。カプチーノについてもこのフィルム以上に様々角度からもっともっと深く調べていくことができるでしょう。おもしろく、不思議です。
いつものことですが、 アメリカのiTunes Storeではレンタルできますが日本のiTunes Storeではアクセスできないので、日本でこの映画をみるにはちょっとした努力が必要です。日本でドキュメンタリー映画が全然パブリシティーを得ないのは何時もながら残念です。
[2012年夏休み] Kraków
小さな町ばかりを見てきた後だったので、 Krakówはとても大きな街に感じました。 Krakówでは予定していたより全然早く用事が済んでしまった ので宿泊せずにそのままWarszawaへ。 Warszawaへは電車で約3時間です。
Saturday, 18 August 2012
[2012年夏休み] Bielsko-Biała
Bielsko- BiałaはKrakówからバスで2時間の街。
大きな数日続くコンサートイベントから帰ってきた若者達も電車か ら降りてきました。
大きな数日続くコンサートイベントから帰ってきた若者達も電車か
Bielskoでは社会主義時代の名残のホステル泊です。
内装もコップも社会主義時代の様子をそのままとどめている様です
日本はいつ社会主義から抜け出すのでしょうか?
Friday, 17 August 2012
[2012年夏休み] Frankfurt am Main/Słubice
ドイツとポーランドの国境の橋。 ドイツ側の街はFrankfurt am Oder, ポーランド側はSłubice。 ポーランドとドイツの両方に関係のある人たちのとって、 この橋には引力の中心があるようです。 私達も毎日何度かこの橋を渡りました。 ぶらっと散歩で橋を渡る人、観光客、商売人、 国境の向こうの恋人に会いになどそれぞれ様々です。
2004年にEUに加盟した東欧の国々の人々は確か2011年か 2012年からビザなしでEUのどこの国でも住んで仕事ができま す。 労働市場が開放された直後は多くの人が英語圏で裕福なイギリスを 中心に移動したようです。今は一息ついたようです。 いびつなEUですが、 国境が国境として存在し続けているのは何となく不思議な感覚です 。
2004年にEUに加盟した東欧の国々の人々は確か2011年か
国境の橋の下をボートで通る人達。 2003年にはこんなことは出来なかったのでしょうか。
ここではSłubiceのは外れの村に住んでいる知り合い宅に1
そして今度は南東に。寝台車の快適な旅路です。
Thursday, 16 August 2012
イギリスでは墓地以外でも火葬した遺骨を撒くことができるみたいです
私が見たイギリス、ドイツ、ポーランドのお墓は奇麗でした。まあ、日本の限られた土地事情とは比べられないですが。
イギリス人の知り合いに聞いた話では、イギリスでは死体は火葬の後庭や森などでも骨を撒いても良いとのこと。知らずに森の中を歩いていた人が骨を見つけても困るので、焼け残った骨は粉々にするなどの方法がある様です。この知り合いの両親は両方が死んでから一緒に混ぜて撒いたそうです。お墓を持つ人もありますが、このようなお墓を持たないケースは一般的らしいです。
ちなみに日本の法律も調べてみましたが、やはり日本では墓地以外に骨を埋葬することはできないようです。
私が死んだら森や海に骨を撒いてほしいです。家族には死んだ人を悔やむより、生きている人たちの為に働き、生きている人と共に過ごして欲しいです。
イギリス人の知り合いに聞いた話では、イギリスでは死体は火葬の後庭や森などでも骨を撒いても良いとのこと。知らずに森の中を歩いていた人が骨を見つけても困るので、焼け残った骨は粉々にするなどの方法がある様です。この知り合いの両親は両方が死んでから一緒に混ぜて撒いたそうです。お墓を持つ人もありますが、このようなお墓を持たないケースは一般的らしいです。
ちなみに日本の法律も調べてみましたが、やはり日本では墓地以外に骨を埋葬することはできないようです。
私が死んだら森や海に骨を撒いてほしいです。家族には死んだ人を悔やむより、生きている人たちの為に働き、生きている人と共に過ごして欲しいです。
[2012年夏休み] ベルリン着
ベルリンは世界でも有数の魅力的な街だと思います。 いろんな民族が住んでいて、公園も多くあり、 芸術を含めて色々な仕事のチャンスがあります。 ただ失業率は高いですが。毎日いろんなイベントが起きています。 湖が近くにいくつかあるので、 休日には泳いだりボートに乗ったりもできます。
ベルリンでは知り合い宅に泊。
一泊して東へ。
Wednesday, 15 August 2012
Friday, 27 July 2012
月に1度の記帳
家計簿と仕事の記帳を月に一度やっているのですが、性格的にこういうルーティンな仕事はとても苦手…。ただ以前は記帳は気がついたときにやっていたのですが、月に1回にする事で効率が全然上がりました。
郵便局の口座は特に面倒でネットバンキングがとても使えないので、通帳に記入が必用。私はもっと運動が必用なのでATMまで散歩をする良い口実になりますが…。
Wednesday, 25 July 2012
Improve your productivity with Gmail
There was a chance for me to read "Gmail超仕事術". I summarize the contents below.
- You can configure gmail user interface so that starred emails are listed above other messages. http://support.google.com/mail/bin/answer.py?hl=en&answer=18522
- You can create labels which fit your work/life-style, e.g. @work, @home, @waiting response + @date, @to be processed later, @referece
- Google Chrome browser has many integrated functions for Gmail. So, this browser is recommended for Gmail users.
- from:taro --> Matches emails from "taro".
- to:taro --> Matches emails to "taro".
- cc:taro --> Matches emails which have cc to "taro".
- label:task --> Matches emails which have label "task".
- has:attachment --> Matches emails which have attachment file(s).
- after:yyyy/mm/dd --> Matches emails sent after yyyy/mm/dd.
- before:yyyy/mm/dd --> Matches emails sent before yyyy/mm/dd.
- filename:pdf --> Matches emails which have pdf file.
- filename:[.jpg .png] --> Matches emails which have either .jpg or .png files.
- in:spam --> Matches email in spam folder.
Together with above operators, following operators can be used in combination.
- AND
- OR
- "-" --> exclusion
For example, "from:taro AND filename:pdf" matches emails which were sent from "taro" and have pdf file attachment.
Another example is, "from:taro -from:murao" matches emails which were sent from "taro", but not "taro murao".
Gmail has a spam filter. Choose a spam message and click [Report spam]. Similar messages will be automatically filtered out later.
There are email magazines you do not have to read right at the time they arrive, but want to keep. Make a filter, skip inbox and automatically archive them. Labels can be applied when automatically archiving new messages.
http://google.about.com/od/toolsfortheoffice/ss/filter-gmail-messages.htm
- From Yahoo to Gmail --> http://www.wikihow.com/Switch-from-Yahoo!-Mail-to-Gmail
- From Hotmail to Gamil --> http://www.wikihow.com/Switch-from-Hotmail-to-Gmail
- IMAP server to Gmail --> http://www.2by2host.com/articles/import-imap-to-gmail/
Even if you have already fetched email on your local machine, emails can be exported to Gmail account by first enabling IMAP on Gmail and copying local emails to Gmail's on your local machine.
General direction
1. Decide how many times to check emails. This can be one a day, twice a day or more frequent depending on your work style. Checking emails as they arrive-method generally reduces productivity.
2. Keep Inbox clear (empty)
General processing flow
Tips
- Don't user folders but labels and stars.- You can configure gmail user interface so that starred emails are listed above other messages. http://support.google.com/mail/bin/answer.py?hl=en&answer=18522
- You can create labels which fit your work/life-style, e.g. @work, @home, @waiting response + @date, @to be processed later, @referece
- Google Chrome browser has many integrated functions for Gmail. So, this browser is recommended for Gmail users.
Search operators
Following are example of search operators.- from:taro --> Matches emails from "taro".
- to:taro --> Matches emails to "taro".
- cc:taro --> Matches emails which have cc to "taro".
- label:task --> Matches emails which have label "task".
- has:attachment --> Matches emails which have attachment file(s).
- after:yyyy/mm/dd --> Matches emails sent after yyyy/mm/dd.
- before:yyyy/mm/dd --> Matches emails sent before yyyy/mm/dd.
- filename:pdf --> Matches emails which have pdf file.
- filename:[.jpg .png] --> Matches emails which have either .jpg or .png files.
- in:spam --> Matches email in spam folder.
Together with above operators, following operators can be used in combination.
- AND
- OR
- "-" --> exclusion
For example, "from:taro AND filename:pdf" matches emails which were sent from "taro" and have pdf file attachment.
Another example is, "from:taro -from:murao" matches emails which were sent from "taro", but not "taro murao".
Filter emails
There are emails you do not have to check immediately, e.g. email redundant email magazines, or spams.Gmail has a spam filter. Choose a spam message and click [Report spam]. Similar messages will be automatically filtered out later.
There are email magazines you do not have to read right at the time they arrive, but want to keep. Make a filter, skip inbox and automatically archive them. Labels can be applied when automatically archiving new messages.
http://google.about.com/od/toolsfortheoffice/ss/filter-gmail-messages.htm
Relocating from and to Gmail
Import and export from POP, IMAP, Yahoo, Hotmail email servers can be done.- From Yahoo to Gmail --> http://www.wikihow.com/Switch-from-Yahoo!-Mail-to-Gmail
- From Hotmail to Gamil --> http://www.wikihow.com/Switch-from-Hotmail-to-Gmail
- IMAP server to Gmail --> http://www.2by2host.com/articles/import-imap-to-gmail/
Even if you have already fetched email on your local machine, emails can be exported to Gmail account by first enabling IMAP on Gmail and copying local emails to Gmail's on your local machine.
Working offline
Some times, you want to check and write emails when you do not have an internet connection. If you are using Google Chrome, install https://chrome.google.com/webstore/detail/ejidjjhkpiempkbhmpbfngldlkglhimk
and enable the offline mode.
Send emails to a group of contacts
You can create a group of contacts, http://support.google.com/mail/bin/answer.py?hl=en&answer=30970, specify the group name and send emails all the member of this group instantly.
Tuesday, 24 July 2012
ドキュメンタリー映画 "Grandma, a Thousand Times"
ドキュメンタリー映画の "Grandma, a Thousand Times" を見ました。トレイラーはYoutubeで見れます。
レバノンに住んでいる普通のおばあちゃんの生活をドキュメンタリー映画にしたものですが、文化的に縁の遠いこの地域の人たちの日常の生活に少し触れることができるとても良い映画だと思いました。ただこの周辺の地区の過去の戦争のことやその他社会背景をもっと分かっていればもっと理解して楽しめたのになと残念です。また、アラブ世界の人たちは人種的に私が関わったことが少ない人たちなので、顔の表情をとってもその表情が何を表しているのか未だに分かりません。文化の面でも家族の関係が一般的に感覚としてどのようなものなのか分かっていないので、いろいろな意味でとても新鮮でした。
Monday, 23 July 2012
Ruby は殆ど知らなくてもRoRは組めるのですが
RoRはRubyで書かれたフレームワークですが、フレームワークのパーツ(scaffoldやgemなど)を集めて組み立てればRuby自体は基本的なことだけ知っていればあり程度動くウェブアプリケーションは作ることができます。セキュリティーの面でも怖ければ、セッション管理などはライブラリに任せて触らないようにすれば難は逃れられるでしょう。
良いフレームワークは矯正ギブスのようなもので、良い習慣を身につけるのに使えるという話を以前PHPerに聞きました。この意味でRoRはとても良いと思います。最近は、小さなウェブサービスの構築だとRoRを使わずにSinatraで作れるし、実はデータベースが必要なアプリケーションも単純にgemでActiveRecordやMongoIDのようなORマッパーさえ拾ってくればRoRはなくても組めるということにも気がつきます。
もっと自由にRubyを使えるようになりたいと思い、以前に買ったYugui著「はじめてのRuby」を引っ張り出してきたのですが、このコンテクストでは使えないようです。この本はRubyを学び始める人に有益なように譲りたいですね…。Rubyとソフトウェアのデザインパターンを一緒に習得できる書籍を見つけます。
良いフレームワークは矯正ギブスのようなもので、良い習慣を身につけるのに使えるという話を以前PHPerに聞きました。この意味でRoRはとても良いと思います。最近は、小さなウェブサービスの構築だとRoRを使わずにSinatraで作れるし、実はデータベースが必要なアプリケーションも単純にgemでActiveRecordやMongoIDのようなORマッパーさえ拾ってくればRoRはなくても組めるということにも気がつきます。
もっと自由にRubyを使えるようになりたいと思い、以前に買ったYugui著「はじめてのRuby」を引っ張り出してきたのですが、このコンテクストでは使えないようです。この本はRubyを学び始める人に有益なように譲りたいですね…。Rubyとソフトウェアのデザインパターンを一緒に習得できる書籍を見つけます。
Saturday, 21 July 2012
Sinatra で拡張子ごとにMIME-Type (と対応するContent-Type) を設定する
*.bin 拡張子のファイルを"audio/mpeg"としてサーバからヘッダを返さないとiOSで動画が再生されないという仕様のサービスがあり、Sinatraとthinで動かしているシステムの調整が必要になりました。
結論としては
configure do
mime_type :bin, 'audio/mpeg'
end
と書けば解決しました。書式は
mime_type :<extension name>, '<mime type name>'
のようです。
Middlewareを間に挟んで調整するかthinもしくは.ruファイルを編集する必要があるかと考えたのですが、現在Sinatraはモジュールタイプで動かしていないので面倒です。しかし、とても簡単にSinatra上でメソッドが提供されていました。SinatraはMiddlewareとしても利用できるという話ですが、さすが httpヘッダ を調整するのは簡単にできるようです。
結論としては
configure do
mime_type :bin, 'audio/mpeg'
end
と書けば解決しました。書式は
mime_type :<extension name>, '<mime type name>'
のようです。
Middlewareを間に挟んで調整するかthinもしくは.ruファイルを編集する必要があるかと考えたのですが、現在Sinatraはモジュールタイプで動かしていないので面倒です。しかし、とても簡単にSinatra上でメソッドが提供されていました。SinatraはMiddlewareとしても利用できるという話ですが、さすが httpヘッダ を調整するのは簡単にできるようです。
Thursday, 19 July 2012
メソッドチェーンをRSpecでテストする
RSpecでメソッドチェーンをテストするのにどうやったものか手間取りました。
例えば
obj.do1.do2.do3
とあったときには
一気に
obj.stub(:do1.do2.do3)
とstubできないので、
res1 = stub()
res2 = stub()
obj.stub(:do1).and_return(res1)
res1.sbub(:do2).and_return(res2)
とそれぞれstubを作る必要がある様です。
メソッドチェーンはRuby(とRSpec)では推奨されないやり方なのでしょうか…
例えば
obj.do1.do2.do3
とあったときには
一気に
obj.stub(:do1.do2.do3)
とstubできないので、
res1 = stub()
res2 = stub()
obj.stub(:do1).and_return(res1)
res1.sbub(:do2).and_return(res2)
とそれぞれstubを作る必要がある様です。
メソッドチェーンはRuby(とRSpec)では推奨されないやり方なのでしょうか…
Sunday, 15 July 2012
複数言語が入り交じったの家庭の大人は頭が良い?
以前複数言語が入り交じったの家庭のこどもは常に脳がトレーニング状態にあるため、一般に頭が良いという記事をどこかで読みました。
これは複数言語が入り交じったの家庭に生きる大人にも当てはまるのでしょうか?私はこの大人が”諦めなければ”という条件付きで可能な説だと思います。
がんばれ大人です。
これは複数言語が入り交じったの家庭に生きる大人にも当てはまるのでしょうか?私はこの大人が”諦めなければ”という条件付きで可能な説だと思います。
がんばれ大人です。
Friday, 13 July 2012
モデルとコントローラーのバランス
Skinny controller, fat modelというようにコントローラはできるだけ小さくするのがMVCの良いプラクティスなようです。
コントローラは「何を」するのか知っているが、「どうやって」それをするのか知らない状態が一つの目安。
コントローラは「何を」するのか知っているが、「どうやって」それをするのか知らない状態が一つの目安。
Thursday, 12 July 2012
BDDのコアコンセプトは?
BDDのメソッドは何となく面白いので使ってみたいと思うのですが、その基本となるコンセプトは何か私なりにまとめてみました。
上のメモのように、つまりユーザー(もしくはオブジェクトなど)のリクエストというbehaviourが発生した時にソフトウェア(API、オブジェクトなど何でも) がどのようなレスポンスを返すかということに集中して開発をするということだと理解しました。
データベースのリレーションや、ソフトウェアのロジックは後回しにして、これをするとこういう動きが返ってくるべきだという地点から全てを開始するということですね。
上のメモのように、つまりユーザー(もしくはオブジェクトなど)のリクエストというbehaviourが発生した時にソフトウェア(API、オブジェクトなど何でも) がどのようなレスポンスを返すかということに集中して開発をするということだと理解しました。
データベースのリレーションや、ソフトウェアのロジックは後回しにして、これをするとこういう動きが返ってくるべきだという地点から全てを開始するということですね。
Tuesday, 10 July 2012
Ruby " と ' の違い
特に "(ダブルクオート) と ' (シングルクオート)の違いを意識せずに使用してきたのですが、本当は " と ' はどう違うのか?と今更調べたのですが、さっと出てきた結果では ' で囲った文字列の特殊文字は解析されないということです。例えば
name = "Sam"
として、
puts "Hi #{name}!"
では
Hi Sam!
と出力されるのに対して、
puts 'Hi #{name}!'
では
Hi #{name}!
と出力されます。
もしくは
puts "a \n b \n c"
では改行が入り、
puts 'a \n b \n c'
だと
a \n b \n c
と表示されます。
ユーザに表示させる文字列には " を使い、そうでないのは ' を基本的に使う方が便利かな???というところですね。
name = "Sam"
として、
puts "Hi #{name}!"
では
Hi Sam!
と出力されるのに対して、
puts 'Hi #{name}!'
では
Hi #{name}!
と出力されます。
もしくは
puts "a \n b \n c"
では改行が入り、
puts 'a \n b \n c'
だと
a \n b \n c
と表示されます。
ユーザに表示させる文字列には " を使い、そうでないのは ' を基本的に使う方が便利かな???というところですね。
Monday, 2 July 2012
失敗しないと半人前?
以前にインド人両親を持った香港育ちの知り合いが、香港ではビジネスに失敗したことが無い人は半人前に見做されるという話をしていました。この人たちはタフだなと思いました。
先日DNS移行の失敗でクライエント側でメールを2営業日使用できなくなるという失敗をしました。メールに対する影響のことが念頭に無く、ドメインを管理するDNS自体を移行してしまったことが原因です。メールが届かなくなったという報せを受けて調査をし、DNSの問題だということに気がつき慌てて元のDNSサーバにドメインの管理を戻してホスティングサーバのAレコードだけを書き換えて移行は完了しました。
クライエントの方には迷惑をかけましたが、コミュニケーションの問題があったことなど今回の問題の主因ではない問題も浮き彫りになりました。サイト運営の方針を転換する機会でもあると感じます。
仕事をしている身として、ミスをすることはロスをもたらすことになるので本来は起きない様にするのが第一です。しかし、ミスをしてそれを解決したことによる経験とコミュニケーションの改善というのは同時にとても貴重であることを感じました。
全てゼロに戻っても立ち直るさという割り切り、諦め、自信などが混沌とした様子です。
先日DNS移行の失敗でクライエント側でメールを2営業日使用できなくなるという失敗をしました。メールに対する影響のことが念頭に無く、ドメインを管理するDNS自体を移行してしまったことが原因です。メールが届かなくなったという報せを受けて調査をし、DNSの問題だということに気がつき慌てて元のDNSサーバにドメインの管理を戻してホスティングサーバのAレコードだけを書き換えて移行は完了しました。
クライエントの方には迷惑をかけましたが、コミュニケーションの問題があったことなど今回の問題の主因ではない問題も浮き彫りになりました。サイト運営の方針を転換する機会でもあると感じます。
仕事をしている身として、ミスをすることはロスをもたらすことになるので本来は起きない様にするのが第一です。しかし、ミスをしてそれを解決したことによる経験とコミュニケーションの改善というのは同時にとても貴重であることを感じました。
全てゼロに戻っても立ち直るさという割り切り、諦め、自信などが混沌とした様子です。
Saturday, 30 June 2012
Test Double について
TDD, BDDは使い慣れていない用語や普段使っている言語とは異なるソフトウェアサイエンスでの用法があるので、用語の理解が一つのハードルであると感じます。
この辺りはかなりソフトウェアエンジニアリングではなく、ソフトウェアサイエンスの領域に入ってくるんでしょうね。最近はビジネスに関連してソフトウェアエンジニアリングのアプリケーションばかりをしていますが、学生の頃にはサイエンスの方をしていたのが懐かしく感じます。
"Test Double"もその一つではないでしょうか?"Test Double" G. Meszarosという人が考えた言葉なそうです。本人の書いた記事にその内容が書かれています。是非オリジナルを当たってください。個人的に著者の言葉の使い方にはprecisionが欠けている箇所がある気がしますが。
Doubleというのは英語ではいわゆるそっくりさんのことですね。G. Meszarosの原文ではスタントマンを例にとってきています。上の図に表される様にG. Meszarosの定義では、Test DoubleにはTest Stub, Test Spy, Mock Object, Fake ObjectとDummy Objectが含まれます(このDummy Objectは正確にはTest Doubleには含まれないそうですが)。要は"Test Double"とはこれらの用語を総称した言葉ですね。
用語
SUT: System Under Test テスト対象のシステム
DOC: depended-on component 異存しているコンポーネント
indirect output: 公開APIでは見れないが、他のコンポーネントに送られているSUTからのアクション
以下、それぞれの意味というか使い方です。
- Test Stub: SUTから送られてくるメッセージを受け取るために使用。indirect outputを正常に受け取らないとSUTが正常に動作しないなどの場合に使用。
- Test Spy: SUTから送られてくるメッセージを受け取るために使用というのはTest Stubと同様だが、Test SpyはSUTから送られてきたindirect outputの内容を記録して、後でバリデーションに使用できるようにする。
- Mock Object: Test Spyと同様に使用。原著からは私はTest StubとTest Spyの違いが見つけられませんでした。
- Fake Object: 実際のDOCの疑似コンポーネント。実際のDOCと似た動きをするが、まだ実際のDOCが用意できていない時に使用する。また、実際のDOCではデータベースの読み込みに時間がかかりテストに適していないという場合には、Fake Objectのハッシュオブジェクトにデータを収納してテストに用いる。
- Dummy Object: SUTがパラメータにオブジェクトを必要とするときに渡すオブジェクト。中身の無いメソッドを実装したnull object 参照でも問題無い。Dummy Objectは原著では厳密にはTest Doubleではなく、Literal Value、Derived Value、Generated Valueに属するとされている。
この辺りはかなりソフトウェアエンジニアリングではなく、ソフトウェアサイエンスの領域に入ってくるんでしょうね。最近はビジネスに関連してソフトウェアエンジニアリングのアプリケーションばかりをしていますが、学生の頃にはサイエンスの方をしていたのが懐かしく感じます。
"Test Double"もその一つではないでしょうか?"Test Double" G. Meszarosという人が考えた言葉なそうです。本人の書いた記事にその内容が書かれています。是非オリジナルを当たってください。個人的に著者の言葉の使い方にはprecisionが欠けている箇所がある気がしますが。
Doubleというのは英語ではいわゆるそっくりさんのことですね。G. Meszarosの原文ではスタントマンを例にとってきています。上の図に表される様にG. Meszarosの定義では、Test DoubleにはTest Stub, Test Spy, Mock Object, Fake ObjectとDummy Objectが含まれます(このDummy Objectは正確にはTest Doubleには含まれないそうですが)。要は"Test Double"とはこれらの用語を総称した言葉ですね。
用語
SUT: System Under Test テスト対象のシステム
DOC: depended-on component 異存しているコンポーネント
indirect output: 公開APIでは見れないが、他のコンポーネントに送られているSUTからのアクション
以下、それぞれの意味というか使い方です。
- Test Stub: SUTから送られてくるメッセージを受け取るために使用。indirect outputを正常に受け取らないとSUTが正常に動作しないなどの場合に使用。
- Test Spy: SUTから送られてくるメッセージを受け取るために使用というのはTest Stubと同様だが、Test SpyはSUTから送られてきたindirect outputの内容を記録して、後でバリデーションに使用できるようにする。
- Mock Object: Test Spyと同様に使用。原著からは私はTest StubとTest Spyの違いが見つけられませんでした。
- Fake Object: 実際のDOCの疑似コンポーネント。実際のDOCと似た動きをするが、まだ実際のDOCが用意できていない時に使用する。また、実際のDOCではデータベースの読み込みに時間がかかりテストに適していないという場合には、Fake Objectのハッシュオブジェクトにデータを収納してテストに用いる。
- Dummy Object: SUTがパラメータにオブジェクトを必要とするときに渡すオブジェクト。中身の無いメソッドを実装したnull object 参照でも問題無い。Dummy Objectは原著では厳密にはTest Doubleではなく、Literal Value、Derived Value、Generated Valueに属するとされている。
Subscribe to:
Posts (Atom)