<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: RobL</title>
    <description>The latest articles on DEV Community by RobL (@braindeaf).</description>
    <link>https://dev.to/braindeaf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F648177%2F238407ca-bdb6-4d04-8355-888264bed701.jpeg</url>
      <title>DEV Community: RobL</title>
      <link>https://dev.to/braindeaf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/braindeaf"/>
    <language>en</language>
    <item>
      <title>Puma-dev is one of my favourite tools</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Mon, 05 Feb 2024 17:03:20 +0000</pubDate>
      <link>https://dev.to/braindeaf/puma-dev-is-one-of-my-favourite-tools-lc5</link>
      <guid>https://dev.to/braindeaf/puma-dev-is-one-of-my-favourite-tools-lc5</guid>
      <description>&lt;p&gt;Running applications locally on your laptop is normally a doddle. Boot up a Rails app and point your browser at&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy peasy. But what if your application is not your average application. Suppose it's multi-tenanted app with a hostname for each tenant and you want to try that locally. Well you could whack a load of entries in your &lt;code&gt;/etc/hosts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;/etc/hosts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;##&lt;/span&gt;
&lt;span class="c"&gt;# Host Database&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# localhost is used to configure the loopback interface&lt;/span&gt;
&lt;span class="c"&gt;# when the system is booting.  Do not change this entry.&lt;/span&gt;
&lt;span class="c"&gt;##&lt;/span&gt;
127.0.0.1    demo.fossa-are-great.org
127.0.0.1    demo.fossa-are-ok.org
127.0.0.1   localhost
255.255.255.255 broadcasthost
::1             localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you could visit...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http://demo.fossa-are-great.org:3000/
http://demo.fossa-are-ok.org:3000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...with ease and everything would be fine, even if port 3000 is now a little jarring. It is possible to remove the port if we ran our own version of Nginx running on port 80 and configured it to proxy onto our running application on port 3000. I'm going to go out on a limb and say there are will be a high proportion of developers that won't know how to configure Nginx to do this and it's a bit overkill anyway. However, &lt;em&gt;puma-dev&lt;/em&gt; makes pretty light work of this.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Puma-dev: A fast, zero-config development server for macOS and Linux&lt;/em&gt; - &lt;a href="https://github.com/puma/puma-dev"&gt;https://github.com/puma/puma-dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On macOS it's pretty easy to set up with &lt;code&gt;brew&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;puma/puma/puma-dev
&lt;span class="c"&gt;# Configure some DNS settings that have to be done as root&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;puma-dev &lt;span class="nt"&gt;-setup&lt;/span&gt;
&lt;span class="c"&gt;# Configure puma-dev to run in the background on ports 80 and 443 with the domain `.test`.&lt;/span&gt;
puma-dev &lt;span class="nt"&gt;-install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in order to configure our hostnames we create a file the ~/.puma-dev per hostname we want to support with the port of the running application.&lt;/p&gt;

&lt;p&gt;~/.puma-dev/demo.fossa-are-great&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;~/.puma-dev/demo.fossa-are-ok&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we have to visit our domain with the &lt;em&gt;.test&lt;/em&gt; Top-Level Domain as Puma Dev, by default, supports that TLD. Puma-dev runs on port 80 and 443 as standard and so there is no need to supply a port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;http://demo.fossa-are-great.test/
http://demo.fossa-are-ok.test/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The way this works is really neat and I'm a bit of a fan to be fair. Hostnames on macOS and Linux flavours uses /etc/resolver/. Puma creates a file &lt;code&gt;/etc/resolver/test&lt;/code&gt; to indicate that name resolution for .test domains should use a local nameserver running on port 9253 to resolve hostname blah.test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generated by puma-dev&lt;/span&gt;
nameserver 127.0.0.1
port 9253
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact let's try it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig blah.test @127.0.0.1 &lt;span class="nt"&gt;-p&lt;/span&gt; 9253

&lt;span class="p"&gt;;&lt;/span&gt; &amp;lt;&amp;lt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; DiG 9.10.6 &amp;lt;&amp;lt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; blah.test @127.0.0.1 &lt;span class="nt"&gt;-p&lt;/span&gt; 9253
&lt;span class="p"&gt;;;&lt;/span&gt; global options: +cmd
&lt;span class="p"&gt;;;&lt;/span&gt; Got answer:
&lt;span class="p"&gt;;;&lt;/span&gt; -&amp;gt;&amp;gt;HEADER&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt; &lt;span class="no"&gt;opcode&lt;/span&gt;&lt;span class="sh"&gt;: QUERY, status: NOERROR, id: 2962
;; flags: qr rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;blah.test.         IN  A

;; ANSWER SECTION:
blah.test.      0   IN  A   127.0.0.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#9253(127.0.0.1)
;; WHEN: Mon Feb 05 15:42:26 GMT 2024
;; MSG SIZE  rcvd: 52
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, this returns and resolves our domain to 127.0.0.1, however visiting &lt;a href="http://blah.test"&gt;http://blah.test&lt;/a&gt; will result in the following because we haven't configured puma-dev to point at an internal port.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;unknown app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty neat huh? Well that's not the end of the story. What if we wanted to use &lt;a href="https://demo.fossa-are-great.test"&gt;https://demo.fossa-are-great.test&lt;/a&gt;. Well that just works out of the box. Like I said it also runs on port 443. Puma manages the certificate authority for the .test domain locally and adds the certificate and key to the local keychain so now we have valid SSL. Magic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; ~/Library/Application&lt;span class="se"&gt;\ &lt;/span&gt;Support/io.puma.dev 
total 16
drwx------   4 rl  staff   128 16 Jan 09:03 &lt;span class="nb"&gt;.&lt;/span&gt;
drwx------+ 62 rl  staff  1984 29 Jan 02:06 ..
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt;   1 rl  staff  1208 16 Jan 09:03 cert.pem
&lt;span class="nt"&gt;-rw-------&lt;/span&gt;   1 rl  staff  1679 16 Jan 09:03 key.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've been using this setup for years now and it has enabled us to run multiple applications locally and fully test running up to 5 different multi-tenanted Rails apps logging users in with the same cookie domain as an extreme example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://app1.blah.something.test
https://app1.club.something.test
https://app2.blah.something.test
https://app2.club.something.test
https://app3.blah.something.test
https://app3.club.something.test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have only ever found one issue with this setup and that was today.&lt;/p&gt;

&lt;h2&gt;
  
  
  SSL Certificate seemingly invalid
&lt;/h2&gt;

&lt;p&gt;Today's issue involved building PDFs with Grover that had missing styles and as it turned out the this was only over SSL so there was an issue with the certificate which was fixed by re-configuring Puma-dev to presumably re-add the certificate to the keychain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;puma-dev &lt;span class="nt"&gt;-uninstall&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;puma-dev &lt;span class="nt"&gt;-setup&lt;/span&gt;
puma-dev &lt;span class="nt"&gt;-install&lt;/span&gt;
puma-dev &lt;span class="nt"&gt;-stop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thumbs up for &lt;em&gt;puma-dev&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>pumadev</category>
      <category>ssl</category>
    </item>
    <item>
      <title>How do you test frozen_string_literal in Ruby?</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Wed, 13 Dec 2023 23:11:22 +0000</pubDate>
      <link>https://dev.to/braindeaf/how-do-you-test-frozenstringliteral-in-ruby-84e</link>
      <guid>https://dev.to/braindeaf/how-do-you-test-frozenstringliteral-in-ruby-84e</guid>
      <description>&lt;p&gt;Just posed the question on LinkedIn'&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Potentially silly question, I am not ashamed of not knowing this... How do you mark a Haml file with the magic comment # frozen_string_literal: true. Is it even possible?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7140300572573724673/"&gt;https://www.linkedin.com/feed/update/urn:li:activity:7140300572573724673/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alek K came back with a bit of research. I'm a fan of poking something with a stick.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That's a quite interesting question, one I've never thought of myself before. As a response, I wrote a short article on my blog, describing a little experiment. I hope this can shed some light on the issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://torrocus.com/blog/haml-with-frozen-string-literal-wtf/"&gt;https://torrocus.com/blog/haml-with-frozen-string-literal-wtf/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;His theory was Rubocop must know how to solve this. Sadly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# frozen_string_literal: true
SOMETHING
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is not valid Haml. Since it's trying to render a # which would be a div with no id. Simply won't work. I thought I'd take a quick stab at this.&lt;/p&gt;

&lt;p&gt;Suppose we have. Silly example. But all I want to prove is that with &lt;strong&gt;frozen_string_literal&lt;/strong&gt; that the object_id is the same for all instances of "A" since it's the same String.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"--&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here goes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% ruby frozen.rb
&lt;span class="nt"&gt;--&lt;/span&gt;/Users/roblacey/repos/personal/robl.me/frozen.rb
60
60
60
60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep it's the same object_id everytime. So how would we even test this in Erb?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# frozen_string_literal: true

&amp;lt;% puts "--#{__FILE__}" %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I guess we do...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% irb
irb&lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt;:001&amp;gt; require &lt;span class="s1"&gt;'erb'&lt;/span&gt;
irb&lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt;:002&amp;gt; ERB.new&lt;span class="o"&gt;(&lt;/span&gt;File.read&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'frozen.erb'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;.result&lt;span class="o"&gt;(&lt;/span&gt;binding&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;--&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;erb&lt;span class="o"&gt;)&lt;/span&gt;
7980
8000
8020
8040
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"# frozen_string_literal: true&lt;/span&gt;&lt;span class="se"&gt;\n\n\n\n\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nope none of these are the same object_id. There is some more magic going on. Indeed our Haml file is going to fail with what we saw before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haml"&gt;&lt;code&gt;# frozen_string_literal: true

&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"--&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'haml'
=&amp;gt; true
irb(main):005&amp;gt; (Haml::Template.new() { File.read('frozen.haml') }).render
(__TEMPLATE__):2:in `__tilt_18120': Illegal element: classes and ids must have values. (Haml::SyntaxError)
    from /Users/roblacey/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/tilt-2.3.0/lib/tilt/template.rb:207:in `bind_call'
    from /Users/roblacey/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/tilt-2.3.0/lib/tilt/template.rb:207:in `evaluate'
    from /Users/roblacey/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/tilt-2.3.0/lib/tilt/template.rb:102:in `render'
    from (irb):5:in `&amp;lt;main&amp;gt;'
    from /Users/roblacey/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.9.1/exe/irb:9:in `&amp;lt;top (required)&amp;gt;'
    from /Users/roblacey/.asdf/installs/ruby/3.2.2/bin/irb:25:in `load'
    from /Users/roblacey/.asdf/installs/ruby/3.2.2/bin/irb:25:in `&amp;lt;main&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So honestly, I am not sure how this even works with ERB templates in Rails. I need to take a further dig into the Rails source to find out more.&lt;/p&gt;

&lt;p&gt;Anyone, Bueller?&lt;/p&gt;

&lt;p&gt;UPDATE: Cheers &lt;a class="mentioned-user" href="https://dev.to/castwide"&gt;@castwide&lt;/a&gt; seems so obvious now. erb templates aren't Ruby they are just converted/eval'ed into Ruby. So this makes sense if the first line is the comment has the comment delimited.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%# frozen_string_literal: true %&amp;gt;

&amp;lt;% puts "--#{__FILE__}" %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&amp;lt;% puts "A".object_id %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'erb'
=&amp;gt; true
irb(main):003&amp;gt; ERB.new(File.read('frozen.erb')).result(binding)
--(erb)
27600
27600
27600
27600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Haml clearly doesn't work in the same way. As we can't just replicate it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-# frozen_string_literal: true

- puts "--#{__FILE__}"
- puts "A".object_id
- puts "A".object_id
- puts "A".object_id
- puts "A".object_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require 'haml'
=&amp;gt; true
irb(main):003&amp;gt; (Haml::Template.new() { File.read('frozen.haml') }).render
--(__TEMPLATE__)
48000
48020
48040
48060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>rails</category>
      <category>haml</category>
      <category>erb</category>
    </item>
    <item>
      <title>January 1st 0001 is actually January 3rd 0001 or is it?</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Sat, 18 Nov 2023 15:20:32 +0000</pubDate>
      <link>https://dev.to/braindeaf/january-1st-0001-is-actually-january-3rd-0001-or-is-it-5c8b</link>
      <guid>https://dev.to/braindeaf/january-1st-0001-is-actually-january-3rd-0001-or-is-it-5c8b</guid>
      <description>&lt;p&gt;I came across a rather strange bug in some client code yesterday which had me stumped for quite some time. They're using a &lt;code&gt;date_select&lt;/code&gt; to present the day and month and storing that day with just any arbitrary year. It doesn't really matter just that you can retrieve the date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;date_select&lt;/span&gt; &lt;span class="ss"&gt;:starts_on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;order: &lt;/span&gt;&lt;span class="sx"&gt;%i[day month]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;include_blank: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we might expect the date select creates MultiParameterAttributes  which will result in our parameters containing values like so.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"starts_on(1i)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# year&lt;/span&gt;
  &lt;span class="s2"&gt;"starts_on(2i)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# month&lt;/span&gt;
  &lt;span class="s2"&gt;"starts_on(3i)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="c1"&gt;# day&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting html from the date select produces 2 selects for the month and day, but since we're excluding the year we get a hidden field for the year since we need starts_on(1i), starts_on(2i) and starts_on(3i) parameters to construct a Date/Time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"_starts_on_1i"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"[starts_on(1i)]"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"off"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's worth noting that the year defaults "1" because we are using &lt;code&gt;include_blank: true&lt;/code&gt; because we want the the date to be set or not. This has interesting side-effects. In part because we're using Mongoid, Mongoid stores dates as times so a Time object is being created when we mass-assign it. We're effectively doing this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mo"&gt;0001&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;01&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;01&lt;/span&gt; &lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mo"&gt;0100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which seems fine, until you call &lt;code&gt;.to_date&lt;/code&gt; on it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_date&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Mon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt; &lt;span class="no"&gt;Jan&lt;/span&gt; &lt;span class="mo"&gt;0001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh. Erm... I was all ready to start reporting this as a bug. It's not really a bug but an anomaly. The first thing I can find out about it is on this &lt;a href="https://www.quora.com/What-was-the-day-on-1st-Jan-0001-AD"&gt;Quora thread&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Ok, calendars at that time varied and who am I to argue, it was 2000 years ago. I am by no means a calendar expert.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JIEL1GRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq488vg5grteua55ehu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JIEL1GRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq488vg5grteua55ehu2.png" alt="Image description" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I do know is that I need a solution to my problem, suddenly moving from Rails 6.0 to Rails 6.1 (in Ruby 3.2.2) this has appeared. The fastest solution without getting bogged down and changing 100 different selects is to start thinking in terms of another default year.&lt;/p&gt;

&lt;p&gt;This would be easy if we didn't have to use &lt;code&gt;include_blank&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;date_select&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:starts_on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;order: &lt;/span&gt;&lt;span class="sx"&gt;%i[day month]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1970&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# or &lt;/span&gt;
&lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;date_select&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:starts_on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;order: &lt;/span&gt;&lt;span class="sx"&gt;%i[day month]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;year: &lt;/span&gt;&lt;span class="mi"&gt;1970&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;outputs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"_starts_on_1i"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"[starts_on(1i)]"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1970"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"off"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and 1970 onwards uses a calendar we can rely on,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1970&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_date&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1970&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;01&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;01&lt;/span&gt; &lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mo"&gt;00&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mo"&gt;0100&lt;/span&gt;
&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1970&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_date&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Thu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;01&lt;/span&gt; &lt;span class="no"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;1970&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However since we're using &lt;code&gt;include_blank&lt;/code&gt; I need to just hack  date_select to use "1970" instead of "1" and be done with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Helpers&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateTimeSelector&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_year&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vi"&gt;@datetime&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
          &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1"&lt;/span&gt; &lt;span class="c1"&gt;# hardcoded to "1"&lt;/span&gt;
          &lt;span class="n"&gt;middle_year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;year&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;middle_year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;year&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:use_hidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:discard_year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="n"&gt;build_hidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1800&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;"1970"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# don't use "1" please.&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;                     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:start_year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;middle_year&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;               &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:end_year&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;middle_year&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:step&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;              &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:leading_zeros&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
          &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_years_allowed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_years_allowed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:end&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:start&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_years_allowed&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;ArgumentError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter."&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;build_select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;build_year_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's heavy handed but there was no other way to change that hardcoded "1" default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build_hidden(:year, val.to_i &amp;lt; 1800 ? "1970" : val)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, I change the value to 1970 if the date happend to be less than 1800 (either by default or if it from the database), so if the value in the database is already 0001 or 0000, then the date_select will use the values for year that are already set which means we could potentially start poisoning the data in the database unless we go and correct all values to use 1970 in advance of rolling this out.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>I need a new adventure...</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Thu, 16 Nov 2023 13:07:12 +0000</pubDate>
      <link>https://dev.to/braindeaf/i-need-a-new-adventure-4lmp</link>
      <guid>https://dev.to/braindeaf/i-need-a-new-adventure-4lmp</guid>
      <description>&lt;p&gt;This year has been a weird one. And life takes a turn.&lt;/p&gt;

&lt;p&gt;At the end of last year, after 4 years, I decided to move on from &lt;a href="https://sardjv.co.uk"&gt;SARD JV Limited&lt;/a&gt; they are lovely people and the team are great and we still talk but  for varying personal reasons, could not continue and I set out to seek my fortune elsewhere.&lt;/p&gt;

&lt;p&gt;I landed with &lt;a href="https://builder.ai"&gt;Builder.ai&lt;/a&gt; in January of this year and realised pretty quickly that the role I had taken was not for me. I'm not afraid of meetings, planning, mentoring, code reviews, far from it. But when I realised that I wasn't writing any code myself that became a problem. With SARD JV I was in the heart of everything, guiding the development of the application and introducing new ways of restructuring code, adding in performance gains the whole package, I had code coming out of my ears and I was waking up thinking about code. Without being in the thick of it I was in a place where I wasn't happy. This is the first time I felt like I'd made the wrong choice and it was wrong to continue for myself and for Builder.ai so I made a quick exit. &lt;/p&gt;

&lt;p&gt;In April I joined &lt;a href="https://junipereducation.org/"&gt;Juniper Education&lt;/a&gt; and have for the past six months been working as a Senior Developer in an exceptional team on a pretty complex Assessment tracking system for UK schools. Plenty of performance problems to tackle and interesting UIs. We were on the verge of launching the product in the coming months. Sadly, however, the business has decided not to continue with Ruby. I mean I think Ruby is pretty great, but... that's not our decision. That means a medium size team of developers were released in the wild on Tuesday of this week. &lt;/p&gt;

&lt;p&gt;If only there was a startup that needed 5 to 10 developers to that were already comfortable working with one another to start on a new product. Wishful thinking I know.&lt;/p&gt;

&lt;p&gt;So for now I'm on the hunt for work myself. I have all of my possessions wrapped in a hankerchief on the end of a stick and I am off to the end of our driveway to seek my fortune. That might be a lie.&lt;/p&gt;

&lt;p&gt;So here goes "...I'm a seasoned but not salty Senior Software Engineer from Brighton, UK who's been working with Ruby/Rails (remotely) for the past 15 years. I'm looking for a fully remote role that is hands-on focusing on code rather than people management although I love working with other developers and wish to continue code review and mentoring. I want to make a positive impact on the team I land in and inject my experience in a new project/adventure...".&lt;/p&gt;

&lt;p&gt;If you have a quest that needs a Tank, I'm available and ready to work with you. Feel free to &lt;a href="https://robl.me/cv"&gt;take a look at my CV&lt;/a&gt; and any feedback positive or negative is very welcome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x2cm5p31xdvz7f4ooln.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9x2cm5p31xdvz7f4ooln.jpg" alt="Image description" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;blockquote&gt;
&lt;br&gt;
&lt;p&gt;It appears to be the wrong time of year to be looking for a new Ruby/Rails gig. But unfortunately my brain isn't ready to hibernate for the Winter. So if you have hard problems, horrible upgrades or just need a reliable, competent, conscientious Senior Ruby Dev... &lt;a href="https://twitter.com/hashtag/ruby?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#ruby&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/rails?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#rails&lt;/a&gt; &lt;a href="https://t.co/gKEJSfT5J1"&gt;pic.twitter.com/gKEJSfT5J1&lt;/a&gt;&lt;/p&gt;— RobL (&lt;a class="mentioned-user" href="https://dev.to/braindeaf"&gt;@braindeaf&lt;/a&gt;) &lt;a href="https://twitter.com/braindeaf/status/1728949213004984543?ref_src=twsrc%5Etfw"&gt;November 27, 2023&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt; 

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>seniorsoftwareengineer</category>
      <category>lookingforwork</category>
    </item>
    <item>
      <title>Making a YouTube Short</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Thu, 28 Sep 2023 13:07:26 +0000</pubDate>
      <link>https://dev.to/braindeaf/making-a-youtube-short-5gih</link>
      <guid>https://dev.to/braindeaf/making-a-youtube-short-5gih</guid>
      <description>&lt;p&gt;Every year myself and my wife go to Essen, Germany for the annual Spiel, this year it's 5th - 8th October. She runs her own board game &lt;a href="//youtube.com/iplayred"&gt;YouTube channel as I Play Red&lt;/a&gt;. I help her film and stuff. &lt;/p&gt;

&lt;p&gt;So, this year we decided to create a fun video before the Spiel, which coincidentally crosses over with &lt;a href="https://rubyonrails.org/world" rel="noopener noreferrer"&gt;Rails World&lt;/a&gt; which I am sad about not attending, maybe next year.&lt;/p&gt;

&lt;p&gt;As a fun side-project I created &lt;a href="https://myspiel.co.uk" rel="noopener noreferrer"&gt;MySpiel&lt;/a&gt; which gathers information about all of the new board game releases at Spiel including grabbing images of the board game box art. It's a Rails project with the images stored with ActiveStorage, there are about 1,000 images so what came we make with that.&lt;/p&gt;

&lt;p&gt;We wanted to make a &lt;a href="https://www.youtube.com/hashtag/shorts" rel="noopener noreferrer"&gt;YouTube Short&lt;/a&gt;, the criteria for that is a video with a ratio of 16:9 that is 60 seconds long at the most. Ok, it actually got to be vertical, so the ratio is actually 9:16. So I think we're going to smash all of those images together into a video just to demonstrate how huge 1,000 new releases really is. So whatever images we've got they have to be resized to that ratio before we do anything else.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imagemagick.org/index.php" rel="noopener noreferrer"&gt;ImageMagick&lt;/a&gt; is a pretty standard tool for image manipulation and it's got a pretty powerful command line interface which honestly is often overwhelming but fortunately there are plenty of forums, stack overflow, etc to get good examples.&lt;/p&gt;

&lt;p&gt;Firstly though I want to find all the images on my local disk I'm using local storage for ActiveStorage. We can grab the path to all of the files and whack that in an external file. You can extract the path name to the file using &lt;code&gt;ActiveStorage::Blob.service#path_for&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_one_attached&lt;/span&gt; &lt;span class="ss"&gt;:cover&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;on_disk&lt;/span&gt;
    &lt;span class="no"&gt;ActiveStorage&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we dump all the paths to a file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"images.txt"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 
  &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:on_disk&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have all the paths, I'm going to use ImageMagick to resize and crop all the images to 9:16 in bash. It will read in the files from &lt;code&gt;images.txt&lt;/code&gt; and output each of them to a .png&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;images.txt&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;do 
  &lt;/span&gt;file &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;o&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
  magick &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="nt"&gt;-gravity&lt;/span&gt; center &lt;span class="nt"&gt;-extent&lt;/span&gt; 9:16 &lt;span class="nt"&gt;-resize&lt;/span&gt; 1440x2560 out/&lt;span class="nv"&gt;$o&lt;/span&gt;.png&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://boardgamegeek.com/boardgame/374200/celtae" rel="noopener noreferrer"&gt;Celtae&lt;/a&gt;  from &lt;a href="https://pythagoras.pt/en/" rel="noopener noreferrer"&gt;Pythagoras Games&lt;/a&gt; is a "worker swapping" game powered by a rondel in which players choose actions to perform during their turn. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Celtae 1:1
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5im17djvp5y9bfxbhfq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5im17djvp5y9bfxbhfq.png" alt="Celtae 1:1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Celtae 9:16
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsolxf6yw6vtv6rq34gvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsolxf6yw6vtv6rq34gvf.png" alt="Celtae 9:16"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, that took a while but now we have almost 1,100 images resized and cropped. We want to collect these altogether into a video. We can use &lt;a href="https://ffmpeg.org/" rel="noopener noreferrer"&gt;FFMpeg&lt;/a&gt; for that, but pausing a bit. We want to fit 1,100 images into 60 seconds. That 18 images per second. I'm going to take a guess that smashing that many images together in close succession is going to be quite jarring. How can we make make it less jarring. Well for fun we could order the images by colour (or approximate colour).&lt;/p&gt;

&lt;p&gt;This was a nice little snippet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.imagemagick.org/discourse-server/viewtopic.php?t=29789" rel="noopener noreferrer"&gt;https://www.imagemagick.org/discourse-server/viewtopic.php?t=29789&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Effectively it resizes the image in memory to 1px by 1px, then extracts the RGB value&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;convert celtae.png &lt;span class="nt"&gt;-scale&lt;/span&gt; 1x1&lt;span class="se"&gt;\!&lt;/span&gt; txt:- | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1
0,0: &lt;span class="o"&gt;(&lt;/span&gt;76,30,13&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;#4C1E0D  srgb(29.6631%,11.7692%,4.93835%)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The full script here effectively renames each file to extracted RGB value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.png
&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;convert &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="nt"&gt;-scale&lt;/span&gt; 1x1&lt;span class="se"&gt;\!&lt;/span&gt; txt:- | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1 | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;|cut &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="se"&gt;\)&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;|awk &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="se"&gt;\,&lt;/span&gt; &lt;span class="s1"&gt;'{print $1$2$3}'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;

  &lt;span class="nv"&gt;extension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;".png"&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$filename$extension&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;random&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$RANDOM&lt;/span&gt; % 10 + 1 | bc&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$filename$random&lt;/span&gt;
  &lt;span class="k"&gt;done

  &lt;/span&gt;&lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="nv"&gt;$filename$extension&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now I have a directory of images that are ordered by the filename (RGB value) by default. We can now use &lt;code&gt;ffmpeg&lt;/code&gt; to convert our images to into a video, each image represents a frame and we can set our framerate to 18 in order to fit everything into 60 seconds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.png | ffmpeg &lt;span class="nt"&gt;-framerate&lt;/span&gt; 18 &lt;span class="nt"&gt;-f&lt;/span&gt; image2pipe &lt;span class="nt"&gt;-i&lt;/span&gt; - &lt;span class="nt"&gt;-c&lt;/span&gt;:v libx264 &lt;span class="nt"&gt;-r&lt;/span&gt; 30 &lt;span class="nt"&gt;-pix_fmt&lt;/span&gt; yuv420p output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is our &lt;code&gt;output.mp4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The final version needed a few tweaks, so I imported the final mp4 into &lt;a href="https://www.blackmagicdesign.com/uk/products/davinciresolve" rel="noopener noreferrer"&gt;DaVinci Resolve&lt;/a&gt; added a few overlay images but here it is.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Y6iSFTCtb4I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That was a fun, can you spot any games you are looking forward to? I can pick a few of them out and recognise but 18 frames per second is a bit unsettling. &lt;/p&gt;

&lt;p&gt;If you like boardgames this is &lt;a href="//youtube.com/iplayred?sub_confirmation=1"&gt;I Play Red&lt;/a&gt;, if you're in Germany and not at &lt;a href="https://rubyonrails.org/world" rel="noopener noreferrer"&gt;Rails World&lt;/a&gt; then you could do worse than to check out &lt;a href="https://www.spiel-essen.de/en/" rel="noopener noreferrer"&gt;Spiel&lt;/a&gt;. It's a little bit enormous, and a spectacle and with 1,100 releases this year you'll find something that appeals.&lt;/p&gt;

&lt;p&gt;I'd love to see how other people are programmatically creating video content for some further inspiration.&lt;/p&gt;

</description>
      <category>bash</category>
      <category>imagemagick</category>
      <category>ruby</category>
      <category>ffmpeg</category>
    </item>
    <item>
      <title>Measuring Success</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Mon, 10 Apr 2023 18:41:32 +0000</pubDate>
      <link>https://dev.to/braindeaf/measuring-success-53bg</link>
      <guid>https://dev.to/braindeaf/measuring-success-53bg</guid>
      <description>&lt;p&gt;Much of the work I’ve been doing over the past 10 years has been taking older systems and keeping them current. My first Rails gig was to move hundreds of thousands of users and their services from two older systems effectively white labelled brands written in Perl (CGI) into one new stonking system under just one of those brands. You have to keep your eye on the ball, technology changes and you have to keep up. Anyone still doing web development with Perl are probably thin on the ground now products will have died and the people that wrote them moved onto better things.&lt;/p&gt;

&lt;p&gt;Hell, even when you choose a language like Ruby things change all the time and code needs nurturing. This is often burying my head in code quality improvements both in terms of legibility and performances. You make code more legible and when you do you spot things that can turn a controller action from making stupid amounts of database queries to 2 queries for example. As a side-note I sometimes get so buried in these things that when it comes to doing the simple stuff I have to refresh things I haven’t touched in a year. Like how the hell do I set up a collection_select. That aside, this work to some might seem monotonous but I love it.&lt;/p&gt;

&lt;p&gt;But as with many refactoring and upgrading tasks, its hard to prove it’s worth to your average outsider. Yeah, I worked really hard on this thing guys and if you look hard enough you’ll see there is less code and less network traffic too and from our DB server. Blank faces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OLyorUJL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wiuy98qe9vh399j7emcj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OLyorUJL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wiuy98qe9vh399j7emcj.jpeg" alt="Image description" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, that’s not strictly true we have a great team at SARD who understand that we’re not just sitting pretty drink cups of tea and kicking a can down the street. It’s important to know when you’ve made successful leaps in productivity and that has had a purpose. In my case my last piece of work was a means to an end to unlock a blocked upgrade.&lt;/p&gt;

&lt;p&gt;It is however intensely satisfying to see a measure of success and today that was to show that on this application the average request from is down from 1500ms to 800ms. Boom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QvSxyhNi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jzn8vuull0rc89zwrvr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QvSxyhNi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jzn8vuull0rc89zwrvr.jpg" alt="Image description" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Always end with a graph with Caramel brown in it.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>newrelic</category>
      <category>performance</category>
      <category>rails</category>
    </item>
    <item>
      <title>Mission to watch Stephen King in order.</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Fri, 07 Apr 2023 21:14:06 +0000</pubDate>
      <link>https://dev.to/braindeaf/mission-to-watch-stephen-king-in-order-1b79</link>
      <guid>https://dev.to/braindeaf/mission-to-watch-stephen-king-in-order-1b79</guid>
      <description>&lt;p&gt;A new mission. We need to watch all of the Stephen King adaptations in order of release. It's all on &lt;a href="https://stephenking.com/works/movie/index.html"&gt;https://stephenking.com/works/movie/index.html&lt;/a&gt; but I want to pull each title into a spreadsheet. So I'm going to knock up a quick script to extract all of the movies in order.&lt;/p&gt;

&lt;p&gt;The markup on the page is quite nice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"works-inner"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/works/movie/carrie.html"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row work"&lt;/span&gt; &lt;span class="na"&gt;data-date=&lt;/span&gt;&lt;span class="s"&gt;"1976-0-03, "&lt;/span&gt; &lt;span class="na"&gt;data-sort=&lt;/span&gt;&lt;span class="s"&gt;"Carrie"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-12 col-sm-6 works-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Carrie&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6 col-sm-3 works-type"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Movie&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6 col-sm-3 works-date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;November 03rd, 1976&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/works/movie/shining.html"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row work"&lt;/span&gt; &lt;span class="na"&gt;data-date=&lt;/span&gt;&lt;span class="s"&gt;"1980-0-23, "&lt;/span&gt; &lt;span class="na"&gt;data-sort=&lt;/span&gt;&lt;span class="s"&gt;"Shining, The"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-12 col-sm-6 works-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;The Shining&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6 col-sm-3 works-type"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Movie&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6 col-sm-3 works-date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;May 23rd, 1980&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can grab the markup quite easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'open-uri'&lt;/span&gt;

&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://stephenking.com/works/movie/index.html'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, but I want to parse it. I can use Nokogiri to extract the data I need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'nokogiri'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'open-uri'&lt;/span&gt;

&lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Nokogiri&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://stephenking.com/works/movie/index.html'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use &lt;em&gt;.css&lt;/em&gt; method to extract all matches for the CSS selector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.work'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each link has a selector of work and inside that we have a div each with a convenient selector for the data we want&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.work'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.works-title'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.works-date'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's great but I want to sort by the date of release. Ruby copes with Dates and Times sure. But Rails has some handy convenience extensions provided by &lt;em&gt;active_support&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'November 03rd, 1976'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Wed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt; &lt;span class="no"&gt;Nov&lt;/span&gt; &lt;span class="mi"&gt;1976&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not every value is actually a date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TBD'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`parse': invalid date (Date::Error)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use a quick &lt;em&gt;rescue&lt;/em&gt;. This is horrid but this is a quick script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;012&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TBD'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then sort our records by the date. Here's the full script. It works a treat.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_support'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'nokogiri'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'open-uri'&lt;/span&gt;

&lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Nokogiri&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://stephenking.com/works/movie/index.html'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.work'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.works-title'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.works-date'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="no"&gt;Carrie&lt;/span&gt;
&lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="no"&gt;Shining&lt;/span&gt;
&lt;span class="no"&gt;Creepshow&lt;/span&gt;
&lt;span class="no"&gt;Cujo&lt;/span&gt;
&lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="no"&gt;Dead&lt;/span&gt; &lt;span class="no"&gt;Zone&lt;/span&gt;
&lt;span class="no"&gt;Christine&lt;/span&gt;
&lt;span class="no"&gt;Children&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="no"&gt;Corn&lt;/span&gt;
&lt;span class="no"&gt;Cat&lt;/span&gt;&lt;span class="s1"&gt;'s Eye
Silver Bullet
Maximum Overdrive
Stand By Me
Creepshow 2
The Running Man
Pet Sematary (1989)
Tales from the Darkside: The Movie
Graveyard Shift
Misery
Sleepwalkers
The Dark Half
Needful Things
The Shawshank Redemption
The Mangler
Dolores Claiborne
Thinner
The Night Flier
Apt Pupil
The Green Mile
Hearts in Atlantis
Dreamcatcher
Secret Window
Riding the Bullet
1408
The Mist
Dolan'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="no"&gt;Cadillac&lt;/span&gt;
&lt;span class="no"&gt;Mercy&lt;/span&gt;
&lt;span class="no"&gt;A&lt;/span&gt; &lt;span class="no"&gt;Good&lt;/span&gt; &lt;span class="no"&gt;Marriage&lt;/span&gt;
&lt;span class="no"&gt;Cell&lt;/span&gt;
&lt;span class="no"&gt;My&lt;/span&gt; &lt;span class="no"&gt;Pretty&lt;/span&gt; &lt;span class="no"&gt;Pony&lt;/span&gt;
&lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="no"&gt;Dark&lt;/span&gt; &lt;span class="no"&gt;Tower&lt;/span&gt;
&lt;span class="no"&gt;IT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="no"&gt;Part&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;The&lt;/span&gt; &lt;span class="no"&gt;Losers&lt;/span&gt;&lt;span class="s1"&gt;' Club
Gerald'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="no"&gt;Game&lt;/span&gt;
&lt;span class="mi"&gt;1922&lt;/span&gt;
&lt;span class="no"&gt;Pet&lt;/span&gt; &lt;span class="no"&gt;Sematary&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;IT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Chapter&lt;/span&gt; &lt;span class="no"&gt;Two&lt;/span&gt;
&lt;span class="no"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="no"&gt;Tall&lt;/span&gt; &lt;span class="no"&gt;Grass&lt;/span&gt;
&lt;span class="no"&gt;Doctor&lt;/span&gt; &lt;span class="no"&gt;Sleep&lt;/span&gt;
&lt;span class="no"&gt;Firestarter&lt;/span&gt;
&lt;span class="no"&gt;Mr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="no"&gt;Harrigan&lt;/span&gt;&lt;span class="s1"&gt;'s Phone
The Girl Who Loved Tom Gordon
Hearts
Suffer the Little Children
Salem'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="no"&gt;Lot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I guess we're starting with Brian De Palma's Carrie.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>stephenking</category>
      <category>nokogiri</category>
    </item>
    <item>
      <title>Petty Annoyances #4929</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Fri, 24 Mar 2023 18:26:25 +0000</pubDate>
      <link>https://dev.to/braindeaf/petty-annoyances-4929-51a9</link>
      <guid>https://dev.to/braindeaf/petty-annoyances-4929-51a9</guid>
      <description>&lt;p&gt;Not every Rails app is run on port 3000, if you're fortunate enough to be managing more than one application over the course of your work you may well have a server boot script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
rails server &lt;span class="nt"&gt;-b&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7000 &lt;span class="nt"&gt;-u&lt;/span&gt; puma
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running apps on 3000, 4000, 5000, 6000, 7000, and beyond. That's plenty of apps. And then one day you get...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FnW6GXsz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfk08kgztdlsck83988a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FnW6GXsz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfk08kgztdlsck83988a.png" alt="Image description" width="800" height="297"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Address already &lt;span class="k"&gt;in &lt;/span&gt;use - &lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s2"&gt;"0.0.0.0"&lt;/span&gt; port 7000 &lt;span class="o"&gt;(&lt;/span&gt;Errno::EADDRINUSE&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'd be forgiven for thinking that you're already running the app in another tab, that's happened before. Nope...&lt;/p&gt;

&lt;p&gt;Well, we can &lt;code&gt;netstat&lt;/code&gt; and take a look. This is a trimmed down result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rl@Robs-MacBook-Pro-2 someapp % netstat -ant | grep LISTEN
tcp6       0      0  *.5000                 *.*                    LISTEN     
tcp4       0      0  *.5000                 *.*                    LISTEN     
tcp6       0      0  *.7000                 *.*                    LISTEN     
tcp4       0      0  *.7000                 *.*                    LISTEN     
tcp4       0      0  *.443                  *.*                    LISTEN     
tcp4       0      0  *.80                   *.*                    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep it's running as well as something else on port 5000. 443 and 80 (that's &lt;code&gt;puma-dev&lt;/code&gt;). So ports 5000, 7000 are running even though I know the apps that are assigned those ports aren't.&lt;/p&gt;

&lt;p&gt;Well, I won't keep the suspense. It's Apple AirPlay. If you go to System Preferences &amp;gt; Sharing, you'll it running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--67rHh03D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6dqejdkdye9rm1zo09o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--67rHh03D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u6dqejdkdye9rm1zo09o.png" alt="Image description" width="800" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Untick that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rl@Robs-MacBook-Pro-2 someapp % netstat -ant | grep LISTEN
tcp4       0      0  *.443                  *.*                    LISTEN     
tcp4       0      0  *.80                   *.*                    

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now our app boots unhindered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rl@Robs-MacBook-Pro-2 someapp % ./bin/server                    
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Booting Puma
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Rails 6.1.7 application starting &lt;span class="k"&gt;in &lt;/span&gt;development 
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Run &lt;span class="sb"&gt;`&lt;/span&gt;bin/rails server &lt;span class="nt"&gt;--help&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;more startup options
&lt;span class="o"&gt;[&lt;/span&gt;DEPRECATED] ActiveSupportBackports should no longer be needed. Please remove!
Puma starting &lt;span class="k"&gt;in &lt;/span&gt;single mode...
&lt;span class="k"&gt;*&lt;/span&gt; Puma version: 5.4.0 &lt;span class="o"&gt;(&lt;/span&gt;ruby 2.7.6-p219&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Super Flight"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt;  Min threads: 5
&lt;span class="k"&gt;*&lt;/span&gt;  Max threads: 5
&lt;span class="k"&gt;*&lt;/span&gt;  Environment: development
&lt;span class="k"&gt;*&lt;/span&gt;          PID: 18359
&lt;span class="k"&gt;*&lt;/span&gt; Listening on http://0.0.0.0:7000
Use Ctrl-C to stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>rails</category>
      <category>ruby</category>
      <category>puma</category>
    </item>
    <item>
      <title>The answer is 42</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Wed, 08 Mar 2023 19:23:36 +0000</pubDate>
      <link>https://dev.to/braindeaf/the-answer-is-42-31ne</link>
      <guid>https://dev.to/braindeaf/the-answer-is-42-31ne</guid>
      <description>&lt;p&gt;I have been working on an internal project recently to plot the gem interdependencies of a project that has very limited version requirements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'somegem'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'somegem-with-some-extended-feature'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'someothergem'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'somegem-with-something-thats-broken-no-really'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can plot the interdependencies of this project, I can take a look at the Gemfile.lock and at a given point in time (at the point it was last bundled) that the project had those dependencies. This includes the sub-dependencies (which as we all know can be a laundry list). But this is a goal post that changes all the time. If I want to plot over time what a projects dependencies are it needs to be against something static. But in an ecosystem where software is being updated constantly what are those checkpoints? Gemfile.lock?&lt;/p&gt;

&lt;p&gt;If I am constantly bundling in development the Gemfile.lock is always changing. If I commit my repo without a Gemfile.lock at all, the state of the dependencies is highly unpredictable. So for a project for sanity we lock it down and commit our Gemfile.lock so we know what we are deploying and it's predictable and can be deployed with a degree of confidence in what we are deploying in terms of bundled gems.&lt;/p&gt;

&lt;p&gt;But suppose this was a third-party gem that we are building. There is no Gemfile.lock or not one we should be committing. We have a fluid set of dependencies, the inter-dependencies can change all the time with every release of our above gems and their own interdependencies. Sure, when our gem is embedded in a project, that project has a Gemfile.lock, etc each project should be have the same versioned gem dependencies no matter how many instances of that project are deployed. We can capture the state of the dependencies on project by graphing each Gemfile.lock over time.&lt;/p&gt;

&lt;p&gt;But when it comes to gems that don't have a Gemfile.lock this is forever changing and there is no fixed checkpoint at all. You can't rely on a say a semantic version update because any unlocked dependencies still change over time.&lt;/p&gt;

&lt;p&gt;This begs the question, what exactly am I trying to graph or even prove. At the very least it proves that the we're trying to graph and understand our ecosystem and we can't do that without bringing it into some kind of order first.&lt;/p&gt;

&lt;p&gt;I did learn today that you can discretely update a single gem without updating it's dependencies. I wonder if we can limit this conservative approach to a group of gems from a single source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle update --conservative m3ta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My project started as a fairly simple objective but that objective has just raised more questions than I think it can answer without further clarification or acceptance that the result will be flawed. So I can conclude the answer is 42.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>planning</category>
      <category>rubygems</category>
      <category>bundler</category>
    </item>
    <item>
      <title>JBuilder Arrays and non-collections</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Tue, 07 Mar 2023 17:03:22 +0000</pubDate>
      <link>https://dev.to/braindeaf/jbuilder-arrays-and-non-collections-2i9k</link>
      <guid>https://dev.to/braindeaf/jbuilder-arrays-and-non-collections-2i9k</guid>
      <description>&lt;p&gt;JBuilder may not be the most efficient way to present an API but for simple cases it works pretty well. Our JSON-API standardized API could return the current authenticated user like so.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;&lt;code&gt;show.json.jbuilder&lt;/code&gt;&lt;/em&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'users'&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:full_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;em&gt;&lt;code&gt;GET /api/v1/me&lt;/code&gt;&lt;/em&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1a2b3c4d000001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aaaaaaaabbbbbbbbccccccccc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rob.lacey@buttonmoon.co.uk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"full_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mr Rob Lacey"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ideally I want to now add an included block so that can included related objects such as Tenant. Something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1a2b3c4d000001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"aaaaaaaabbbbbbbbccccccccc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rob.lacey@buttonmoon.co.uk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"full_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Mr Rob Lacey"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"included"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tenants"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"attributes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"superadmin"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of the JBuilder examples talk in terms of Arrays of objects being built from a collection. Most of the time they probably are.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array!&lt;/span&gt; &lt;span class="vi"&gt;@comments&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;marked_as_spam_by?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first_name&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first_name&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last_name&lt;/span&gt; &lt;span class="n"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last_name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Or&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array!&lt;/span&gt; &lt;span class="vi"&gt;@people&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But not always. If we want to add an array that is made up or arbitrary builder blocks, you find yourself thinking in terms of doing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant_id&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'tenants'&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant_id&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'tenants'&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither of which work, turns out the way to do it is using the undocumented child! method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'users'&lt;/span&gt;
  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:full_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;child!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant_id&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt; &lt;span class="s1"&gt;'tenants'&lt;/span&gt;
      &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think I’ll do a pull request for the README as this took me a while to work out. &lt;a href="https://github.com/rails/jbuilder/pull/507"&gt;https://github.com/rails/jbuilder/pull/507&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>jbuilder</category>
    </item>
    <item>
      <title>Warnings / I just live here</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Mon, 06 Mar 2023 11:16:36 +0000</pubDate>
      <link>https://dev.to/braindeaf/warnings-i-just-live-here-5abe</link>
      <guid>https://dev.to/braindeaf/warnings-i-just-live-here-5abe</guid>
      <description>&lt;p&gt;I remember distinctly returning home to our flat and finding what can only be described as &lt;code&gt;something horrible&lt;/code&gt; all over the front door of the shared entrance. We armed ourselves with rubber gloves, bleach, and a bucket and set about cleaning it up. As we did another person who lived in the block walked and said 'oh, yes I saw that. But &lt;em&gt;I just live here&lt;/em&gt;' and wandered off.&lt;/p&gt;

&lt;p&gt;I just live here. Well, so do we. We all live and breath our code and we are the caretakers of it. We like to check in on it from time to time. And we should listen to it.&lt;/p&gt;

&lt;p&gt;Sometimes it's trying to tell us something. I know we're told to often keep our tickets / tasks limited to the task at hand and don't go off on a wild goose chase to Rubocop every single file in the application when you were only supposed to  bump a gem version. But everytime we do a piece of work, it's not a bad idea to go in a fix the things our application is complaining about. Hell. Many of them tell you exactly how to fix them.&lt;/p&gt;

&lt;p&gt;Today I saw this and we can all do with a world with less noise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Randomized with seed 11034
.................************************************************************************
Warning from shoulda-matchers:

The `with` qualifier on `define_enum_for` is deprecated and will be
removed in the next major release. Please use `with_values` instead.
************************************************************************
.************************************************************************
Warning from shoulda-matchers:

The `with` qualifier on `define_enum_for` is deprecated and will be
removed in the next major release. Please use `with_values` instead.
************************************************************************
......................************************************************************************
Warning from shoulda-matchers:

The `with` qualifier on `define_enum_for` is deprecated and will be
removed in the next major release. Please use `with_values` instead.
************************************************************************
...........

/Users/rl/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/faker-2.22.0/lib/helpers/unique_generator.rb:21: Passing `number` with the 1st argument of `alphanumeric` is deprecated. Use keyword argument like `alphanumeric(number: ...)` instead.

To automatically update from positional arguments to keyword arguments,
install rubocop-faker and run:

rubocop \
  --require rubocop-faker \
  --only Faker/DeprecatedArguments \
  --auto-correct

Finished in 4.41 seconds (files took 10.26 seconds to load)
51 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is easily fixed, and no one was hurt in the process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff --git a/lib/blah/factories/some_model_or_something.rb b/lib/blah/factories/some_model_or_something.rb
index 65ccf6e..58752f8 100644
--- a/lib/blah/factories/some_model_or_something.rb
+++ b/lib/blah/factories/some_model_or_something.rb
@@ -2,7 +2,7 @@

 FactoryBot.define do
   factory :some_model_or_something do
-    name { Faker::Alphanumeric.unique.alphanumeric(7) }
+    name { Faker::Alphanumeric.unique.alphanumeric(number: 7) }
     categories { FactoryBot.create_list(:some_model_or_something, 1) }
     parent_id { nil }
   end

diff --git a/spec/models/some_model_or_something_spec.rb b/spec/models/some_model_or_something_spec.rb
index cec65ff..007a77a 100644
--- a/spec/models/some_model_or_something_spec.rb
+++ b/spec/models/some_model_or_something_spec.rb
@@ -34,14 +34,14 @@ RSpec.describe SomeModelOrSomething, type: :model do 
     describe "somthing" do
       it {
         should define_enum_for(:button_alignment)
-          .with([:centre, :left, :right])
+          .with_values([:centre, :left, :right])
       }
     end
   end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I feel like I've added a few months to my life as this no longer causes stress. &lt;em&gt;I just live here&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to smash that interview</title>
      <dc:creator>RobL</dc:creator>
      <pubDate>Fri, 03 Mar 2023 14:37:52 +0000</pubDate>
      <link>https://dev.to/braindeaf/how-to-smash-that-interview-1nmb</link>
      <guid>https://dev.to/braindeaf/how-to-smash-that-interview-1nmb</guid>
      <description>&lt;p&gt;Ask questions, lots of them.&lt;/p&gt;

&lt;p&gt;It's the end of a rather nice interview and the MD of &lt;em&gt;YourPerfectJobProbably.com&lt;/em&gt; says do you have any questions? You panic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5eNpKpR3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v703f707c3fja3y0pfdw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5eNpKpR3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v703f707c3fja3y0pfdw.jpeg" alt="Ask questions, lots of them" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are always questions, so I'll chuck out some.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why are you hiring now? (Growth/Expansion/Last developer decided they wanted to be an astronaut)&lt;/li&gt;
&lt;li&gt;What projects are you working on&lt;/li&gt;
&lt;li&gt;What does your tech / deployment stack look like?&lt;/li&gt;
&lt;li&gt;What is your typical developer day (70% writing code, 10% meetings, 20% code review)&lt;/li&gt;
&lt;li&gt;What are the working hours?&lt;/li&gt;
&lt;li&gt;What's the biggest challenge to the business&lt;/li&gt;
&lt;li&gt;Do you have any Technical Debt? How much of that is a priority?&lt;/li&gt;
&lt;li&gt;Do you think I would be a good fit for the team?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best comedians out there have a tool in their arsenal, it's a callback. If you're paying attention at the beginning of a show and that sly quip comes back again later in the performance and you notice it. That's for you, because you've been paying attention. You win an ice cream.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It wouldn't spoil the line of a tight fitting cagoule or poncho - Harry Hill&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Always, always, show that you've been paying attention. Not because you're playing a game but because you have been.&lt;/p&gt;

&lt;p&gt;Oh and never ever ask.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many days holiday are there&lt;/li&gt;
&lt;li&gt;How much are you going to offer me&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oh and if they ask you what you want to be doing in 5 years time&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I love code, I live and breathe it, you can't eat it that would be silly and given the choice of writing code and sitting in meetings for 60% of my life I'd choose code every time. In fact talking to you is taking away from my coding time. I definitely don't want your job, your job is your job.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Definitely don't say&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will be doing your job (while you are unemployed and living under a bridge because I am so brilliant. I love code so much that I want to not be doing it in 5 years).&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>interview</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
