Issue #9 - 5-11 September 2022

The one about organizing code

Hello,

I’m Lucian (@lucianghinda on Twitter), and I am the curator of this newsletter.

Last week I launched Code Summaries, where I summarise technical articles about Ruby with code.

If you want to see a short version of this newsletter with only the content that has code, you can see it here. It is a presentation that has one tweet per slide uploaded to speakerdeck.com. 

This edition was created with support from @adrianthedev from Avo for Ruby on Rails (a friendly full-featured Rails admin panel) and from @jcsrb, who sent me recommendations to include in the newsletter.

If you have any feedback or ideas about this newsletter, please reach out on Twitter or via email at [email protected]

πŸ‘‰ Xavier Noria shared a short explanation of how constants work in Ruby:

Unlike variables, constants in Ruby are not their identifiers, but entries in a map conceptually stored in class and module objects. For example, Object.const_set(:X, 1) creates a constant, and Object.const_get(:X) # => 1 retrieves it. No bare `X` was involved, see?

Constant identifiers and constant paths are just convenient interfaces into those maps. Helpful for common usage, and for giving the illusion of namespaces. The constants API gives a direct access to those maps, and allows other things like listing or deleting, for example. - Xavier Noria

πŸ‘‰ Thiago Massa shared a new example of pattern matching with hashes:

If you are a Ruby dev and not yet enchanted by my previous pattern matching tweets... Be prepared for my most powerful spell. πŸ§™β€β™€οΈ Do you remember when you've first saw how powerful Regexps were? And magical? πŸͺ„βœ¨πŸ’Ž Pattern matching=Regexp for Data structures.

He also shared the gist in case you want to play with it.

πŸ‘‰ Shino Kouda shared a short code example of .map(&:to_s) and Brandon Weaver explain more in depth how this works:

For those wondering what this does: Ampersand (&) is `to_proc`, translating to `:to_s.to_proc` which is equivalent to the following block function: -> v { http://v.to_s } This works with any method that takes no arguments.

πŸ‘‰ Thiago Massa shared an example of how to use the Pin operator (^) pattern matching:

Do you know why the new Pin operator(^) was added to Ruby? πŸ€” What does it do? It's a strange operator. Only when I tried to use pattern matching based on a dynamic variable that I understood its usefulness. πŸ‘‡ Check this example and learn about it!

πŸ‘‰ Joel Drapper shared an example of another underused operator, XOR:

Using the XOR operator like this is really concise, and is usually clearly explained by the error message. If not, a quick search for β€œruby ^ operator” reveals what it does.

πŸ‘‰ Lucian Ghinda shared another example of using XOR:

Here is also an example of a production code that I wrote in a project a while ago in the context of dry-validation: rule(:after, :status) do if key? unless has_one_or_the_other?(values, :status, :after) key.failure("cannot filter by after and status at the same time") end end end private def has_one_or_the_other?(values, key1, key2) values.key?(key1) ^ values.key?(key2) end

But you should read the entire thread, as it has some excellent discussions about using these operators.

πŸ‘‰ Kirill Shevchenko shared two code samples explaining how |= is creating a new array instead of adding to the existing one:

|= assignment operator in #ruby (which is actually a short form of a=a | b) creates a new one array instead of adding value to an existing one, unlike push

πŸ‘‰ JoΓ«l Quenneville shared code about how to generate infinite series with Enumerator:

#Ruby's Enumerator.produce is a really cool method! It can generate an infinite series where each item is used to calculate the next. ✨ For example the series of even numbers

As the produce cannot be used to generate series where the input from each step needs the output of the previous step, then he showed how to add unfold to the Enumerator to achieve more:

And here is how he showed how to use that:

There are more examples shared in that thread.

πŸ‘‰ Lucian Ghinda shared a thread about an opinionated way to learn Ruby:

Here is a simple and opinionated way to learn Ruby I think learning Ruby has three parts: 1. Ruby Syntax 2. OOP + SOLID in Ruby 3. Idiomatic Ruby What follows assumes you already know how to program in any other programming language.

πŸ‘‰ Emmanuel Hayford asked a smart question: How to explain Class.class being Class:

How would you, *in one sentence*, explain this to a neophyte Rubyist in a way they'll understand without questions?

πŸ‘‰ Brandon Weaver shared an experimental piece of code to implement proc_line:

I should probably feel bad about this, but I don't. ALT gist: https://gist.github.com/baweaver/8c82642be77f99c943ea474751f64e05

πŸ‘‰ Joel Drapper shared an example of how to use Phlex with ERB:

Here’s a better example of what it might look like to use a Phlex component in an existing ERB view (ActionView or ViewComponent). This is borrowing the tabs component from the https://t.co/geJjRUmxq9 documentation.

πŸ‘‰ Jean Boussier shared their process to improve performance on string interpolation. Amazing read!

First step a micro benchmark to have a right idea of the situation. Interpolation somehow takes about 1.75x longer.

πŸ‘‰ Kevin Newton shared a quick command to help understand Ruby TRICK entries published by Yusuke Endoh here:

If you want to better understand the entries for Ruby TRICK this year, run: gem install syntax_tree stree write '**/entry.rb' Then you'll be able to read it much more easily. (Except 04-tompng, which does weird things with syntax...)

πŸ‘‰ Robby Russell asked what is one main improvement for speeding up tests and received some very good answers.

Aside from deleting all of your existing tests, what is one of the smallest changes that you made to speed up your automated test suite in a Ruby on Rails app?

Here are some of the responses shared by Brandon Weaver, Greg Navis, Konnor Rogers, Andrey Novikov, Benjamin Silva H, Andrew Ek, but please do go and read the entire conversation:

> Turning database cleaner down or off entirely, and making sure tests aren't polluting each other. I've seen that drop test times by > 80% before. (source: [@keystonelemur](https://twitter.com/keystonelemur/status/1568443211529752576?s=21&t=1Swh-mDlfNdSl2FrIUyKcA)) > You can move the database to a memory based file system (source: [@gregnavis](https://twitter.com/gregnavis/status/1568489038025265152?s=21&t=1Swh-mDlfNdSl2FrIUyKcA)) > Does factories -> fixtures count as small? (source: [@RogersKonnor](https://twitter.com/rogerskonnor/status/1568406745323552769?s=21&t=1Swh-mDlfNdSl2FrIUyKcA)) > Disabling logging speeds up tests quite noticeably (source: [@Envek](https://twitter.com/envek/status/1568405606830309376?s=21&t=1Swh-mDlfNdSl2FrIUyKcA)) > Sometimes more junior devs don't realize that in many cases you don't need to create records in order to test them, in many cases you can replace create(: for build(: in factories and it works (source: [@bsilva96](https://twitter.com/bsilva96/status/1567913277748813824?s=21&t=1Swh-mDlfNdSl2FrIUyKcA)) > In many of the codebases I've been in, it's a relatively small number of very slow tests that, if fixed or reworked, can speed up the whole test suite quite a bit. So finding the 5-10 slowest tests and deciding what to do with them can sometimes do the trick. (source: [@ektastrophe](https://twitter.com/ektastrophe/status/1567912675279097862?s=21&t=1Swh-mDlfNdSl2FrIUyKcA))

πŸ‘‰ Thiago Massa asked a question and shared a code sample about the ampersand Ruby idiom:

What's your favorite Ruby idiom? I'll start with mine. Using &(ampersand) to write functional code in Ruby. Methods/function in Ruby aren't first class citizens. But & make them at least second class 🎩. Code becomes shorter & looks great. I'm curious to know yours πŸ‘‡

And along with this question Thiago shared a code sample:

He received some inspiring responses, read the entire conversation. Here are two of them:

Sometimes we just need a shortcut to create a data holder object with keyword argument initializer.

πŸ‘‰ Stan Lo shared a list of feature proposals for Ruby debug:

Since my #rubykaigi talk got some developers interested in ruby/debug, I want to share some feature proposals that can use feedback and discussions

πŸ‘‰ Joel Drapper shared a new update for Phlex.fun showing support for conditional CSS classes:

Phlex.fun now has conditional CSS classes.

πŸ‘‰ Cj Avilla shared code showing how to use right assignment / pattern matching:

I think this Rightward assignment is growing on me=> # Monkey patch module Stripe class StripeObject def deconstruct_keys(keys) @values end end end Stripe::PaymentIntent.create( amount: 100, currency: 'usd' ) => { client_secret: } p client_secret #=> "pi_3LfRKsCZ6_secret_RPlff9ie0"

πŸ‘‰ Matt Swanson shared code about how to use modules to organize features:

Really digging this pattern for organizing different 'features' of a model. Keeps related methods together and makes it easier to find relevant code as the codebase grows. Plus I can separate out test files by feature.

Here are some interesting replies, but I really recommend you to read the entire conversation (for people not using Twitter use this)as it has great sugestions and some great explanation for various styles:

Classes are namespaces. The important point is that object types have to agree: class Post module DueDate end end As Kasper said module Post::DueDate end works too.
For me, Task::Assignment is about extending the Task from within itself, and Tasks::Assignment is about an outside module reaching into Task and extending it with something else. For me, they’re two different things because they’re not about containing both controllers & models.

πŸ‘‰Shino Kouda asked what is the result of executing the following code:

Brandon Weaver shared explaining how [] works for arrays and hashes:

`[]` is a method, `something.[](index)`, so the result would be `"a"`. This is similar to other operators like `1 + 2` is actually `1.+(2)`. That said, not common use, `dig` or `fetch` or `slice` would be more common if you're avoiding `[]` directly.

πŸ‘‰ Kirill Shevchenko shared a code sample about how to use lazy enumerators:

Ruby's lazy enumerators are great. For e.g. you can process the data without iterating through all elements since the loop exits when N elements match the condition

πŸ‘‰ Collin shared a tip about how to require a library when starting IRB:

πŸ‘‰ Joe Masilotti shared a sample code showing how to add a hidden field to the button_to helper:

If you read so far and you like the content, maybe you take into consideration sharing this and subscribe:

Related (but not Ruby specific)

Vinicius Stock shared two VSCode tips for people working with Sorbet:

Two quick VS Code tips for Ruby projects using Sorbet: CMD + SHIFT + O: fuzzy search symbols on a file CMD + T: fuzzy search symbols everywhere

Joe Masilotti πŸ“— shared asked about Ruby and Rails communities and he received a lot of replies:

What are some free Ruby/Rails communities that anyone can join? I know of the GoRails Discord, the new official Hotwired + Rails Discords, and the Stimulus Reflex Discord.

Here are some of the communities shared in the conversation:

New projects built with Ruby

🚒 Julian Rubisch shared that they launched railsreviews.com - Reactive Rails Reviews.

🚒 Jeremy Smith shared launched railsinspire.com - A curated collection of code samples from Ruby on Rails projects.

Articles and Videos

RubyKaigi 2022 slides and more

Yusuke Endoh shared a Cookpad code puzzle that was created for RubyKaigi, but anyone can play it now: https://ruby-puzzles-2022.cookpad.tech

Jeremy Evans shared slides from RubyKaigi presentation: Fixing Assignment Evaluation Order

Koichi ITO shared their slides from RubyKaigi about Making Rubocop Super Fast 

Takashi Kokubun shared their slides from RubyKaigi about Towards Ruby 4 JIT

Courses or Books

πŸ“– Noel Rappin shared that the second version of his book Modern Front-end Developmen for Rails is now updated to work with Rails. Buy it here (PragmaticProgrammers shared on twitter also a discount code)

πŸ“– David Colby shared that they made free their book Hotwired ATS, that is teaching how to build a complex Rails 7 application with Turbo, Stimulus, CableReady and Stimulus Reflex.

Something to read

Newsletters

Any Cable shared a new issue of monthly Any Cable updates: Any Cables Monthly #2 β€” August, 2022

Greg Molnar shared a new edition of This Week in Rails created by Emmanuel Hayford.

Andrew Mason shared they released a new Ruby Radar issue #67 - New Rails Release!

Ruby Libhunt released a new version of their #329 Awesome Ruby newsletter.

Articles

Nate Berkopec shared an article written by Jemma Issroff about how to find faster in a sorted array using bsearch

Something to watch πŸŽ₯ or listen 🎧

Videos

πŸŽ₯ Julian Rubisch shared a video showing how he is using CableReady::Updatable and Turbo forms to implement a previewable text area. See it β†’ Public Building RailsReviews - #1 Preview Component

πŸŽ₯ Vladimir Dementyev shared a new episode of AnyCasts where deploys AnyCable to Fly. See it β†’ Ep. 6: Learn to Fly.io with AnyCable

πŸŽ₯ Hexdevs shared a new episode of Open Source Thursdays about an introduction to how Faker works and how to contribute to it. See it β†’ Let’s Faker Together: a Ruby library for generating fake data

πŸŽ₯ Drifting Ruby shared the video version of This Week in Rails. See eit β†’ This Week in Rails Sept 10th, 2022

Audio & Podcasts

🎧 Drew Bragg shared a new episode about Coding Coders who Code with Ernesto. Listen β†’ Episode 10 - Ernesto Tagwerker

🎧 Therubyonrailspodcast shared a new episode of The Ruby on Rails podcast about RubyConfMini: Listen β†’ Episode 434: All Things RubyConf Mini (Brittany + Jemma)

🎧 Fullstack Ruby shared a new podcast about How to manage ruby apps dependencies. Listen β†’ Episode 6: How do you manage Ruby Application Dependencies

🎧 Ruby For All shared a new episode about programming with ADHD. Listen β†’ Programming with ADHD

🎧 JoΓ«l Quenneville shared a new episode of BikeShed with @EebsKobeissi. Listen β†’ 353: Mental Models

🎧 Remote Ruby shared a new episode about the new Hatchbox.io V2. Listen β†’ Episode 196 β†’ The brand new Hatchbox.io V2

Gems, Libraries, and Updates

Aaron Patterson shared a release of Rack 3.0.0.rc1 and invited anyone to test it. Read the latest Changelog here.

Mike Dalessio shared the latest version of sqlite3 gem is out and it ships with precompiled sqlite. Read the Changelog here

Rob Sanheim shared a gem that helps running parallel_tests:

It will run parallel on multiple CPU cores. ParallelTests splits tests into even groups (by number of lines or runtime) and runs each group in a single process with its own database.

ζˆη€¬ shared that Ruby 3.2 preview 2 is released. See the announcement here. Ruby 3.2 has WASI based WebAssembly support, Regexp timeout, YJIT arm64 support and many more things.

Hiroshi Shibata shared they released Ruby build with support doe Ruby 3.2.0 preview2. See the release

Koichi Ito shared rubocop performance 1.15. Check release notes

Konnor Rogers shared declarative shadow DOM components in Rails. See the code here.

Ruby Lib Hunt shared for creating chains, similar to chaining with then. The source code of this library is here. Here is a code sample:

Michael Nikitochkin shared a new version of the toxiproxy library that is a TCP proxy to simulate network and system conditions for chaos and resilience testing. See the project here and here is an example:

This was a long issue as there was a lot of great content that I discovered in Ruby community. I started to follow what is happening on Reddit communities so I will probably start bringing content from there.

Please consider sharing this on social media or with your colleagues:

Reply

or to participate.