2

A common pattern I find myself using in Ruby is the following:

foo = foos.find {|foo| foo.attribute == some_other_attribute }

In IDEs that check for shadowing, that line complains that foo is being shadowed.

A tempting alternative is the following:

foo = foos.find {|f| f.attribute == some_other_attribute }

But that approach breaks the search feature in many IDEs - searching for f within a complicated block is going to be a nightmare and searching for foo.attributes within the project will miss this line of code.

The ugly solution I've been leaning toward is just prefixing the variable name with its scope:

foo = foo.find {|block_foo| block_foo.attribute == some_other_attribute }

While that's fine for short blocks, anything longer starts to generate a lot of noise from all the block_'s polluting the code.

Is there a standard Ruby way of doing this sort of assignment? Specifically, I'm looking for a solution that meets the following criteria:

  • Variable names aren't abbreviated
  • Variable names remain descriptive of what type of object they contain
  • IDEs don't squawk about shadowing

1 Answers1

3

I would prefer making the variable on the left hand side more descriptive:

blue_box = boxes.find { |box| box.color == BLUE }

Even something more generic like found_foo I would consider to be more descriptive.

Zorg
  • 978
  • 6
  • 10
  • 1
    or extract it into a `blue_box` method and skip the assignment :) – Stefan Apr 04 '14 at 16:16
  • I like this. It points out what is special about the particular object in the enumerable. My only concern would be the noise generated by the extra `blue_` everywhere, but maybe using methods for more of that code would reduce that downside. –  Apr 04 '14 at 16:24
  • @LeviStanley Your subject misleading.. You should say, how good I name the variables while in programming... All effort that created, by thinking at the subject and body of question wasted.. That's the problem.. :-) – Arup Rakshit Apr 04 '14 at 18:19
  • @ArupRakshit I wasn't asking how to name a variable. While I think the solution of changing the name of the variable is a very good solution (hence why I marked it as accepted), that doesn't mean I want to bias potential answers down that path. If there is a fundamentally different way to achieve the goal without changing the variable names, I'd very much like to see that as well. –  Apr 04 '14 at 18:23
  • @LeviStanley As Ruby is very smart, following the subject and context of your post, an Ruby expert directly suggest you that - *What you are looking for, our language supports*. After a pause, if you are not *happy*, they can advise you - *you could change the variable name.. in so..so..*... But any way no more reply needed, as you got answer, be happy.. :-) – Arup Rakshit Apr 04 '14 at 18:27
  • @ArupRakshit Your answer contained a lot of valuable information. I'm not sure why you removed it. –  Apr 04 '14 at 19:44
  • 1
    @LeviStanley You can get all what I written from [here](http://books.google.com.sg/books?id=jcUbTcr5XWwC&pg=PA143&lpg=PA143&dq=Ruby+shadow+local+variables&source=bl&ots=fIJmxb7xbH&sig=zbRzduwemnsAM6sTEBRz4k6hcyI&hl=en&sa=X&ei=09A-U5F_6LeJB9H7gYAN&ved=0CDcQ6AEwAg#v=onepage&q=Ruby%20shadow%20local%20variables&f=false). – Arup Rakshit Apr 04 '14 at 19:52
  • Alternatively, you can add an adjective to the block variable, such as "potential" or "candidate", so you'd have `candidate_box`. Kind of like using "block_foo" in the question, but more informative. – Andrew Grimm Apr 01 '15 at 03:24