Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for The raise of minimum-churn style in Ruby
Augusts Bautra
Augusts Bautra

Posted on • Edited on

     

The raise of minimum-churn style in Ruby

TL;DR

  • Add trailing commas everywhere
  • Use consistent indentation
  • Disallow whitespace for formatting/aligning
  • Consider leading dot syntax, YMMW

The story

For me it all started with theannouncement of version 1.0 release of thestandard gem sometime back in March, 2021. Here was a library by the accomplished @searls that pre-configured Rubocop for the benefit of all mankind, and I was eager to imbibe. Perusing the readme, I immediately noticed the "Leading dots on multi-line method chains" point and opened thethread that lead to that decision.

The first argument for adopting the particular approach was that it would reduce the lines highlighted by git as changed if a new call was added to the end of a chain:

# trailing dot, noisyupcase.chars.-drop(1)+drop(1).+reverse# leading dot, quiet.upcase.chars.drop(1)+.reverse
Enter fullscreen modeExit fullscreen mode

I had never really appreciated how last lines in chains like this, and, similarly, last lines in hashes and arrays are made different by the style used.
I had been burned by the occasional missing comma in a hash or array, but always figured aesthetics demand no comma at the end; now there was a good argument, even two, for breaking with aesthetics and instead adopting an approach that favours consistency and results in fewer mistakes and less noise!

# no final comma, inconsistent, very noisy{name:"Bob",faves:[:apples,-:beer+:beer,+:candy-]+],+dislikes:[:radishes]}# final comma, very quiet{name:"Bob",faves:[:apples,:beer,+:candy,],+dislikes:[:radishes],}
Enter fullscreen modeExit fullscreen mode

The same goes for multiline argument lists. Basically in any multiline list where individual entries would be comma-separated, keep adding trailing comma.

data.dig(:properties,0,:rooms,-1,-:size+:size,+:square_meters)data.dig(:properties,0,:rooms,-1,:size,+:square_meters,)
Enter fullscreen modeExit fullscreen mode

Now I was sold. Looking to minimise diff noise was a valid and powerful way to drive style decisions!
I looked through some of my recent commits to see what else produces noise and discovered a surprising fact - whitespace was the number one culprit for noise. It results from whitespace being used for alignment, thus tying several lines together, and sometimes change in one line demands changes in all. Extreme noise ensues.

An example with often-seen style where arbitrary leading whitespace is allowed (this sometimes even produces odd-numbered space indent, yuck!). Only the class name is changed, but it's impossible to easily tell. Good style setup should constrain any line to beingat most one level deeper than the previous line.

-SomeClass.where(vip:true)-.where(local:false)-.where(name:"Jack",-title:"mr",)+SomeOtherClass.where(vip:true)+.where(local:false)+.where(name:"Jack",+title:"mr",)# contrast with consistent indentation approach-SomeClass+SomeOtherClass.where(vip:true).where(local:false).where(name:"Jack",title:"mr",)
Enter fullscreen modeExit fullscreen mode

An example with often-seen arbitrary options hash alignment. Having consistent indentation and requiring that options hash starts on its own line also improves readability as to where positional args end and kwargs/options begin.

FactoryBot.build_stubbed(-:some_model,:full_build,vip:true-best:true+:some_model,:no_build,vip:true+best:true)# contrast with consistent indentationFactoryBot.build_stubbed(-:some_model,:full_build,+:some_model,:no_build,vip:truebest:true)
Enter fullscreen modeExit fullscreen mode

And an example with aligned hashes, what got changed? (hint, a new longest key appeared)

{-the_longest_key:"value",-middle_key:"value",-mini_key:"value",+the_longeest_key:"value",+the_longest_key:"value",+middle_key:"value",+mini_key:"value",}# contrast with disallowed whitespace for alignment{+the_longeest_key:"value",the_longest_key:"value",middle_key:"value",mini_key:"value",}
Enter fullscreen modeExit fullscreen mode

The cops

This is not an exhaustive list, created with Rubocop v1.22 in mind. The settings provided should reduce whitespace abuses and add commas everywhere.

Layout/ArgumentAlignment:  EnforcedStyle: with_fixed_indentationLayout/ArrayAlignment:  EnforcedStyle: with_fixed_indentationLayout/ExtraSpacing:    Enabled: true    AllowForAlignment: false    AllowBeforeTrailingComments: true   ForceEqualSignAlignment: falseLayout/ParameterAlignment:  EnforcedStyle: with_fixed_indentationLayout/SpaceAroundOperators:  AllowForAlignment: false  EnforcedStyleForExponentOperator: no_space  Style/TrailingCommaInArguments:    EnforcedStyleForMultiline: consistent_commaStyle/TrailingCommaInArrayLiteral:   EnforcedStyleForMultiline: consistent_commaStyle/TrailingCommaInHashLiteral:    EnforcedStyleForMultiline: consistent_commaLayout/DotPosition:  EnforcedStyle: leading
Enter fullscreen modeExit fullscreen mode

Addendum

You may also look atLayout/First* cops. Using them withEnforcedStyle: consistent complements alignment cops.

# with only alignmentsome_method(:arg1,:arg2,:arg3,)other_method(arg,key1: :value1,key2: :value2,)# with First* copssome_method(:arg1,:arg2,:arg3,)other_method(arg,key1: :value1,key2: :value2,)
Enter fullscreen modeExit fullscreen mode

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Senior Rails developer from Latvia.Avid gamer. Longevity enthusiast. #keto-dude
  • Location
    Riga, Latvia
  • Education
    College, Unfinished
  • Work
    Software Engineer at UPB AS
  • Joined

More fromAugusts Bautra

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp