Issue #15899 has been updated by edd314159 (Edd Morgan).

File 2269.diff added
File test.rb added
File test_mem.rb added

I'd like to add my +1 to this idea. Splitting a string by a substring (and only caring about the first result) is a use case I run into all the time. In fact, the example given by @kke of splitting a `Content-Type` HTTP header by the semicolon is the one I needed it for most recently.

It's true, `partition` and `rpartition` can absolutely achieve the same thing. But they have the side effect of returning (and, of course, allocating) extra String objects that are frequently discarded. This not only negatively impacts performance, but results in less readable code: we have to resort to the convention of prefixing the throwaway variable name with an underscore. This underscore is a convention agreed upon, informally, by humans to indicate the irrelevance of the variable, and I'm sure many Ruby programmers are unaware of the convention, or simply forget about it.

I have suggested an implementation in PR #2269 on Github: https://github.com/ruby/ruby/pull/2269

I also attach the following benchmark to show that when these new methods are used for this use case, performance is ~30% improved for splitting by a String (and moreso when splitting by Regex):

``` ruby
eddmorgan@eddbook ~/Projects/rubydev/build вк make run

../ruby/revision.h unchanged
./miniruby -I../ruby/lib -I. -I.ext/common   ../ruby/test.rb
                       user     system      total        real
String#before      0.182367   0.000587   0.182954 (  0.183625)
String#partition   0.303105   0.000877   0.303982 (  0.304961)
                       user     system      total        real
String#after       0.199295   0.000672   0.199967 (  0.200794)
String#partition   0.302300   0.001409   0.303709 (  0.305278)
```

----------------------------------------
Feature #15899: String#before and String#after
https://bugs.ruby-lang.org/issues/15899#change-79253

* Author: kke (Kimmo Lehto)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
There  seems to be no methods for getting a substring before or after a marker.

Too often I see and have to resort to variations of:

``` ruby
str[/(.+?);/, 1]
str.split(';').first
substr, _ = str.split(';', 2)
str.sub(/.*;/, '')
str[0...str.index(';')]
```

These create intermediate objects or/and are ugly.

The `String#delete_suffix` and `String#delete_prefix` do not accept regexps and thus only can be used if you first figure out the full prefix or suffix.

For this reason, I suggest something like:

``` ruby
> str = 'application/json; charset=utf-8'
> str.before(';')
=> "application/json"
> str.after(';')
=> " charset=utf-8"
```

What should happen if the marker isn't found? In my opinion, `before` should return the full string and `after` an empty string. 



---Files--------------------------------
test.rb (712 Bytes)
test_mem.rb (326 Bytes)
2269.diff (3.77 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>