-
-
Save JoshCheek/5625007 to your computer and use it in GitHub Desktop.
-> { a = case when true then return end } # this is allowed | |
-> { a = if true then return end } # this is not | |
-> { a = if true then return; 2 end } # this is | |
-> { a = (true && return) } # this is allowed | |
-> { a = (return && true) } # this is not | |
-> { a = begin; return | |
rescue; return | |
ensure; return | |
end } # this is allowed | |
-> { a = begin; return; end } # this is not |
Lets face it, it's an inferior attempt at unnecessary static analysis that leads to incongruent results. this is not to say that it is valueless, I think there may be some very small amount of value. However, I don't think its value exceeds its cost, and I don't think it makes any sense.
You have cleanly nailed it; to my complete surprise, there are some devs out there that still confuse a void-value-expression (an expression with no inherent value) with a void-value-expression-error (an error caused by mixing so-called "value expressions" with "void-expressions").
Interestingly enough, the most basic forms of void-value-expressions are break
, next
, return
and raise
, all of which, intuitively, are used to change the natural path of execution in some way. To me, that has been the reason of the dichotomy between value-expressions and void-expressions -- to prevent things like 12 * break
or 12 * (return 12)
.
To a sane mind, a void value expression error is raised only when the value of a void value expression is needed to resume the execution of the program in some way:
- Consider
12 * break
: the value forbreak
is needed to calculate the value for12 * break
, and that is where the error occurs. - Now consider this:
break && l()
-- the value forbreak
is needed to decide whetherl()
should execute. this, too, is an error. - On the other hand, consider
12 && break
-- the value for12
is needed to decide whether we should proceed to executingbreak
-- which makes complete sense to be honest, because, even though we had abreak
, its value was not needed.
Now consider this: (12 && break) && return
. Sanity-wise, the reasoning that supposed to lead us through executing it would be:
* the value for 12
is needed to decide whether break
should execute (nothing wrong with that!)
* the value for 12 && break
is needed to decide whether return
should execute (12 && break
has no inherent value -- it's not even nil, it must be thought of as a "compound" void-expression, and at this point a "void-value-expression-error" must be actually raised!)
** BUT IT WON'T **
That to me is nothing but poor and insane implementation of a feature that could have had a slight value.
Ruby as a language is not insane (it's a mere description), but the way its standard implementation behaves makes me run for cover occasionally. tl;dr Checks performed for hunting void-value-expression-errors are half-baked and are, at their best, useless, at least the way they are implemented currently.
Ruby is insane, because is genial!
Hello @sdegutis !!
how can you say
Ruby is insane language
?Don't just make unusable comments .