<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Multiline Strings in Ruby 2.3 the Squiggly Heredoc | Infinum</title>
		<atom:link href="https://infinum.com/blog/multiline-strings-ruby-2-3-0-the-squiggly-heredoc/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/multiline-strings-ruby-2-3-0-the-squiggly-heredoc/</link>
		<description>Building digital products</description>
		<lastBuildDate>Thu, 16 Apr 2026 07:26:45 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7952https://infinum.com/uploads/2017/02/multiline-strings-ruby-2-3-0-the-squiggly-heredoc-0.webp</url>
				</image>
				<title>Multiline Strings in Ruby 2.3  the Squiggly Heredoc</title>
				<link>https://infinum.com/blog/multiline-strings-ruby-2-3-0-the-squiggly-heredoc/</link>
				<pubDate>Tue, 22 Dec 2015 11:00:00 +0000</pubDate>
				<dc:creator>Damir Svrtan</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc/</guid>
				<description>
					<![CDATA[<p>Did you ever have to write a nicely indented multiline string in Ruby? There was no out-of-the-box solution until the squiggly heredoc was introduced.</p>
<p>The post <a href="https://infinum.com/blog/multiline-strings-ruby-2-3-0-the-squiggly-heredoc/">Multiline Strings in Ruby 2.3  the Squiggly Heredoc</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-146"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	Have you ever had to write a <strong>nicely indented multiline string</strong> in Ruby? If you have, you already know that Ruby <strong>doesn’t have a nice out-of-the-box solution</strong> for this problem. At least it hadn’t until a week ago when the squiggly heredoc was introduced…</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	To be honest, I actually rarely need to use multiline strings, but when I do, it <strong>really gets on my nerves</strong> that <a href="https://infinum.com/blog/becoming-a-ruby-on-rails-developer/">Ruby</a> lacks an upfront way to do them. Every time I need to write a multiline string, I google it and hope that someone has found a way to write it without performing ugly ‘hacks’ that can be found in this <a href="http://stackoverflow.com/questions/2337510/ruby-can-i-write-multi-line-string-with-no-concatenation">Stack Overflow post</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	The first thing that comes to mind when doing multiline strings is using the <code>HEREDOC</code> syntax.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-103"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Subscription</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">warning_message</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #032f62;">&lt;&lt;-HEREDOC</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #032f62;">      Subscription expiring soon!
</span></span><span class="line"><span class="token" style="color: #032f62;">      Your free trial will expire in </span><span class="token" style="color: #032f62;">#{</span><span class="token" style="color: #032f62;">days_until_expiration</span><span class="token" style="color: #032f62;">}</span><span class="token" style="color: #032f62;"> days.
</span></span><span class="line"><span class="token" style="color: #032f62;">      Please update your billing information.
</span></span><span class="line"><span class="token" style="color: #032f62;">    HEREDOC</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-106"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-104">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-105'
	>
	Unfortunately, the string inside the heredoc is going to be output with 6 leading spaces, and so far that’s <strong>never</strong> been the expected behavior for me:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-108"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">text</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #6f42c1;">Subscription</span><span class="token"> </span><span class="token" style="color: #032f62;">expiring</span><span class="token"> </span><span class="token" style="color: #032f62;">soon!</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #6f42c1;">Your</span><span class="token"> </span><span class="token" style="color: #032f62;">free</span><span class="token"> </span><span class="token" style="color: #032f62;">trial</span><span class="token"> </span><span class="token" style="color: #032f62;">will</span><span class="token"> </span><span class="token" style="color: #032f62;">expire</span><span class="token"> </span><span class="token" style="color: #032f62;">in</span><span class="token"> </span><span class="token" style="color: #005cc5;">5</span><span class="token"> </span><span class="token" style="color: #032f62;">days.</span><span class="token">
</span></span><span class="line"><span class="token">      </span><span class="token" style="color: #6f42c1;">Please</span><span class="token"> </span><span class="token" style="color: #032f62;">update</span><span class="token"> </span><span class="token" style="color: #032f62;">your</span><span class="token"> </span><span class="token" style="color: #032f62;">billing</span><span class="token"> </span><span class="token" style="color: #032f62;">information.</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-111"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-109">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-110'
	>
	One solution for this would be to indent the string to the left margin, but that leaves our code looking <strong>really ugly and badly indented</strong>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Subscription</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">warning_message</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #032f62;">&lt;&lt;-HEREDOC</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #032f62;">Subscription expiring soon!
</span></span><span class="line"><span class="token" style="color: #032f62;">Your free trial will expire in </span><span class="token" style="color: #032f62;">#{</span><span class="token" style="color: #032f62;">days_until_expiration</span><span class="token" style="color: #032f62;">}</span><span class="token" style="color: #032f62;"> days.
</span></span><span class="line"><span class="token" style="color: #032f62;">Please update your billing information.
</span></span><span class="line"><span class="token" style="color: #032f62;">    HEREDOC</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	Other ways like removing multiple leading whitespace characters with <code>#gsub</code>, appending multiple strings to each other and so on can be found in the above mentioned Stack Overflow post. There isn’t a nice way to do this in pure Ruby, however Rails does have a ’patch’ to support this behavior with the <a href="http://apidock.com/rails/String/strip_heredoc">#strip_heredoc</a> method, but it’s one method call too much to support a simple behavior like this.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-117">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-118'
	>
	Meet the squiggly heredoc</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	Besides numerous new features in Ruby 2.3, such as the safe navigation operator or <code>Hash#dig</code> (read more about new features in Ruby 2.3 in <a href="http://nithinbekal.com/posts/ruby-2-3-features/">this post</a>), there will be a new and improved HEREDOC syntax called the <strong>squiggly HEREDOC</strong> that does what I’ve always expected the regular HEREDOC syntax to do &#8211; <strong>it strips the leading whitespace</strong> (similar to the <code>#strip_heredoc</code> method in Rails)</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	It looks quite similar to HEREDOC, except instead of writing <code>&lt;&lt;-HEREDOC</code>, you will substitute the hyphen with a <strong>tilda</strong>: <code>&lt;&lt;~HEREDOC</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-126"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-127">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2017/02/multiline-strings-ruby-2-3-0-the-squiggly-heredoc-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="488"
															width="728"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-129">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-130'
	>
	We can finally write our multiline strings in a nice manner with a minimal change (squint hard, you can barely notice it):</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-ruby github-light" data-language="ruby" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Subscription</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">def</span><span class="token"> </span><span class="token" style="color: #6f42c1;">warning_message</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #032f62;">&lt;&lt;~HEREDOC</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #032f62;">      Subscription expiring soon!
</span></span><span class="line"><span class="token" style="color: #032f62;">      Your free trial will expire in </span><span class="token" style="color: #032f62;">#{</span><span class="token" style="color: #032f62;">days_until_expiration</span><span class="token" style="color: #032f62;">}</span><span class="token" style="color: #032f62;"> days.
</span></span><span class="line"><span class="token" style="color: #032f62;">      Please update your billing information.
</span></span><span class="line"><span class="token" style="color: #032f62;">    HEREDOC</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">end</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	The rule for stripping enough whitespace:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-shellscript github-light" data-language="shellscript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">The</span><span class="token"> </span><span class="token" style="color: #032f62;">indentation</span><span class="token"> </span><span class="token" style="color: #032f62;">of</span><span class="token"> </span><span class="token" style="color: #032f62;">the</span><span class="token"> </span><span class="token" style="color: #032f62;">least-indented</span><span class="token"> </span><span class="token" style="color: #032f62;">line</span><span class="token"> </span><span class="token" style="color: #032f62;">will</span><span class="token"> </span><span class="token" style="color: #032f62;">be</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">removed</span><span class="token"> </span><span class="token" style="color: #032f62;">from</span><span class="token"> </span><span class="token" style="color: #032f62;">each</span><span class="token"> </span><span class="token" style="color: #032f62;">line</span><span class="token"> </span><span class="token" style="color: #032f62;">of</span><span class="token"> </span><span class="token" style="color: #032f62;">the</span><span class="token"> </span><span class="token" style="color: #032f62;">content.</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-139">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-140'
	>
	This feature was <a href="https://bugs.ruby-lang.org/issues/9098">suggested</a> by <a href="https://twitter.com/sikachu">Sikachu</a> 2 years ago, merged to Ruby on December 7th, and you can read more about it in this <a href="https://github.com/ruby/ruby/pull/878">pull request</a> by <a href="https://twitter.com/bjmllr">Ben Miller</a> and this <a href="https://github.com/ruby/ruby/commit/9a28a29b870b5f45d370bc8f16c431b435f0bbb3">commit</a> by <a href="https://www.youtube.com/watch?v=yqyIi0pwRO4">Nobu</a>, the mysterious No. 1 committer to the Ruby core.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-142">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-143'
	>
	You can check out all the new features in Ruby 2.3 by installing <code>ruby 2.3.0preview2</code>, or simply wait until Christmas when the new official minor version will be released.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/multiline-strings-ruby-2-3-0-the-squiggly-heredoc/">Multiline Strings in Ruby 2.3  the Squiggly Heredoc</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>