<p>How do I do a diff of two strings or arrays in Ruby?</p>

[{'answer_id': 80111, 'author': 'Brian Mitchell', 'author_id': 13716, 'author_profile': 'https://Stackoverflow.com/users/13716', 'pm_score': 5, 'selected': True, 'text': '<p>diff.rb is what you want, which is available at <del><a href="http://users.cybercity.dk/~dsl8950/ruby/diff.html" rel="nofollow noreferrer">http://users.cybercity.dk/~dsl8950/ruby/diff.html</a></del> via internet archive: </p>\n\n<p><a href="http://web.archive.org/web/20140421214841/http://users.cybercity.dk:80/~dsl8950/ruby/diff.html" rel="nofollow noreferrer">http://web.archive.org/web/20140421214841/http://users.cybercity.dk:80/~dsl8950/ruby/diff.html</a></p>\n'}, {'answer_id': 80117, 'author': 'Chris Bunch', 'author_id': 422, 'author_profile': 'https://Stackoverflow.com/users/422', 'pm_score': 5, 'selected': False, 'text': "<p>For arrays, use the minus operator. For example:</p>\n\n<pre><code>&gt;&gt; foo = [1, 2, 3]\n=&gt; [1, 2, 3]\n&gt;&gt; goo = [2, 3, 4]\n=&gt; [2, 3, 4]\n&gt;&gt; foo - goo\n=&gt; [1]\n</code></pre>\n\n<p>Here the last line removes everything from foo that is also in goo, leaving just the element 1. I don't know how to do this for two strings, but until somebody who knows posts about it, you could just convert each string to an array, use the minus operator, and then convert the result back.</p>\n"}, {'answer_id': 416136, 'author': 'da01', 'author_id': 52001, 'author_profile': 'https://Stackoverflow.com/users/52001', 'pm_score': 4, 'selected': False, 'text': '<p>For strings, I would first try out the Ruby Gem that @sam-saffron mentioned below. It\'s easier to install: \n<a href="http://github.com/pvande/differ/tree/master" rel="noreferrer">http://github.com/pvande/differ/tree/master</a></p>\n\n<pre><code>gem install differ\n\nirb\nrequire \'differ\'\n\none = "one two three"\ntwo = "one two 3"\n\nDiffer.format = :color\nputs Differ.diff_by_word(one, two).to_s\n\nDiffer.format = :html\nputs Differ.diff_by_word(one, two).to_s\n</code></pre>\n'}, {'answer_id': 419013, 'author': 'Grant Hutchins', 'author_id': 6304, 'author_profile': 'https://Stackoverflow.com/users/6304', 'pm_score': 3, 'selected': False, 'text': '<p>There is also <code>diff-lcs</code> which is available as a gem. <strike>It hasn\'t been updated since 2004 but</strike> we have been using it without any problem.</p>\n\n<p><strong>Edit:</strong> A new version was released in 2011. Looks like it\'s back in active development.</p>\n\n<p><a href="http://rubygems.org/gems/diff-lcs" rel="nofollow noreferrer">http://rubygems.org/gems/diff-lcs</a></p>\n'}, {'answer_id': 739161, 'author': 'Brian Armstrong', 'author_id': 76486, 'author_profile': 'https://Stackoverflow.com/users/76486', 'pm_score': 3, 'selected': False, 'text': "<p>The HTMLDiff that @da01 mentions above worked for me.  </p>\n\n<pre><code>script/plugin install git://github.com/myobie/htmldiff.git\n\n# bottom of environment.rb\nrequire 'htmldiff'\n\n# in model\nclass Page &lt; ActiveRecord::Base\n  extend HTMLDiff\nend\n\n# in view\n&lt;h1&gt;Revisions for &lt;%= @page.name %&gt;&lt;/h1&gt;\n&lt;ul&gt;\n&lt;% @page.revisions.each do |revision| %&gt;\n  &lt;li&gt;\n    &lt;b&gt;Revised &lt;%= distance_of_time_in_words_to_now revision.created_at %&gt; ago&lt;/b&gt;&lt;BR&gt;\n      &lt;%= Page.diff(\n        revision.changes['description'][0],\n        revision.changes['description'][1]\n      ) %&gt;\n      &lt;BR&gt;&lt;BR&gt;\n  &lt;/li&gt;\n&lt;% end %&gt;\n\n# in style.css\nins.diffmod, ins.diffins { background: #d4fdd5; text-decoration: none; }\ndel.diffmod, del.diffdel { color: #ff9999; }\n</code></pre>\n\n<p>Looks pretty good.  By the way I used this with the <code>acts_as_audited</code> plugin.</p>\n"}, {'answer_id': 1210782, 'author': 'Sam Saffron', 'author_id': 17174, 'author_profile': 'https://Stackoverflow.com/users/17174', 'pm_score': 2, 'selected': False, 'text': '<p>I just found a new project that seems pretty flexible: </p>\n\n<p><a href="http://github.com/pvande/differ/tree/master" rel="nofollow noreferrer">http://github.com/pvande/differ/tree/master</a> </p>\n\n<p>Trying it out and will try to post some sort of report. </p>\n'}, {'answer_id': 1511882, 'author': 'Daniel Cukier', 'author_id': 105514, 'author_profile': 'https://Stackoverflow.com/users/105514', 'pm_score': 2, 'selected': False, 'text': '<p>I had the same doubt and the solution I found is not 100% ruby, but is the best for me.\nThe problem with diff.rb is that it doesn\'t have a pretty formatter, to show the diffs in a humanized way. So I used diff from the OS with this code:</p>\n\n<pre><code> def diff str1, str2\n   system "diff #{file_for str1} #{file_for str2}"\n end\n\n private\n def file_for text\n   exp = Tempfile.new("bk", "/tmp").open\n   exp.write(text)\n   exp.close\n   exp.path\n end\n</code></pre>\n'}, {'answer_id': 3146315, 'author': 'samg', 'author_id': 211136, 'author_profile': 'https://Stackoverflow.com/users/211136', 'pm_score': 5, 'selected': False, 'text': '<p>I got frustrated with the lack of a good library for this in ruby, so I wrote <a href="http://github.com/samg/diffy" rel="noreferrer">http://github.com/samg/diffy</a>.  It uses <code>diff</code> under the covers, and focuses on being convenient, and providing pretty output options.</p>\n'}, {'answer_id': 6610781, 'author': 'grosser', 'author_id': 110333, 'author_profile': 'https://Stackoverflow.com/users/110333', 'pm_score': 1, 'selected': False, 'text': '<p>Maybe Array.diff via monkey-patch helps...</p>\n\n<p><a href="http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/" rel="nofollow">http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/</a></p>\n'}, {'answer_id': 9133162, 'author': 'russthegibbon', 'author_id': 1129925, 'author_profile': 'https://Stackoverflow.com/users/1129925', 'pm_score': 2, 'selected': False, 'text': "<p>Just for the benefit of Windows people: diffy looks brilliant but I belive it will only work on *nix (correct me if I'm wrong).  Certainly it didn't work on my machine.</p>\n\n<p>Differ worked a treat for me (Windows 7 x64, Ruby 1.8.7).</p>\n"}, {'answer_id': 45572385, 'author': 'dimus', 'author_id': 23080, 'author_profile': 'https://Stackoverflow.com/users/23080', 'pm_score': 1, 'selected': False, 'text': '<p>To get character by character resolution I added a new function to <a href="https://rubygems.org/gems/damerau-levenshtein" rel="nofollow noreferrer">damerau-levenshtein gem</a></p>\n\n<pre><code>require "damerau-levenshtein"\ndiffer = DamerauLevenshtein::Differ.new\ndiffer.run "Something", "Smothing"\n# returns ["S&lt;ins&gt;o&lt;/ins&gt;m&lt;subst&gt;e&lt;/subst&gt;thing", \n#  "S&lt;del&gt;o&lt;/del&gt;m&lt;subst&gt;o&lt;/subst&gt;thing"]\n</code></pre>\n\n<p>or with parsing:</p>\n\n<pre><code>require "damerau-levenshtein"\nrequire "nokogiri"\n\ndiffer = DamerauLevenshtein::Differ.new\nres = differ.run("Something", "Smothing!")\nnodes = Nokogiri::XML("&lt;root&gt;#{res.first}&lt;/root&gt;")\n\nmarkup = nodes.root.children.map do |n|\n  case n.name\n  when "text"\n    n.text\n  when "del"\n    "~~#{n.children.first.text}~~"\n  when "ins"\n    "*#{n.children.first.text}*"\n  when "subst"\n    "**#{n.children.first.text}**"\n  end\nend.join("")\n\nputs markup\n</code></pre>\n'}, {'answer_id': 51544818, 'author': 'Steve', 'author_id': 6621187, 'author_profile': 'https://Stackoverflow.com/users/6621187', 'pm_score': 3, 'selected': False, 'text': "<pre><code>t=s2.chars; s1.chars.map{|c| c == t.shift ? c : '^'}.join\n</code></pre>\n\n<p>This simple line gives a <code>^</code> in the positions that don't match.  That's often enough and it's copy/paste-able.    </p>\n"}]
['https://Stackoverflow.com/questions/80091', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5004/']