{"id":23154,"date":"2018-11-07T12:15:06","date_gmt":"2018-11-07T10:15:06","guid":{"rendered":"https:\/\/www.webcodegeeks.com\/?p=23154"},"modified":"2018-11-07T11:06:28","modified_gmt":"2018-11-07T09:06:28","slug":"test-ruby-code-thread-safety","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/","title":{"rendered":"Do You Test Ruby Code for Thread Safety?"},"content":{"rendered":"<p>Are you a Ruby developer? If you are, I\u2019m pretty sure you have a very vague idea of what concurrency and thread safety are. No offense, but this is what I\u2019ve figured out after dealing with Ruby code and speaking with Ruby programmers over the last half a year. I\u2019ve been writing in Ruby pretty actively recently and I do like the language and the ecosystem around it. Zold, the experimental cryptocurrency we are creating, is written almost entirely in Ruby. What does that tell you? I like Ruby. But when it comes to concurrency, there are blank spots. Big time.<\/p>\n<p>Look at this Ruby class:<\/p>\n<pre class=\"brush:php\">require 'sinatra'\r\nclass Front &lt; Sinatra::Base\r\n  configure do\r\n    IO.write('idx.txt', '0')\r\n  end\r\n  get '\/' do\r\n    idx = IO.read('idx.txt').to_i + 1\r\n    IO.write('idx.txt', idx.to_s)\r\n    idx.to_s\r\n  end\r\nend\r\nFront.run!<\/pre>\n<p>It\u2019s a simple web server. It does work\u2014try to run it like this (you will need Ruby 2.3+ installed):<\/p>\n<pre class=\"brush:php\">$ gem install sinatra\r\n$ ruby server.rb<\/pre>\n<p>Then, open <code>http:\/\/localhost:4567<\/code> and you will see the counter. Refresh the page and the counter will increment. Try again. It works. The counter is in the file <code>idx.txt<\/code> and it\u2019s essentially a <a href=\"https:\/\/www.yegor256.com\/2018\/07\/03\/global-variables.html\">global variable<\/a>, which we increment on every HTTP request.<\/p>\n<p>Let\u2019s create a unit test for it, to make sure it is automatically tested:<\/p>\n<pre class=\"brush:php\">require 'minitest\/autorun'\r\nrequire 'net\/http'\r\nrequire 'uri'\r\nclass FrontTest &lt; Minitest::Test\r\n  def test_works\r\n    front = Thread.start do\r\n      Front.run!\r\n    end\r\n    sleep 1\r\n    count = Net::HTTP.get(URI('http:\/\/localhost:4567\/')).to_i\r\n    assert_equal(1, count)\r\n    Front.stop!\r\n  end\r\nend<\/pre>\n<p>OK, it\u2019s not a unit test, but more like an integration test. First we start a web server in a background thread. Then we wait for a second, to give that thread enough time to bootstrap the server. I know, it\u2019s a very ugly approach, but I don\u2019t have anything better for this small example. Next we make an HTTP request and compare it with the expected number 1. Finally, we stop the web server.<\/p>\n<p>So far so good. Now, the question is, what will happen when many requests are sent to the server? Will it still return the correct, consecutive numbers? Let\u2019s try:<\/p>\n<pre class=\"brush:php\">def test_works\r\n  front = Thread.start do\r\n    Front.run!\r\n  end\r\n  sleep 1\r\n  numbers = []\r\n  1000.times do\r\n    numbers &lt;&lt; Net::HTTP.get(URI('http:\/\/localhost:4567\/')).to_i\r\n  end\r\n  assert_equal(1000, numbers.uniq.count)\r\n  Front.stop!\r\nend<\/pre>\n<p>Here we make a thousand requests and put all the returned numbers into an array. Then we <code>uniq<\/code> the array and <code>count<\/code> its elements. If there is a thousand of them\u2014everything worked fine, we received a correct list of consecutive, unique numbers. I just tested it, and it works.<\/p>\n<p>But we are making them one by one, that\u2019s why our server doesn\u2019t have any problems. We aren\u2019t making them concurrently. They go strictly one after another. Let\u2019s try to use a few additional threads to simulate parallel execution of HTTP requests:<\/p>\n<pre class=\"brush:php\">require 'concurrent\/set'\r\ndef test_works\r\n  front = Thread.start do\r\n    Front.run!\r\n  end\r\n  sleep 1\r\n  numbers = Concurrent::Set.new\r\n  threads = []\r\n  5.times do\r\n    threads &lt;&lt; Thread.start do\r\n      200.times do\r\n        numbers &lt;&lt; Net::HTTP.get(URI('http:\/\/localhost:4567\/')).to_i\r\n      end\r\n    end\r\n  end\r\n  threads.each { |t| t.join }\r\n  assert_equal(1000, numbers.to_a.count)\r\n  Front.stop!\r\nend<\/pre>\n<p>First of all, we keep the list of numbers in a <a href=\"http:\/\/ruby-concurrency.github.io\/concurrent-ruby\/master\/Concurrent\/Set.html\"><code>Concurrent::Set<\/code><\/a>, which is a thread-safe version of Ruby <a href=\"http:\/\/ruby-doc.org\/stdlib-2.4.0\/libdoc\/set\/rdoc\/Set.html\"><code>Set<\/code><\/a>. Second, we start five background threads, each of which makes 200 HTTP requests. They all run in parallel and we wait for them to finish by calling <code>join<\/code> on each of them. Finally, we take the numbers out of the Set and validate the correctness of the list.<\/p>\n<p>No surprise, it fails.<\/p>\n<p>Of course, you know why. Because the implementation is not <em>thread-safe<\/em>. When one thread is reading the file, another one is writing it. Eventually, and very soon, they clash and the contents of the file is broken. The more threads we put into the test, the less accurate will be the result.<\/p>\n<p>In order to make this type of testing easier I created <a href=\"https:\/\/github.com\/yegor256\/threads\">threads<\/a>, a simple Ruby gem. Here is how it works:<\/p>\n<pre class=\"brush:php\">require 'threads'\r\ndef test_works\r\n  front = Thread.start do\r\n    Front.run!\r\n  end\r\n  sleep 1\r\n  numbers = Concurrent::Set.new\r\n  Threads.new(5).assert(1000) do\r\n    numbers &lt;&lt; Net::HTTP.get(URI('http:\/\/localhost:4567\/')).to_i\r\n  end\r\n  assert_equal(1000, numbers.to_a.count)\r\n  Front.stop!\r\nend<\/pre>\n<p>That\u2019s it. This single line with <code>Threads.new()<\/code> replaces all other lines, where we have to create threads, make sure they start at the same time, and then collect their results and make sure their stack traces are visible in the console if they crash (by default, the error log of a background thread is not visible).<\/p>\n<p>Try this gem in your projects, it\u2019s pretty well tested already and I use it in all my concurrency tests.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Web Code Geeks with permission by Yegor Bugayenko, partner at our <a href=\"\/\/www.webcodegeeks.com\/join-us\/wcg\/\" target=\"_blank\" rel=\"noopener\">WCG program<\/a>. See the original article here: <a href=\"https:\/\/www.yegor256.com\/2018\/11\/06\/ruby-threads.html\" target=\"_blank\" rel=\"noopener\">Do You Test Ruby Code for Thread Safety?<\/a><\/p>\n<p>Opinions expressed by Web Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Are you a Ruby developer? If you are, I\u2019m pretty sure you have a very vague idea of what concurrency and thread safety are. No offense, but this is what I\u2019ve figured out after dealing with Ruby code and speaking with Ruby programmers over the last half a year. I\u2019ve been writing in Ruby pretty &hellip;<\/p>\n","protected":false},"author":6534,"featured_media":4128,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[],"class_list":["post-23154","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ruby"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Do You Test Ruby Code for Thread Safety? - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"Interested to learn about thread safety? Check our article explaining concurrency and thread safety when you&#039;re dealing with ruby code.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Do You Test Ruby Code for Thread Safety? - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about thread safety? Check our article explaining concurrency and thread safety when you&#039;re dealing with ruby code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/yegor256\" \/>\n<meta property=\"article:published_time\" content=\"2018-11-07T10:15:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Yegor Bugayenko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@yegor256\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Yegor Bugayenko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\"},\"author\":{\"name\":\"Yegor Bugayenko\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/96538e7abaac9f7a3dce9d5d92e1cb33\"},\"headline\":\"Do You Test Ruby Code for Thread Safety?\",\"datePublished\":\"2018-11-07T10:15:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\"},\"wordCount\":649,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"articleSection\":[\"Ruby\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\",\"name\":\"Do You Test Ruby Code for Thread Safety? - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"datePublished\":\"2018-11-07T10:15:06+00:00\",\"description\":\"Interested to learn about thread safety? Check our article explaining concurrency and thread safety when you're dealing with ruby code.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruby\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/ruby\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Do You Test Ruby Code for Thread Safety?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/96538e7abaac9f7a3dce9d5d92e1cb33\",\"name\":\"Yegor Bugayenko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c3696c78da79ebdd9ffa8e87e8832461b7cd59659483373b34da4ae25dfb573a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c3696c78da79ebdd9ffa8e87e8832461b7cd59659483373b34da4ae25dfb573a?s=96&d=mm&r=g\",\"caption\":\"Yegor Bugayenko\"},\"description\":\"Yegor Bugayenko is an Oracle certified Java architect, CEO of Zerocracy, author of Elegant Objects book series about object-oriented programing, lead architect and founder of Cactoos, Takes, Rultor and Jcabi, and a big fan of test automation.\",\"sameAs\":[\"http:\/\/www.yegor256.com\/\",\"https:\/\/www.facebook.com\/yegor256\",\"https:\/\/www.linkedin.com\/in\/yegor256\",\"https:\/\/x.com\/yegor256\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/yegor-bugayenko\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Do You Test Ruby Code for Thread Safety? - Web Code Geeks - 2026","description":"Interested to learn about thread safety? Check our article explaining concurrency and thread safety when you're dealing with ruby code.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/","og_locale":"en_US","og_type":"article","og_title":"Do You Test Ruby Code for Thread Safety? - Web Code Geeks - 2026","og_description":"Interested to learn about thread safety? Check our article explaining concurrency and thread safety when you're dealing with ruby code.","og_url":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_author":"https:\/\/www.facebook.com\/yegor256","article_published_time":"2018-11-07T10:15:06+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","type":"image\/jpeg"}],"author":"Yegor Bugayenko","twitter_card":"summary_large_image","twitter_creator":"@yegor256","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Yegor Bugayenko","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/"},"author":{"name":"Yegor Bugayenko","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/96538e7abaac9f7a3dce9d5d92e1cb33"},"headline":"Do You Test Ruby Code for Thread Safety?","datePublished":"2018-11-07T10:15:06+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/"},"wordCount":649,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","articleSection":["Ruby"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/","url":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/","name":"Do You Test Ruby Code for Thread Safety? - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","datePublished":"2018-11-07T10:15:06+00:00","description":"Interested to learn about thread safety? Check our article explaining concurrency and thread safety when you're dealing with ruby code.","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2015\/04\/ruby-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/ruby\/test-ruby-code-thread-safety\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Ruby","item":"https:\/\/www.webcodegeeks.com\/category\/ruby\/"},{"@type":"ListItem","position":3,"name":"Do You Test Ruby Code for Thread Safety?"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/96538e7abaac9f7a3dce9d5d92e1cb33","name":"Yegor Bugayenko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c3696c78da79ebdd9ffa8e87e8832461b7cd59659483373b34da4ae25dfb573a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c3696c78da79ebdd9ffa8e87e8832461b7cd59659483373b34da4ae25dfb573a?s=96&d=mm&r=g","caption":"Yegor Bugayenko"},"description":"Yegor Bugayenko is an Oracle certified Java architect, CEO of Zerocracy, author of Elegant Objects book series about object-oriented programing, lead architect and founder of Cactoos, Takes, Rultor and Jcabi, and a big fan of test automation.","sameAs":["http:\/\/www.yegor256.com\/","https:\/\/www.facebook.com\/yegor256","https:\/\/www.linkedin.com\/in\/yegor256","https:\/\/x.com\/yegor256"],"url":"https:\/\/www.webcodegeeks.com\/author\/yegor-bugayenko\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/23154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/6534"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=23154"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/23154\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/4128"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=23154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=23154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=23154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}