From 9f9fce7835c595c57ef3c37a0b57e5b48e0b05ca Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Mon, 1 Dec 2025 06:35:43 -0600 Subject: [PATCH] Add Make Structs Easier To Use With Keyword Initialization as a Ruby TIL --- README.md | 3 +- ...sier-to-use-with-keyword-initialization.md | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 ruby/make-structs-easier-to-use-with-keyword-initialization.md diff --git a/README.md b/README.md index 0a44635..5fcbd6e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter). -_1704 TILs and counting..._ +_1705 TILs and counting..._ See some of the other learning resources I work on: @@ -1413,6 +1413,7 @@ If you've learned something here, support my efforts writing daily TILs by - [List The Running Ruby Version](ruby/list-the-running-ruby-version.md) - [Listing Local Variables](ruby/listing-local-variables.md) - [Make An Executable Ruby Script](ruby/make-an-executable-ruby-script.md) +- [Make Structs Easier To Use With Keyword Initialization](ruby/make-structs-easier-to-use-with-keyword-initialization.md) - [Map With Index Over An Array](ruby/map-with-index-over-an-array.md) - [Mock Method Chain Calls With RSpec](ruby/mock-method-chain-calls-with-rspec.md) - [Mocking Requests With Partial URIs Using Regex](ruby/mocking-requests-with-partial-uris-using-regex.md) diff --git a/ruby/make-structs-easier-to-use-with-keyword-initialization.md b/ruby/make-structs-easier-to-use-with-keyword-initialization.md new file mode 100644 index 0000000..e29b60c --- /dev/null +++ b/ruby/make-structs-easier-to-use-with-keyword-initialization.md @@ -0,0 +1,44 @@ +# Make Structs Easier To Use With Keyword Initialization + +Typically a [`Struct`](https://ruby-doc.org/3.4.1/Struct.html#method-c-new) in +Ruby is defined and initialized like so: + +```ruby +> Subscriber = Struct.new(:email, :first_name, :status, :tags) +=> Subscriber +> s1 = Subscriber.new('bob.burgers@example.com', 'Bob', :active, [:food, :family]) +=> # +> s1.email +=> "bob.burgers@example.com" +``` + +That's a nice way to structure light-weight objects. + +A potential challenge with multi-argument `Struct` definitions like this, +especially when they aren't colocated with initialization, is that it can be +hard to remember or distinguish the argument order when initializing an instance +of one. + +Ruby 2.5 added the `keyword_init` option to help with this exact issue. When +that option is set to `true` for a `Struct` definition, then we get to +initialize it with keyword arguments rather than positional arguments. + +```ruby +> Subscriber = Struct.new(:email, :first_name, :status, :tags, keyword_init: true) +=> Subscriber(keyword_init: true) +* s1 = Subscriber.new( +* first_name: 'Bob', +* email: 'bob.burgers@example.com', +* tags: [:food, :family], +* status: :active +> ) +=> # +> s1.email +=> "bob.burgers@example.com" +``` + +Notice I have to use keyword arguments now and that because of that I can +organize them in whatever order makes sense. Coming back to view this line of +code later, it is easy to see attribute each value corresponds to. + +[source](https://www.bigbinary.com/blog/ruby-2-5-allows-creating-structs-with-keyword-arguments)