Jeremy Kemper wrote:
> On Fri, Mar 26, 2010 at 11:45 AM, Kurt  Stephens <redmine / ruby-lang.org> wrote:
>> Issue #889 has been updated by Kurt  Stephens.
>>
>>
>> This is not a good idea, because the expression value Strings accumulated in the Array must be protected from mutation.
>> ERB expressions can have side-effects.
>>
>> <pre>
>> SOME_STRING = 'foobar'
>> def foo
>>  SOME_STRING
>> end
>> def bar
>>  SOME_STRING.sub!(/bar/, '')
>>  SOME_STRING
>> end
>> # ERB GENERATED CODE: from "<%= foo %><%= bar %>"
>> eoutvar = [ ]
>> eoutvar << foo
>> eoutvar << bar
>> eoutvar.join('')
>> </pre>
> 
> I disagree. That's based on a loose assumption that <%= ... %> behaves
> like #{...}.
> 

String#<<(x) "appends by value", Array#<<(x) "appends by reference". 
The subsequent Array#join is affected by mutations to the argument, the 
former is not.  Ruby Strings are passed and returned by reference, not 
by value.

The proposal introduces aliasing problems that did not exist before.

IMO, it's counter-intuitive.  <%= ... %> currently behaves as if it's 
embedded in a stream, similarly "#{...}" interpolations are evaluated 
left-to-right.  String#<< and IO#<< have stream-like semantics and are 
immune to argument aliasing, Array#<< and the subsequent Array#join 
behave differently.

The example above would work differently, if IO === eoutvar, than if 
Array === eoutvar.  If we don't care about preserving semantics, then 
it's not an issue.

I'd prefer that <%= ... %> continues to behave like "#{...}", both
have implicit order-of-evaluation and are immune to aliasing.

KAS