5 ms·
I enjoyed reading that, thanks. One thing: replacing def my_method @foo == :bar ? :foo_matches : nil end with def my_method :foo_mat
by stephth 14y ago
I enjoyed reading that, thanks.
One thing: replacing
def my_method
@foo == :bar ? :foo_matches : nil
end
with
def my_method
:foo_matches if @foo == :bar
end
doesn't look like an improvement to me. The first style is direct and readable, and lowers the barrier of entry to understand it. The second one requires to be familiar with the subtleties of Ruby, which adds difficulty when you're working with multiple languages daily or getting started with Ruby. I'm not saying you should avoid pushing Ruby to its best capabilities so that it's readable by any programmer, but in this case, winning 4 characters doesn't seem worth the compromise.
- evilduck 14y agoIf you're coming from another programming language, sure, you know what ternary operators are already and can reason out what the function does without necessarily knowing Ruby that well, but read the logic out loud: Ternary: "If instance variable foo equals symbol bar, then return symbol foo_matches, else return nil" Ruby Idiom: "Return symbol foo_matches if instance variable foo equals symbol bar" To me, I don't see it as saving characters as much as the ternary version feeling less idiomatic. In the ternary version you've got to convert 5 sigils into meaning in your head to reason out that method, plus the ? and : sigils as ternary operators are less frequently used in Ruby anyways, so you may have to pause a bit longer on them since the ? and colon are frequently used for query-style methods and symbols respectively. That adds context as a requirement to interpreting them in your head. The idiomatic version is functionally equivalent, but reads a little better converted to English. You've only got to convert 4 programming language sigils into meaning and there's no ambiguity of the colon sigil and the ? goes away entirely.
- stephth 14y agoI hear you, and I realize Rubyists tend to avoid ternary operators, but I think this case is one where idiomatic Ruby makes unnecessary compromises against readability. Your arguments still don't convince me the latter is more readable. Ruby Idiom: "Return symbol foo_matches if instance variable foo equals symbol bar" You forgot the "else, it doesn't get called and the method returns nil by default" part. Although it's implicit, it doesn't mean you don't have to reason about it. On top of that, being implicit raises the barrier of understanding. you may have to pause a bit longer on them since the ? and colon are frequently used for query-style methods and symbols respectively I copy pasted from the article but I agree that readability could be improved with parentheses: (@foo == :bar) ? :foo_matches : nil I don't think the colon is a problem for readability either, being surrounded by spaces. I'll give you that a programmer coming from another language may make the mistake to think the space is optional.
- saraid216 14y agoThe ternary is generally a problem for readability. Ruby's particular style (like being able to return a value from an if-block) generally make the cases where they're useful obsolete. In this case, if we cared about readability, we wouldn't use a ternary at all: if @foo == :bar :foo_matches else nil end Which simplifies down to the exact refactoring offered.
- ZeroGravitas 14y agoIn Kent Beck's Smalltalk Patterns book he suggest that although every method returns "self" if you actually intend for that value to be used you should return it explicitly. I believe it's called the "Interesting Return Value Pattern' and I think the same applies here, the nil should be explicit.
- FuzzyDunlop 14y agoI think the example for that is bad, when you look at what it's trying to explain. def foo_matches? @foo == :bar end It returns true if it does, and false if it doesn't, as opposed to true or nil. Which is miles better than any of those alternatives. It also failed to consider that the naming of the method and the usage of Ruby naming conventions is just as important as what goes on in the body.
- stephth 14y agoAgreed, this is an example where returning true or false would be more useful. I presumed the point was assuming a situation where a method returning either a value or nil would be desirable.
- deleted 14y ago[deleted]
- philwelch 14y agoI would write it like this: def my_method if @foo == :bar :foo_matches else nil end end but, hell, you wanna see something even cooler? def my_longer_method ... variable = if @foo == :bar :foo_matches else nil end ... end I find this much better than ternary operators.