ActiveSupport::OrderedOptionsを使ってHashで.(ドット)を使えるようにする٩( ‘ω’ )و
もはやActiveSupportなしでは生きていけない僕
Hashをイイ感じに拡張してるActiveSupport::OrderedOptionsです
# activesupport/lib/active_support/ordered_options.rb module ActiveSupport class OrderedOptions < Hash ... end end
普通のHashだとこんな感じ
hash = {} hash[:name] = 'murajun1978' hash[:name] #=> 'murajun1978'
ActiveSupport::OrderedOptionsを使うとこうなる
hash = ActiveSupport::OrderedOptions.new hash.name = 'murajun1978' hash.name #=> 'murajun1978' hash[:name] #=> 'murajun1978'
.(ドット)でvalueを取得できるようになりましたーヾ( ̄∇ ̄=ノ
チェインしたいときはこんなかんじ
hash = ActiveSupport::OrderedOptions.new hash.user = ActiveSupport::OrderedOptions.new hash.user.name = 'murajun1978' hash.user.name #=> 'murajun1978'
既存のHashを使いたいときはActiveSupport:: InheritableOptionsを使う
hash = ActiveSupport:: InheritableOptions.new({name: 'murajun1978'}) hash.name #=> 'murajun1978'
I18nのconfigを定義するとこで使われてるねー
module I18n class Railtie < Rails::Railtie config.i18n = ActiveSupport::OrderedOptions.new config.i18n.railties_load_path = [] config.i18n.load_path = [] config.i18n.fallbacks = ActiveSupport::OrderedOptions.new ... end end
次はThreadについて書くよてい(多分、明日の神戸.rb Meetup #15で)
Happy Hacking٩( ‘ω’ )و
Array#extract_options!で引数からオプションをひっこぬく٩( ‘ω’ )و
Railsでのvalidationを設定する時はこう書きますよね?
validates :name, :kana, presence: true
validatesメソッドに、symbolとhashが複数指定されています
オプション部分はHashですねー
引数とオプション(Hash)を分離したいときに大活躍するのがArray#extract_options!です
extract_options!のコードを見てみましょう
# activesupport/lib/active_support/core_ext/array/extract_options.rb class Array def extract_options! if last.is_a?(Hash) && last.extractable_options? pop else {} end end end
last.is_a?(Hash) && last.extractable_options?
で配列の末尾のオブジェクトがHashかチェックしてます
HashだったらpopメソッドでHashを引っこ抜いてます
Hashでなかったら空のHashを返してます
Railsコンソールで確認してみましょう
args = [:name, :kana, {presence: true}] options = args.extract_options! args #=> [:name, :kana] options #=> {:presence=>true}
おおー、引数とoption(Hash)を分離できましたヾ( ̄∇ ̄=ノ
validatesのコードはこんなかんじ( ˘ω˘)
# activemodel/lib/active_model/validations/validates.rb def validates(*attributes) defaults = attributes.extract_options!.dup [...] end
extract_options!のコードを見ればわかりますが、Hashは末尾に指定しないとダメなので気を付けよう
[:name, {presence: true}, :kana].extract_options! #=> {}
Happy Hacking٩( ‘ω’ )و
Enumerable#partitionでブロックの評価が真と偽の要素に分ける٩( ‘ω’ )و
いままでブロックで評価して真のものはselectで、それ以外はrejectとか2回やってた...
でも、これ1回でできたらおしゃれですよねー
そんなときはEnumerable#partition
こんなかんじ( ˘ω˘)
array = ["cat", 1, 2, "dog", 0.1] numbers, non_numbers = array.partition { |v| v.is_a?(Numeric) } numbers #=> [1, 2, 0.1] non_numbers #=> ["cat", "dog"]
Happy Hacking٩( ‘ω’ )و
Adequate Recordでキャッシュされないケースヘ(^o^)ノ
第65回 Ruby関西 勉強会に参加したよヘ(^o^)ノのつづき
スライドに、Adequate Recordでキャッシュされないケースを書いたけど、 ざっくりしすぎなのでまとめてみる( ˘ω˘)
find_byを例にactiverecordのコードを読みながら確認していく
コードはこんな感じ(コメントの*1
とかは説明しやすいのでつけてるだけ)
# activerecord/lib/active_record/core.rb def find_by(*args) # :nodoc: # *1 return super if current_scope || !(Hash === args.first) || reflect_on_all_aggregations.any? # *2 return super if default_scopes.any? hash = args.first # *3 return super if hash.values.any? { |v| v.nil? || Array === v || Hash === v } # We can't cache Post.find_by(author: david) ...yet # *4 return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) } ... end
*1
で判定していること
current_scopeがある
current_scope
でスコープがないことを確認してる
引数がHash以外
!(Hash === args.first)
でチェックしてる
こんなのはキャッシュしてくれない
Post.find_by('created_at < ?', 1.weeks.ago)
composed_ofが設定されている
reflect_on_all_aggregations.any?
でチェックしてる
設定されているだけでキャッシュしてくれない
*2
で判定してること
default_scopeが設定されている
設定されているだけでキャッシュしてくれない
*3
で判定していること
引数のハッシュ値(Value)がnil
, Array
,Hash
こんなのはキャッシュしない
Post.find_by(title: nil) Post.find_by(title: ['ruby', 'rails']) # Hashがくるケースが思い浮かばない...
*4
で判定していること
Hashのキーにモデルのカラム以外が指定されている
以上の条件に当てはまる場合に、super
すなわち本家のfind_by
をよんでます
なので、単一テーブル継承(STI)やPolymorphicは、設定されているだけではキャッシュの対象外とはなりません
ここがややこしそうだ。。。
間違えてたら教えてくださいねー
Happy Hacking٩( ‘ω’ )و
神戸.rb Meetup #13に参加したよヘ(^o^)ノ
神戸.rb Meetup #13に参加しましたー
毎回思うがホント勉強になる
僕の思いもみんなに伝えられたし良かった
今日はActiveSupport::StringInquirerについて調べた
結構こんなの書いちゃいがちですよね?
if Rails.env == 'production' ... end
それが、こう書ける
if Rails.env.production? ... end
これを使ってこんなの実装してみた
priority_typeってフィールドがあって、'low'や'high'なんかの文字列がセットされてるとする
class Task < ActiveRecord::Base def priority priority_type.inquiry end end
lowかどうかチェックしてみる
task.priority_type #=> "low" task.priority.low? #=> true task.priority.middle? #=> false
==で判定するよりグッと意図が伝わりやすくなってると思う(多分...
Happy Hacking٩( ‘ω’ )و
RubyのHashで要素数を取得するヘ(^o^)ノ
Hashで要素の数を取得してみる
Hash#lengthとHash#size
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.length #=> 3 favorites_language.size #=> 3
Enumerable#count
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.count #=> 3
では、Valueが'Ruby'である要素の数を取得してみる
Hash#lengthとHash#size
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.select{|k, v| v == 'Ruby'}.size #=> 2
Enumerable#count{|obj| ...}
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.count{|key, v| v == 'Ruby'} #=> 2
そう!countにはブロックを渡せるのだー(今までマジで知らんかった...
もう少しおしゃれにしてみよう
Enumerable#count(item)
favorites_language = { bob: 'Ruby', jone: 'Ruby', tiger: 'Perl' } favorites_language.values.count('Ruby') #=> 2
まだまだ知らんこといっぱいですわー
がんばろっと
Happy Hacking٩( ‘ω’ )و
第65回 Ruby関西 勉強会に参加したよヘ(^o^)ノ
第65回 Ruby関西 勉強会に参加し、発表してきました。
発表内容はRails4.2の新機能について。
4.2がリリースされてから2ヶ月が経ちますが、ActiveJob中心に紹介させてもらいました。
発表中にデモする時があると思います
スライド見ながらタイプするの大変ですよねー( ̄▽ ̄;)
そんな時はtmuxですよ!
- tmuxを起動
- 新しいターミナルから、起動済みtmuxへアクセス
$ tmux attach -t 0
- 普通に操作する
これで発表中のデモも楽ちんですねーヘ(^o^)ノ
Happy Hacking٩( ‘ω’ )و
みなさんの発表内容
Ruby 2.0 以降の変更をふりかえる
RubyでBCCWJを弄ぶ
@pico1aさん
Wakayama.rbボードの紹介
Rubyコミュニティx企業
Medaka.rb活動概要
Gemをコードリーディングしてみよう!
@taiyopさん
Railsの見える化 開発(API編)
@ogomさん
Treasure DataでのRubyの利用
追記
- 2014/02/27 @takamiya_amsさんのスライド追加