ActiveSupport::Inflector::Inflections#acronym が期待通りで無い件
ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'OAuth' end
ネームスペースがつくと期待通りの変換をしてくれない模様。
'OAuth'.underscore # => 'oauth' 'oauth'.camelize # => 'OAuth' 'Auth::OAuth'.underscore # => 'auth/o_auth' 'auth/oauth'.camelize # => 'Auth::OAuth'
ActiveSupport::Inflector#underscore の実装は以下の通り。
def underscore(camel_cased_word) word = camel_cased_word.to_s.dup word.gsub!('::', '/') word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" } word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2') word.gsub!(/([a-z\d])([A-Z])/,'\1_\2') word.tr!("-", "_") word.downcase! word end
問題は2個目のgsub!で使っている正規表現。acronym で指定した単語が指定文字列の先頭に登場するか、英数字に続いて登場するかしないとマッチしないため、スラッシュに続いて登場するケースでは対象外となってしまう。
ActiveSupport::Inflector.inflections.acronym_regex # => /OAuth/ 'OAuth'.gsub(/(?:([A-Za-z\d])|^)(#{ActiveSupport::Inflector.inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" } # => 'oauth' 'Auth/OAuth'.gsub(/(?:([A-Za-z\d])|^)(#{ActiveSupport::Inflector.inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" } # => 'Auth/OAuth' 'Auth/oOAuth'.gsub(/(?:([A-Za-z\d])|^)(#{ActiveSupport::Inflector.inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" } # => 'Auth/o_oauth'
これは、以前からこのような結果だっただろうか?