2011-05-31
■[perl] ハッシュの値を宣言と同時に参照する方法
ruby だと以下のように書くのをperlでどう書けばいいのか。。
# ruby # 無名ハッシュ(という呼び方でいいかわからないけど)を作成と同時に値を引っ張る {:k1 => 'v1', :k2 => 'v2'}[:k2] # ==> "v2"
一応、こんな感じで書けたけど、リファレンスにせずに引っ張る方法はわからず。。
# perl {k1 => 'v1', k2 => 'v2'}->{k2} # ==> "v2" (k1 => 'v1', k2 => 'v2'){k2} # syntax error...
# ruby # 無名配列を作成と同時に値を引っ張る %w[one two three][1] # ==> "two"
# perl qw(one two three)[1] # ==> "two"
2011-02-25
■[rails] image_tagで付加される画像のタイムスタンプを、production環境でも画像ファイルが更新されたタイミングで更新されるようにする
image_tagで画像を表示した際に、srcの後ろに付くタイムスタンプは
基本的には File.mtime(image_path) なので、画像ファイルの最終更新時刻です。
image_tag 'rails.png' #=> <img src="/images/rails.png?1298610241" alt="Rails" />
なので、developement環境では画像ファイルをtouchしてあげたりすると、タイムスタンプも更新されます。
しかし、production環境ではtouchしても更新されません。(passengerなり、サーバをリスタートすれば更新されます)
なぜこうなるかは、ActionView::Helpers::AssetTagHelper の rails_asset_id メソッドを見るとわかります。
# File actionpack/lib/action_view/helpers/asset_tag_helper.rb def rails_asset_id(source) if asset_id = ENV["RAILS_ASSET_ID"] asset_id else if @@cache_asset_timestamps && (asset_id = @@asset_timestamps_cache[source]) asset_id else path = File.join(ASSETS_DIR, source) asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : '' if @@cache_asset_timestamps @@asset_timestamps_cache_guard.synchronize do @@asset_timestamps_cache[source] = asset_id end end asset_id end end end
最初1回は、File.mtime(path) をちゃんと取ってくれるのですが、
その際に、@@asset_timestamps_cache[source] = asset_id で、キャッシュして、
以降は、そのキャッシュが使われます。
で、@@cache_asset_timestamps が何かを見ると
# File actionpack/lib/action_view/helpers/asset_tag_helper.rb def self.cache_asset_timestamps @@cache_asset_timestamps end # You can enable or disable the asset tag timestamps cache. # With the cache enabled, the asset tag helper methods will make fewer # expense file system calls. However this prevents you from modifying # any asset files while the server is running. # # ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false def self.cache_asset_timestamps=(value) @@cache_asset_timestamps = value end @@cache_asset_timestamps = true
booleanの値です。
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false すれば、
毎回 File.mtime(path) してくれるようになります。
なので、initializersとかに、適当なファイルを作って、
# config/intializers/cache_asset_timestamp.rb とか ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
だけ書いておけば、production環境でもtouchしたらタイムスタンプが更新されるようになります。
ちなみに、development環境は、config/environments/development.rb で
config.cache_classes = false
になってると思いますが、cache_classesがfalseだと、
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
2011-02-17
■[rails] jpmobileを使って、au/softbankでも、controller内で、ドコモ絵文字にマッピング済みのutf8値を得る方法
ユーザがテキストフォームに絵文字を入れて送ってきたときの話しです。
以下のようなコードがあった際に、
class HogeController < ApplicationController mobile_filter def hoge # 例えば、ドコモの「晴れ」に対応する絵文字は、jpmobileの # before_filterを通った、actionの時点で、 # docomo : \xEE\x98\xBE # au : \xEE\x92\x88 # softbank : \xEF\x81\x8A # となっている end end
そのままhogeアクションのviewで表示するなら、jpmobileのafter_filterがかかって、
docomo : \xF8\x9F (sjis) au : \xF8\x9F (sjis) softbank : \xEE\x98\xBE (utf8)
になるのですが、hogeアクションの中で、au/softbankでもdocomoの値を手に入れるにはどうしたらよいでしょうか。
一応、下記の方法で手に入れることが出来たので、メモっておきます。
class HogeController < ApplicationController mobile_filter def hoge # strが変換したい文字列とすると str = Jpmobile::Emoticon::utf8_to_unicodecr(str) str = Jpmobile::Emoticon::unicodecr_to_external(str, Jpmobile::Emoticon::CONVERSION_TABLE_TO_DOCOMO, false) # これで strは # docomo : \xEE\x98\xBE # au : \xEE\x98\xBE # softbank : \xEE\x98\xBE # となります end end
単純に、jpmobileのafter_filterをかけているだけですが、
unicodecr_to_externalの3つ目の引数をfalseにしてutf8-->sjis変換を行なわないようにしています
2010-12-13
■[rails] 主キー(primary key)の id を任意に指定して、createする
# ruby script/console # 普通に指定しても無視される >> User.create(:id => 100) => #<User id: 1, created_at: "2010-12-13 02:47:03", updated_at: "2010-12-13 02:47:03"> # ブロックで指定すると >> User.create do |u| ?> u.id = 100 >> end => #<User id: 100, created_at: "2010-12-13 02:48:22", updated_at: "2010-12-13 02:48:22">
使う機会は・・・orz
2010-11-25
■[rails] sqlite3-ruby の version が 1.2.x だと、select AS で名前を指定したときに integer 型のカラムのはずが string 型で取れてくる件
sqlite3-ruby : version 1.2.5
$ rails testapp1 $ cd testapp1 $ ruby script/generate model user $ rake db:migrate $ ruby script/console >> User.create => #<User id: 1, created_at: "2010-11-25 08:49:43", updated_at: "2010-11-25 08:49:43"> >> User.first.id.class => Fixnum >> User.find(:first, :select => "id AS user_id").user_id.class => String # あらら
sqlite3-ruby : version 1.3.0
$ rails testapp2 $ cd testapp2 $ ruby script/generate model user $ rake db:migrate $ ruby script/console >> User.create => #<User id: 1, created_at: "2010-11-25 08:57:44", updated_at: "2010-11-25 08:57:44"> >> User.first.id.class => Fixnum >> User.find(:first, :select => "id AS user_id").user_id.class => Fixnum # OK
まぁ findで:selectを使うことがそうないし、ましてAS使うこととかほぼないですが。
ちなみに rails は 2.3.10