Project

General

Profile

Actions

Feature #11575

closed

Blocks in ERB don't work as intended?

Added by rohitpaulk (Paul Kuruvilla) about 9 years ago. Updated over 7 years ago.

Status:
Rejected
Target version:
[ruby-core:<unknown>]

Description

I'm not sure if this is a problem with ERB, but here it goes -

require 'ERB'
require 'Erubis'

$results = []

def return_block(&block)
  result = block.call
  $results << result

  return result
end

erb_template = <<-ERB
  <% return_block { %>
    <% "This should be stored in $results, but not sent to output" %>
  <% } %>

  <% return_block { %>
    <%= "This should be stored in $results AND sent to output" %>
  <% } %>
ERB

puts "Result of Template is:"
puts "---------------------"

#puts Erubis::Eruby.new(erb_template).result
puts ERB.new(erb_template).result(binding)

puts "---------------------"

puts "First call to return_block: #{$results[0]}"
puts "Second call to return_block: #{$results[1]}"

I'd expect the output to be

Result of Template is:
---------------------

    This should be stored in $results AND sent to output
---------------------
First call to return_block: This should be stored in $results, but not sent to output
Second call to return_block:
    This should be stored in $results AND sent to output

And this is exactly what I get when using Erubis. When I use ERB, the output I get is -

Result of Template is:
---------------------





    This should be stored in $results AND sent to output

---------------------
First call to return_block:




    This should be stored in $results AND sent to output

Second call to return_block:




    This should be stored in $results AND sent to output

I'm checking this against older ruby versions too, will update with results.

Actions #1

Updated by rohitpaulk (Paul Kuruvilla) about 9 years ago

  • Subject changed from ERB doesn't work as intended? to Blocks in ERB don't work as intended?
Actions #2

Updated by rohitpaulk (Paul Kuruvilla) about 9 years ago

Tried on 1.8.7, same results. Is there a spec for eRuby somewhere that I can refer to?

Actions #3

Updated by nobu (Nobuyoshi Nakada) about 9 years ago

  • Status changed from Open to Third Party's Issue

ERB preserves white spaces even there is no <%= %> tags.
Seems an Erubis's issue.

Actions #4

Updated by rohitpaulk (Paul Kuruvilla) about 9 years ago

I'm sorry I didn't make myself clear. Whitespace isn't the issue here - look at what's in $results.

With Erubis:

First call to return_block: 
    This should be stored in $results, but not sent to output
Second call to return_block:
    This should be stored in $results AND sent to output

With ERB:

First call to return_block:
    This should be stored in $results AND sent to output

Second call to return_block:
    This should be stored in $results AND sent to output

(I've stripped whitespace to make the issue obvious).

Updated by nagachika (Tomoyuki Chikanaga) about 9 years ago

  • Status changed from Third Party's Issue to Assigned
  • Assignee set to seki (Masatoshi Seki)

Hello, Rohit.
Thank you for your report.

I don't know it's a bug or s spec, but I've found that the $results[0] and $results[1] is the same object.

$results[0].object_id = $results[1].object_id # => return true at the last line of sample code.

seki-san, how do you think?

Updated by nagachika (Tomoyuki Chikanaga) about 9 years ago

Anyway, you can take a workaround to dup block value like result = block.call.dup. Just for reference.

Updated by hsbt (Hiroshi SHIBATA) over 7 years ago

  • Assignee changed from seki (Masatoshi Seki) to k0kubun (Takashi Kokubun)
  • Target version set to 2.5

Updated by k0kubun (Takashi Kokubun) over 7 years ago

  • Tracker changed from Bug to Feature
  • Status changed from Assigned to Rejected

Whitespace isn't the issue here

That's wrong. Definitely whitespace matters. If you change to use a following template, you'll get an expected result and ERB and Erubis will work in the same way.

  <% return_block { %><% "This should be stored in $results, but not sent to output" %><% } %>
  <% return_block { %><%= "This should be stored in $results AND sent to output" %><% } %>

At least for me, this is not a bug but a feature request. I couldn't find any test that ensures the return value for the case that a part of template is captured by a block and it's called. You may be confused with ActionView's features available via yield.

And the original behavior you reported is caused by the fact that one String object is shared by all lines generated from ERB's "<%=". That's a very reasonable thing as both ERB and Erubis do.

It doesn't make sense to rely on the return value of internal code that touches temporal state of ERB. And a suggested template (embedding meaningless '<% "foo" %>') doesn't seem a reasonable real use case. As one of the ERB maintainers, I reject this proposal.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0