[ruby-core:126356] [Ruby Feature#22238] String#tr to take a Hash for multi-character replacements
Issue #22238 has been reported by byroot (Jean Boussier). ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
Issue #22238 has been updated by luke-gru (Luke Gruber). Status changed from Closed to Open The commit in the previous message has the wrong Issue ID, it is unrelated. ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238#change-118506 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
Issue #22238 has been updated by sowieso (So Wieso). Can you explain what ```ruby "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` is supposed to do? I can't wrap my head around this code. ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238#change-118527 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
Issue #22238 has been updated by byroot (Jean Boussier). It's a per character replacement: ```ruby hash = { "e" => "€", "l" => "EL", "o" => "Ø" } str = "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent puts str ``` ``` H€ELELØ ``` ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238#change-118528 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
Issue #22238 has been updated by sowieso (So Wieso). Ah, of course. Thank you! I thought `hash` was `Kernel#hash`🤦 ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238#change-118529 * Author: byroot (Jean Boussier) * Status: Open ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
Issue #22238 has been updated by matz (Yukihiro Matsumoto). Status changed from Closed to Open Assignee set to byroot (Jean Boussier) Reopened. I am satisfied with the spec, but the current implementation (master 3742091) has bugs. ```ruby "hello".tr("x" => "y") #=> nil (should be "hello") "hello".tr({}) #=> nil (should be "hello") s = +"hello" s.tr!("x" => "y") #=> nil s #=> "" (the receiver is emptied) "0123456789abcdefghij".tr("h" => "H", "2" => "@") #=> "0123456789abcdefgHij" ("2" is not replaced) ``` * When nothing is replaced, `tr` returns `nil`, and `tr!` empties the receiver. The spec for `tr!` only checks the return value, so it passes. * On strings of 16 bytes or longer, the SIMD search only finds the first key. The loop that merges the matches of other keys starts with `for (i = i; ...)` and never runs. With more than 16 keys, the SSE2 version finds nothing. Also: * The call-seq and document of `tr` do not mention the Hash form. * A broken string raises `ArgumentError` in non-fastpath encodings, but not in UTF-8/US-ASCII/BINARY. It should be consistent (the 2-argument form raises). Please add tests for these cases as well. Matz. ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238#change-118908 * Author: byroot (Jean Boussier) * Status: Open * Assignee: byroot (Jean Boussier) ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
Issue #22238 has been updated by byroot (Jean Boussier). Thanks for catching that. I believe I addressed all points. ---------------------------------------- Feature #22238: String#tr to take a Hash for multi-character replacements https://bugs.ruby-lang.org/issues/22238#change-118953 * Author: byroot (Jean Boussier) * Status: Closed * Assignee: byroot (Jean Boussier) ---------------------------------------- This is @matz's counter proposal to [Feature #22229] from the last dev-meeting
matz: I will counter-propose String#tr-with-hash style.
```ruby 'Hello </script>'.tr(">" => '\u003e', "<" => '\u003c', "&" => '\u0026') # matz: OK 'Hello </script>'.tr("abc" => 'ABC') # should raise an exception 'Hello </script>'.tr("abc" => 'ABC', "ab" => "XY") # should raise an exception "fée".tr("é" => "€") # it should work "Hello".tr("l" => "ABC", "o" => "XYZ") #=> "HeABCABCXYZ" "Hello".gsub(/./m) { hash[$&] || $& } # gsub equivalent ``` Notes: - Hash keys MUST be single characters (but can be multi-byte). - Values can be multiple characters. -- https://bugs.ruby-lang.org/
participants (4)
-
byroot (Jean Boussier) -
luke-gru (Luke Gruber) -
matz (Yukihiro Matsumoto) -
sowieso (So Wieso)