ruby-dev (Japanese) list archive (unofficial mirror)
 help / color / mirror / Atom feed
From: naruse@airemix•jp
To: ruby-dev@ruby-lang.org
Subject: [ruby-dev:50467] [Ruby trunk Feature#14417] String#sub / String#gsub に『キーが Symbol の Hash』を渡せるようにする提案
Date: Sun, 04 Feb 2018 13:05:34 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-70157.20180204130532.9228138d789d548d@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-14417.20180129093502@ruby-lang.org

Issue #14417 has been updated by naruse (Yui NARUSE).


Hanmac (Hans Mackowiak) wrote:
> @duerst: what about my example where it does transform the keye internal for the given Hash?
> or is that a nono too?
> it might be possible to only do it if the given hash has non String key?

If the hash is called many times from gsub, those integers shold be converted as String before gsub.
Because such conversion needs object allocation many times, and cause many GC.

I think

```
h = {1 => "A", 2 => "B", 3 => "C", 4 => "D", 5 => "E"}
"12345".gsub(/\d/){ h[$&.to_i] }
```

is faster than such code.

----------------------------------------
Feature #14417: String#sub / String#gsub に『キーが Symbol の Hash』を渡せるようにする提案
https://bugs.ruby-lang.org/issues/14417#change-70157

* 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 = {
  '&': "&amp",
  '<': "&lt",
  '>': "&gt",
}

p "<Q&A>".gsub(/[&<>]/, hash)
# => "&ltQ&ampA&gt"
```

```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/

      parent reply	other threads:[~2018-02-04 13:05 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-14417.20180129093502@ruby-lang.org>
2018-01-29  9:35 ` [ruby-dev:50445] [Ruby trunk Feature#14417] String#sub / String#gsub に『キーが Symbol の Hash』を渡せるようにする提案 manga.osyo
2018-01-29  9:56 ` [ruby-dev:50446] " hanmac
2018-01-29  9:59 ` [ruby-dev:50447] [Ruby trunk Feature#14417][Feedback] " shyouhei
2018-01-29 10:51 ` [ruby-dev:50448] [Ruby trunk Feature#14417] " manga.osyo
2018-01-29 15:17 ` [ruby-dev:50449] " hanmac
2018-01-31 11:06 ` [ruby-dev:50454] " duerst
2018-01-31 11:17 ` [ruby-dev:50455] " hanmac
2018-02-04 13:05 ` naruse [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-70157.20180204130532.9228138d789d548d@ruby-lang.org \
    --to=ruby-dev@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).