From 4d579d6a174c9c2f008441afad21c6744ce61456 Mon Sep 17 00:00:00 2001 From: George Bell Date: Mon, 9 Jun 2025 10:38:13 +0100 Subject: [PATCH 1/3] Fix PaperMod --- themes/PaperMod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/PaperMod b/themes/PaperMod index df84e2c..5a46517 160000 --- a/themes/PaperMod +++ b/themes/PaperMod @@ -1 +1 @@ -Subproject commit df84e2c6addeb8a6ef1766f2fd8ecc92309d3a22 +Subproject commit 5a4651783fa9159123d947bd3511b355146d4797 From 9249dc729c6208982a4bbb9a18ca5f3d0424d33a Mon Sep 17 00:00:00 2001 From: George Bell Date: Mon, 9 Jun 2025 11:20:20 +0100 Subject: [PATCH 2/3] Add post on double splat nil --- .../2025-06-09-double-splat-nil/index.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 content/posts/2025-06-09-double-splat-nil/index.md diff --git a/content/posts/2025-06-09-double-splat-nil/index.md b/content/posts/2025-06-09-double-splat-nil/index.md new file mode 100644 index 0000000..7f0669d --- /dev/null +++ b/content/posts/2025-06-09-double-splat-nil/index.md @@ -0,0 +1,70 @@ +--- +author: "George Bell" +title: "TiL: Double Splat Nil in Ruby" +description: "What is a Double Splat Nil and how does it help clamp down on unwanted named arguments" +draft: false +date: 2025-06-09 +tags: ["Ruby", "nil", 'double splat', "Today I Learned"] +categories: ["TIL", "Ruby"] +ShowToc: false +TocOpen: false +--- + +# How Ruby can do what you don't expect + +Ruby is a very clever language. It will take the code you've written and do it's best to make sure it runs. Take for example the following method call: + +```ruby +method_one('Hello', param_two: ' world') +``` + +That looks simple enough as it takes two arguments, one positional and one keyword. Now, lets take a look at what the method is actually doing: + +```ruby +def method_one(param_one, param_two) + p param_one, param_two +end +``` + +Interesting. At first glance it might appear that this method would print `Hello world`, but there is a subtle difference between how the method has been defined and how it is called. Let's see what it actually outputs: + +```ruby +"Hello" +{:param_two=>" world"} +``` + +So what is going on here? Well, it's because when we call `method_one` we are incorrectly assuming that `param_two` is a keyword argument and are providing the name alongside the value. This is where Ruby tries to be clever as it transforms that into the hash `{:param_two=>" world"}`, which is not what we were expecting. There are a few ways you can deal with this, but the one this post is about is adding a double splat nil to the end of the list of arguments. + +# Double Splat Nil + +`**nil` might look a bit strange if you haven't seen it before, so lets break it down. A double splat (`**`) is used to indicate that you are expecting a quantity of keyword arguments to be provided when a method is invoked. For example: + +```ruby +def double_splat(**args) + p args +end + +double_splat(arg_one: 123, arg_two: 'Four Five Six', arg_three: 789) +``` + +That prints out the following hash: +```ruby +{:arg_one=>123, :arg_two=>"Four Five Six", :arg_three=>789} +``` + +This has loads of uses, but as we've already seen the conversion into a hash can have unintended consequences. That is where `**nil` comes in. This tells Ruby that we are expected no keyword arguments when this method is called. Let's use this to write a version of `method_one` that doesn't accept keywords: + +```ruby +def method_two(param_one, param_two, **nil) + p param_one, param_two +end +``` + +Now, what happens if we call it with the unexpected positional argument? + +```ruby +method_two('Hello', param_two: ' world') + => no keywords accepted (ArgumentError) +``` + +Success! Now, we get an error raised saying something has been called with a keyword when it shouldn't have been which means we don't have to deal with unexpected hashes. \ No newline at end of file From 364825696ccc8e73fb7236158d3d2b9b2a6855f9 Mon Sep 17 00:00:00 2001 From: George Bell Date: Mon, 9 Jun 2025 11:27:18 +0100 Subject: [PATCH 3/3] Update workflow to use the latest version of Hugo --- .github/workflows/gh-pages.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f5d1022..a1d731d 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -26,9 +26,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: - # should use latest but there is an issue rendering in the index - # https://github.com/dvla/dvla.github.io/issues/22 - hugo-version: "0.119.0" + hugo-version: "latest" # extended: true - name: Build