Feature #14624
open#{nil} allocates a fresh empty string each time
Description
This causes a bunch of unnecessary string allocations in the following scenario: "#{'rails' unless boolean_condition} is great"
. Each time this line is called when boolean_condition
is true, it evaluates to nil
and when nil
is interpolated into a string it allocates an empty string. Ideally, the behavior of nil.to_s
would reference a frozen empty string that wouldn't need to be reallocated each time.
Updated by Hanmac (Hans Mackowiak) over 6 years ago
i have a problem with that, what if someone might do:
x = obj.to_s
x << obj2.to_s
then it might be nil
, return a frozen string and it would do a RuntimeError
better imo would be that if "#{nil}"
would do a check if to_s
is overwritten or redefined and if not do other magic
Updated by bumblingbear (Dillon Welch) over 6 years ago
That sounds fine to me!
Hanmac (Hans Mackowiak) wrote:
i have a problem with that, what if someone might do:
x = obj.to_s x << obj2.to_s
then it might be nil, return a frozen string and it would do a
RuntimeError
better imo would be that if
"#{nil}"
would do a check ifto_s
is overwritten or redefined and if not do other magic
Updated by phluid61 (Matthew Kerwin) over 6 years ago
I'm confused; are you proposing that nil.to_s
returns the same String object every time, or that string interpolation detects a nil
object and optimises it?
A lot of times I rely on "#{foo}"
returning a new String object that contains a copy of the #to_s of foo
, so it seems to me like spec that "#{nil}"
returns a new empty string every time.
Updated by bumblingbear (Dillon Welch) over 6 years ago
Closer to the string interpolation optimization part. The problem with "#{nil}"
is that it allocates two empty strings each time. I feel like it would be possible to do this with zero/one allocation. I don't know what the underlying code looks like, but the logic I'm thinking of is something like
def interpolate(obj)
if obj == nil
''
else
obj.to_s # assuming this is current behavior
end
end
phluid61 (Matthew Kerwin) wrote:
I'm confused; are you proposing that
nil.to_s
returns the same String object every time, or that string interpolation detects anil
object and optimises it?A lot of times I rely on
"#{foo}"
returning a new String object that contains a copy of the #to_s offoo
, so it seems to me like spec that"#{nil}"
returns a new empty string every time.
Updated by nobu (Nobuyoshi Nakada) over 6 years ago
- Tracker changed from Bug to Feature
- Description updated (diff)
- Backport deleted (
2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN)
Updated by normalperson (Eric Wong) over 6 years ago
nobu@ruby-lang.org wrote:
Btw, I also had [ruby-core:81905] [Feature #13715] from last
year but forgot about it :x