5 ms·
It's not pointless, it makes code read better. It's another option to have. It's not meant for every use case. It indicates you don't understand Ruby if you fin
by soheil 4y ago
It's not pointless, it makes code read better. It's another option to have. It's not meant for every use case. It indicates you don't understand Ruby if you find yourself using an "unless" in a complex boolean operation. It's meant for simple cases like an inline return statement
return unless User.exists(id=100)
- moonchrome 4y agoGod that's such a landmine when reading code. Seeing a return without an explicit change of scope... Why ? To save one line ? Yep that's why I hate ruby - worked on one mature codebase for a year and after seeing various such gems used across the project - from >10 devs - I'm confident I will never touch the language again.
- soheil 4y agoIf you're returning who cares about the scope? Are you saying visually you'd like to have indentation inside the if body? If that's the case there is also nothing stopping you in most languages from doing something as nasty as: a=1;b=2;c=3;d=a+b==c?4:5;return d
- moonchrome 4y agoI do because return means end of scope. Except in your example it hides the fact that it's creating it's own scope. I'm not arguing other languages can't produce bad code, just that ruby is particularly suited for it especially as number of developers working on code increases. I've seen people propose a linter to enforce consistency - but at that point I might as well chose a language with better design choices - plenty of alternatives these days.
- codesnik 4y agoIt doesn't create no scope. Even for variables.
- multiplegeorges 4y ago> I've seen people propose a linter to enforce consistency - but at that point I might as well chose a language with better design choices - plenty of alternatives these days. You're seriously proposing that adding a linter has the same organizational costs as changing languages entirely. Meanwhile, back in the real world... Ruby has major advantages over many other languages and a linter is basic tooling you should have in every development environment.
- ezekg 4y agoRuby doesn't create a new scope for if/unless.
- pmontra 4y agoThose one line returns are particularly handy at the beginning of methods, to validate or process arguments and return immediately for simple cases.
- hnzix 4y agoShort circuiting is such a beautiful way of avoiding giant nested "if" mountains. I wish it was more widely used.
- ilyt 4y agoright but if condition { return } works well enough in other languages and shows actual condition (the important part) to programmer first. if that if and extra brackets is really too long Perl way is also option. condition || return
- swat535 4y agoThose are called Guard clauses and they are implement in plenty of systems.. this paradigm has nothing to do with "Ruby". In any case, the Ruby community already has good guidelines on the "Unless" usage, there are few scenarios where they are useful but it's not like you find them everywhere in a codebase. For example, we don't use "Unless" with "Else", or use Unless with negation (like the article), or use Unless in nested If statement, etc. Rubocop will catch many of these and warn you. My point is that experienced engineers will use the language as it was intended to and not abuse its features.
- quietbritishjim 4y agoI'll admit I'm not a Ruby developer, but wow it allows return conditionally inside an expression? What were the language designers thinking?! I can't think of any other language that allows return inside an expression (or break/continue). Let's see: C, C++, C#, Python, Javascript, Object Pascal, Java, Rust; all nope. That is indefensible.
- maybe_pablo 4y agoKotlin has this, check out https://kotlinlang.org/docs/returns.html https://kotlinlang.org/docs/returns.html
- ckolkey 4y agoIf and unless can be used as post-fix clauses. Also, in ruby, -everything- is an expression, so... of course you can return from there
- vidarh 4y agoThis isn't exactly true. It's a syntax error to put a return anywhere where the grammar expects a value expression, because it's one of few constructs in Ruby that doesn't return a value (contrast with e.g. "if" and "def" and "class", all of which return a value). E.g. "42 == (return true)" is a syntax error while "42 == if false; true; end" is syntactically valid. You can return in the expression in the comment above because the return is at statement level - nothing above it in the grammar requires a value (but obviously allows it). Off the top of my head I can't remember which other keywords fall in that category. Obviously "end", "then", "alias" and there'll be a few more, but for most keywords in Ruby you're right they can be treated as expressions.
- jack_riminton 4y agoNah, it's pretty cool once you get used to it
- tialaramex 4y ago> I can't think of any other language that allows return inside an expression ... Rust Er, what? You understand almost everything in Rust is an expression right? let x = if yeah_nah() { return 5; } else { "X" }; That return is an expression, obviously we mostly care about the expression's side effect which is a change of control flow to leave the function with some sort of integer 5 as the return value (the function signature tells Rust which kind of integer this 5 is) - but the expression "return 5" itself does have a type, it's ! aka Never, an Empty Type because no values of this type can exist - because the side effect will change the control flow before we need a value. Rust's type inference engine is fine with this because under type arithmetic all the values fit in a single type, the type of "X" - &'static str - there are no values on the left to disrupt that.
- ilyt 4y agoreturn if !User.exists(id=100) reads just fine and takes less letters. I don't think unless is "bad", it's just unnecessary > It indicates you don't understand Ruby if you find yourself using an "unless" in a complex boolean operation. It's meant for simple cases like an inline return statement unless `git status -s | grep -v 'RAILS_VERSION\\|CHANGELOG\\|Gemfile.lock\\|package.json\\|version.rb\\|tasks/release.rb'`.strip.empty? abort "[ABORTING] `git status` reports a dirty tree. Make sure all changes are committed" end is not exactly very readable and this unless connection.adapter_name == "Mysql2" && options[:id] == :bigint if [:integer, :bigint].include?(options[:id]) && !options.key?(:default) options[:default] = nil end end isn't glancable either. Just random snippets from Rails code. You can see how author wanted some bonus points and used unless, if, and ! too. Sure it isn't hard to figure out but it makes it needlesly obtuse
- soheil 4y agoFlowers are not necessary either.