Issue #16150 has been updated by sawa (Tsuyoshi Sawada).


For methods that convert object to a string, we already have three:

* `to_s`
* `to_str`
* `inspect`

Adding yet another method (or a variant of an existing method) would make the picture too complicated. It might be a good time to reconsider the division of labor between the existing three methods.

It is suspicious whether the distinction between `to_s` vs. `to_str`, `to_h` vs. `to_hash`, `to_a` vs. `to_ary`, or `to_i` vs. `to_int` etc. is nowadays used in the way it was intended at the beginning. Note that, while the single splat `*` on an object implicitly calls the explicit `to_a`, the double splat `**` implicitly calls the implicit `to_hash`. Also note that there is no explicit counterpart for the implicit method `to_proc`, which is used as in `Symbol#to_proc`, `Method#to_proc`, `Hash#to_proc`, where the (missing) implicit counterpart should have been used.

Personally, I am not that sure why we need `to_str` just to show that an object is string-like. For example, we could have the argument of `Array#join` undergo `to_s` (with a fallback to `to_str`) instead of (just) `to_str`. I don't see any problem with that.

As an example of rearranging the division of labour, one method out of the three mentioned above could be used for creating a new string instance, and another method for referencing a cached representation.

But that is just an example. There may be other ways that can make more sense. The point is, we can perhaps make use of the existing methods rather than adding a new one.

----------------------------------------
Feature #16150: Add a way to request a frozen string from to_s
https://bugs.ruby-lang.org/issues/16150#change-81463

* Author: headius (Charles Nutter)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Much of the time when a user calls to_s, they are just looking for a simple string representation to display or to interpolate into another string. In my brief exploration, the result of to_s is rarely mutated directly.

It seems that we could save a lot of objects by providing a way to explicitly request a *frozen* string.

For purposes of discussion I will call this to_frozen_string, which is a terrible name.

This would reduce string allocations dramatically when applied to many common to_s calls:

* Symbol#to_frozen_string could always return the same cached String representation. This method is *heavily* used by almost all Ruby code that intermingles Symbols and Strings.
* nil, true, false, and any other singleton values in the system could similarly cache and return the same String object.
* The strings coming from core types could also be in the fstring cache and deduplicated as a result.
* User-provided to_s implementations could opt-in to caching and returning the same frozen String object when the author knows that the result will always be the same.

A few ideas for what to call this:

* `to_fstring` or `fstring` reflects internal the "fstring" cache but is perhaps not obvious for most users.
* `to_s(frozen: true)` is clean but there will be many cases when the kwargs hash doesn't get eliminated, making matters worse.
* `def to_s(frozen = false)` would be mostly free but may not be compatible with existing to_s params (like `Integer#to_s(radix)`

This idea was inspired by @schneems's talk at RubyConf Thailand, where he showed significant overhead in ActiveRecord from Symbol#to_s allocation.



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