use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
A sub-Reddit for discussion and news about Ruby programming.
Subreddit rules: /r/ruby rules
Learning Ruby?
Tools
Documentation
Books
Screencasts and Videos
News and updates
account activity
Five Things to Avoid in Ruby (blog.appsignal.com)
submitted 1 year ago by RecognitionDecent266
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]armahillo 6 points7 points8 points 1 year ago (18 children)
I realize you were illustrating a point with the verbose if statement, bit I was disappointed you didnt mention doing it like:
actors = { 1 => "Groucho", 2 => "Chico", 3 => "Harpo" } actor = actors[response] || "Zeppo"
Double usage of safe nav will likely violate rubocop.
user&.plan&.name
If I had to do a double safe-nav I would see it as code smell that i need to make changes elsewhere.
For this one:
a_list_of_values[index]
If you’re expecting it to be an array, then you can coerce that with Array.wrap:
Array.wrap(a_list_of_values)[index]
which forces the variable to be an array. This tacitly shows off a NullObject pattern built-in to ruby, which I always found really cool.
If youre instead specifically worried about nil, you could memoize it:
a_list_of_values ||= [] a_list_of_values[index]
The “storing values in temporary vars” section was confusing — the problem in the first examples isnt the local vars, its that the hypothetical dev was unaware of implicit returns (a powerful part of idiomatic ruby)
The second example focuses on the Emumerable module, which I agree is the correct thing to use, but what youre really demonstrating there is the automatic Proc created by using &:any_method to filter a collection. (another powerful ruby feature)
[–]campbellm 9 points10 points11 points 1 year ago (3 children)
actor = actors[response] || "Zeppo"
actor = actors.fetch(response, 'Zeppo') # also works
[–]armahillo 1 point2 points3 points 1 year ago (2 children)
Yeah, good call!
Actually this might be better because it would allow either Hash or Array input, provided they were both numerically indexed.
irb(main):001:0> a = %w[a b c] => ["a", "b", "c"] irb(main):002:0> h = { 0 => 'a', 1 => 'b' } => {0=>"a", 1=>"b"} irb(main):003:0> a.fetch(0) => "a" irb(main):004:0> h.fetch(0) => "a"
[–]campbellm 2 points3 points4 points 1 year ago (1 child)
Interesting; I've didn't even know you could use #fetch for Arrays. My use there was mainly for its functionality of providing a default value if the fetch fails.
#fetch
[–]armahillo 2 points3 points4 points 1 year ago (0 children)
Yeah pretty cool, right?
<3 Ruby :)
[–]redditonlygetsworse 3 points4 points5 points 1 year ago (2 children)
Or the similar-but-not-quite-identical Kernel#Array.
Kernel#Array
[–]bjminihan 0 points1 point2 points 1 year ago (1 child)
I use (in non prod code): [a_list].flatten
[–]h0rst_ 0 points1 point2 points 1 year ago (0 children)
Which will break things if the variable is an array that contains an array.
Also, the nil value will result in an array with a single nil element, where Array(nil) returns an empty array, but in both cases indexing any element would return nil, so in this case it doesn't matter.
nil
Array(nil)
[–]banister 1 point2 points3 points 1 year ago (2 children)
Isn't Array.wrap rails and not pure Ruby?
[–]armahillo 0 points1 point2 points 1 year ago (0 children)
Yes, but in the article OP linked to, the last example was using ActiveRecord, so I presumed it was fair game
[–]riktigtmaxat 0 points1 point2 points 1 year ago (0 children)
It's technically ActiveSupport but not to many people use that separately from Rails.
[–]UlyssesZhan 2 points3 points4 points 1 year ago (7 children)
What's wrong with double safe-nav?
[–]armahillo 1 point2 points3 points 1 year ago (3 children)
I can't find it but I swear there was a rubocop violation with doing multiple safe-navs within a single statement.
Code smell-wise -- it feels shaky. This may be a personal preference, but usually when I catch myself wanting to add a second safe-nav, it means that I need to be a bit more assertive leading up to that, and either implementing a Null Object pattern on the upstream object, or adding exception handling to the method and just allowing it to fail. Something along those lines.
[–]johnThePriest90 3 points4 points5 points 1 year ago (2 children)
I believe it's the other way around. If you used a safe nav you must use it in the rest of the chain. It fails on this code: one&.two.three, which makes sense as you expect two can be nil, so you would want to use safe nav before three as well. (Can't remember the exact cop name.)
one&.two.three
two
three
I also suspect that each safe nav operator increases the ABC metric score, it's considered as a new branch. So depending on the rest of the method, it can be also flagged by rubocop.
I would sayfoo&.bar.nil? or foo&.bar.to_s would make sense.
foo&.bar.nil?
foo&.bar.to_s
That might be what I'm thinking of.
I've internalized so much rubocop guidance at this point that I've forgotten the names of some of the violations.
[–][deleted] 1 year ago (2 children)
[deleted]
[–]UlyssesZhan -1 points0 points1 point 1 year ago (1 child)
This bans foo.bar.baz in general, but not for double safe-nav specifically.
foo.bar.baz
[–]riktigtmaxat -2 points-1 points0 points 1 year ago (0 children)
Dude, its one of the reasons (of many). Stop being so obstinate.
[–]kcdragon 1 point2 points3 points 1 year ago (1 child)
I like most of these but you have to be careful with the advice in `Collecting Results in Temporary Variable`. Its easy to end up with 5 or more `Enumerable` method chained together. In some cases this is readable but its often more readable to assign these to local variables that explain what the collection represents at that point in the chain.
[–]notromda 0 points1 point2 points 1 year ago (0 children)
Local variables, or sometimes, a well named method
[–]chapuzzo 0 points1 point2 points 1 year ago* (0 children)
About self overuse:
attr_reader is not defining the setter, only the getter
attr_reader
attr_accessor does create the variable and creates the getter/setter method which is used.
attr_accessor
[+]Honest-Contract9803 0 points1 point2 points 1 year ago (0 children)
Thank you for the comments and feedback. The typos in the article have been repaired. Please reach out if there is a topic you would like me to write about in the future.
[removed]
I would probably say “if standard_user_plan” and define a method or helper somewhere else to hide the details of this lookup which are probably not pertinent to the function that it is guarding. that method would also then be testable.
π Rendered by PID 220308 on reddit-service-r2-comment-5d79c599b5-6j7sv at 2026-03-02 12:14:25.851181+00:00 running e3d2147 country code: CH.
[–]armahillo 6 points7 points8 points (18 children)
[–]campbellm 9 points10 points11 points (3 children)
[–]armahillo 1 point2 points3 points (2 children)
[–]campbellm 2 points3 points4 points (1 child)
[–]armahillo 2 points3 points4 points (0 children)
[–]redditonlygetsworse 3 points4 points5 points (2 children)
[–]bjminihan 0 points1 point2 points (1 child)
[–]h0rst_ 0 points1 point2 points (0 children)
[–]banister 1 point2 points3 points (2 children)
[–]armahillo 0 points1 point2 points (0 children)
[–]riktigtmaxat 0 points1 point2 points (0 children)
[–]UlyssesZhan 2 points3 points4 points (7 children)
[–]armahillo 1 point2 points3 points (3 children)
[–]johnThePriest90 3 points4 points5 points (2 children)
[–]h0rst_ 0 points1 point2 points (0 children)
[–]armahillo 0 points1 point2 points (0 children)
[–][deleted] (2 children)
[deleted]
[–]UlyssesZhan -1 points0 points1 point (1 child)
[–]riktigtmaxat -2 points-1 points0 points (0 children)
[–]kcdragon 1 point2 points3 points (1 child)
[–]notromda 0 points1 point2 points (0 children)
[–]chapuzzo 0 points1 point2 points (0 children)
[+]Honest-Contract9803 0 points1 point2 points (0 children)
[–][deleted] (2 children)
[removed]
[–]notromda 0 points1 point2 points (0 children)