ActiveSupportのマイナーだけど 便利なメソッド
先日勤務先の株式会社 iCARE の DevMeetup #14 にて、
「ActiveSupportのマイナーだけど 便利なメソッド」というタイトルでLTしました。
ありがたいことにTwitterで実況していただき、
のようなリアクションをしていただきました。ありがとうございます🙏
このエントリではスライドでは紹介できなかった実際のコードをいくつか紹介したいと思います。
in?
def in?(another_object)
another_object.include?(self)
rescue NoMethodError
raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
end
レシーバと引数を逆にして include?
を使っているだけ。とてもシンプルですね。
こういうちょっとしたコードでもより楽しくかけるようになるということがわかります。
ordinalize
1だったら1st、3だったら3rdなどの文字(序数文字列)を付与できるメソッドです。
> 1.ordinalize
=> "1st"
> 3.ordinalize
=> "3rd"
> 13.ordinalize
=> "13th"
この実装はどうなっているかというと
def ordinal(number)
I18n.translate("number.nth.ordinals", number: number)
end
def ordinalize(number)
I18n.translate("number.nth.ordinalized", number: number)
end
I18n.translate
を実行しています。意外。
それはどうやっているかというと
# frozen_string_literal: true
{
en: {
number: {
nth: {
ordinals: lambda do |_key, options|
number = options[:number]
case number
when 1; "st"
when 2; "nd"
when 3; "rd"
when 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; "th"
else
num_modulo = number.to_i.abs % 100
num_modulo %= 10 if num_modulo > 13
case num_modulo
when 1; "st"
when 2; "nd"
when 3; "rd"
else "th"
end
end
end,
ordinalized: lambda do |_key, options|
number = options[:number]
"#{number}#{ActiveSupport::Inflector.ordinal(number)}"
end
}
}
}
}
なんとロケールで lambda を使っています。こういうことができるとは知りませんでした。
このようにソースコードを読むことで新たな気付きも得られます。
ぜひ ActiveSupport のソースコードを覗いてみてください!