From: manga.osyo@... Date: 2018-01-29T10:51:27+00:00 Subject: [ruby-dev:50448] [Ruby trunk Feature#14417] String#sub / String#gsub に『キーが Symbol の Hash』を渡せるようにする提案 Issue #14417 has been updated by osyo (manga osyo). Thanks for reply!!! > would it probably better if sub/gsub would call hash.transform_keys(&:to_s) internal in their code with the hash if hash is given? hmmmm... Thanks for idea :) > とはいえ機能自体に反対ではないですから、より具体的なユースケースがあると賛成しやすくなるかなと思います。 そうですねえ…もう少し具体的なユースケースを考えてみたいと思います。 コメントありがとうございます。 ---------------------------------------- Feature #14417: String#sub / String#gsub に『キーが Symbol の Hash』を渡せるようにする提案 https://bugs.ruby-lang.org/issues/14417#change-69967 * Author: osyo (manga osyo) * Status: Feedback * Priority: Normal * Assignee: * Target version: ---------------------------------------- ## 概要 `String#sub` / `String#gsub` に『キーが `Symbol` の `Hash`』を渡した場合でも `String` の場合と同様に置き換える。 ## 現行の動作 ```ruby hash = {'b'=>'B', 'c'=>'C'} p "abcabc".gsub(/[bc]/, hash) #=> "aBCaBC" # キー が Symbol の Hash は置き換えられない hash = { b: 'B', c: 'C' } p "abcabc".gsub(/[bc]/, hash) #=> "aa" # キー が Symbol の Hash は String に変換する必要がある p "abcabc".gsub(/[bc]/, hash.transform_keys(&:to_s)) #=> "aBCaBC" ``` ## 提案する動作 ```ruby # キーが String の場合は現行維持 hash = {'b'=>'B', 'c'=>'C'} p "abcabc".gsub(/[bc]/, hash) #=> "aBCaBC" hash = { b: 'B', c: 'C' } # $& は動的であるべきなので String のまま p "abcabc".gsub(/[bc]/){hash[$&]} #=> "aa" # ブロックの引数は動的であるべきなので String のまま p "abcabc".gsub(/[bc]/){ |s| hash[s] } #=> a" # Hash を直接渡した場合のみキーが Symbol でも許容する p "abcabc".gsub(/[bc]/, hash) #=> "aBCaBC" ``` ## 利点 * キーを Symbol で書くことを推奨しているコーディング規約がある * [ruby-style-guide/README.ja.md at japanese · fortissimo1997/ruby-style-guide · GitHub](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md#symbols-as-keys) * キーを Symbol で定義する方が Hash を書いていて気持ちがいい ## 課題 * `String` と `Symbol` の両方のキーがあった場合どうするか * `"abcabc".sub(/[bc]/, { "b" => "A", b: "C" }) # => ???` * 現状は `String` を優先している * それ以前に `String` と `Symbol` が混ざっている Hash はおかしいのではないだろうか * 警告を出すとか? ## `String#gsub` のユースケースなど ```ruby # http://batsov.com/articles/2013/10/03/using-rubys-gsub-with-a-hash/ def geekify(string) string.gsub(/[leto]/, l: '1', e: '3', t: '7', o: '0') end p geekify('leet') # => '1337' p geekify('noob') # => 'n00b' def doctorize(string) string.gsub(/M(iste)?r/, Mister: 'Doctor', Mr: 'Dr') end p doctorize('Mister Freeze') # => 'Doctor Freeze' p doctorize('Mr Smith') # => 'Dr Smith' ``` ```ruby # https://coderwall.com/p/t4y7cw/ruby-gsub-with-a-hash-or-block amino_acid_hash = { A: 'Ala', R: 'Arg', N: 'Asn' } p "R232A".gsub(/[A-Z]/, amino_acid_hash) # => "Arg232Ala" ``` ```ruby # https://qiita.com/scivola/items/416155c307ec29a37b8f hash = { '&': "&", '<': "<", '>': ">", } p "<Q&A>".gsub(/[&<>]/, hash) # => "<Q&A>" ``` ```ruby # https://qiita.com/pocari/items/34855a9b07ea5006fe80 hash = { '#to#': "taro", '#from#': "jiro", } template = <<EOS hello, #to#. message from #from#. EOS puts template.gsub(/#.*#/, hash) # => hello, taro. # message from jiro. ``` その他、具体的なユースケースを思いついた方がいればコメントいただけると助かります。 ---Files-------------------------------- string_sub_with_symbol_key.patch (2.71 KB) -- https://bugs.ruby-lang.org/