I wanted to do a little regex testing using irb with a HTML page I'm trying to gsub something off of.
However, the HEREDOC syntax we all know and love seems to be different in Ruby:
irb(main):140:0> text = <<-FUNUNU <p class="firstpara">
irb(main):141:0" FUNUNU
irb(main):142:0*
irb(main):143:0* puts text
SyntaxError: compile error
(irb):140: syntax error, unexpected kCLASS, expecting kDO or '{' or '('
text = <<-FUNUNU <p class="firstpara">
^
(irb):143: syntax error, unexpected tIDENTIFIER, expecting kDO or '{' or '('
from (irb):143
from :0
It seems to complain about the contents of the string, trying to interpret it. From all the documentation I could find on the HEREDOC syntax, all point out that everything between the keywords should be part of the variable. But it doesn't seem so.
Are there formatting restrictions about the contents of the string, other than that the HEREDOC string ends with the 2nd expression of the HEREDOC indicator?
You can't put the string on the same line of the heredoc delimiter, because after the delimiter, on the same line, it is allowed to put Ruby code, i.e.
irb> text = <<-FOO # Ruby code allowed here...
irb* <a class="foo">
irb* FOO
# => "<a class=\"foo\">\n"
irb> text
# => "<a class=\"foo\">\n"
This is because you can write something like this:
irb> instance_eval(<<-CODE)
irb* def foo
irb* "foo"
irb* end
irb* CODE
Or even:
def foo(a, b, c)
[a, b, c]
end
foo(<<-A, <<-B, <<-C)
foo
A
bar
B
baz
C
# => ["foo\n", "bar\n", "baz\n"]
As has been pointed out, the heredoc text begins on the next line after the heredoc terminator. This is not meant to replace those answers but rather provide a possibly better alternative to the typical heredoc syntax.
I personally prefer to use %q{}
. It equates to using single quotes. The following give the same output:
text = %q{ <a class="foo"> }
text = ' <a class="foo"> '
If you would like to use string interpolation:
text = %Q{ <a class="#{class_name}">}
You can also switch out the {}
for other terminators. The following two lines give exactly the same output:
text = %Q[ <a class="#{class_name}">]
text = %Q| <a class="#{class_name}">|
And they support multiple lines:
text = %q{<p>
Some text
</p>}
There are some good answers on this SO question in reference to different uses for this syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With