4 ms·
There was one thing with block chaining that I was really hoping they'd hit on. They didn't. They had: # good names.select { |name| name.start_with?("S")
by rauljara 14y ago
There was one thing with block chaining that I was really hoping they'd hit on. They didn't. They had:
# good
names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
I've noticed that sort of chaining is changing towards:
names.select { |name| name.start_with?("S") }
.map { |name| name.upcase }
Which can be further chained (if need be) like so:
names.select { |name| name.start_with?("S") }
.map { |name| name.upcase }
.sort
.join(', ')
Which, imo, is just better than trying to do it all on one line or using intermediate variables. It's more of a value call when it comes to the intermediate variables, though. I'd also use
.map(&:upcase)
instead of
.map { |word| word.upcase }
But I think it's perfectly understandable if you find the word.upcase more explicit and readable.
- prawks 14y agoAgreed. I'm no rubyist, but it's not only much more readable, but functionally easier to manage in code. I can easily comment out one or more blocks or methods in the chain in this case if need be, for example. I'm surprised they advocate it on one line, actually.
- deleted 14y ago[deleted]
- edwinnathaniel 14y agoStartin' to look like Java (with its fluent-interface pattern) :). Keep it up! thumbs up
- jordoh 14y agoThis seems to be a popular style in javascript (particularly when using jQuery), but it's not actually valid ruby (edit: ruby 1.8.7, that is - see reply). The first line forms a valid statement, so the dots would need to be at the end of each line to indicate a line continuation. So it would need to be: names.select { |name| name.start_with?("S") }. map { |name| name.upcase }. sort. join(', ') Which is slightly more annoying in that you need to modify two lines to add a new chained line (the line you are adding and the dot added to the previous line). This also creates a mild headache when refactoring, as any change to the length of the "names" variable would force you to re-align the entire chain. You could do something like: names. select { |name| name.start_with?("S") }. map { |name| name.upcase }. sort. join(', ')
- rauljara 14y ago> but it's not actually valid ruby. You are correct that it is invalid for 1.8.6. The code runs just fine in 1.9, though. I take advantage of many things that don't work in 1.8.6, so I'm not particularly concerned with my method chaining breaking compatibility. I prefer the more-than-2-spaces indentation because, by the shape of the code, it is clearer to me that this is a method chain and not a change in control structure. That is also obvious by actually reading the code, though, so I'm fine putting that down to personal preference.
- jordoh 14y agoGreat to know about 1.9 - just looked through the 1.9 changelog and saw it described as "Newlines allowed before ternary colon operator (:) and method call dot operator (.)", so it does seem like they are encouraging this specific formatting style. I agree that the fully indented code is much easier to visually parse - whether that outweighs the refactoring cost is certainly going to vary depending on the team (in addition to personal preference, as you mention).