![](https://seccdn.libravatar.org/avatar/f9a9cf77af20d925b328ee8c95c0068c.jpg?s=120&d=mm&r=g)
On Wed, 18 Nov 2015 10:13:45 +0100 Stefan Hundhammer <shundhammer@suse.de> wrote:
On 18.11.2015 09:56, Josef Reidinger wrote:
And to be honest it can happen in any code in any language ( just depending how often it can happen ).
Wrong.
Any halfway decent parser will realize that in one case you do return something from your function, and in another you don't. That's what happened here.
Preciselly speak you always return something. Just maybe default value for return is not so common in other languages. I know that e.g. C++ can check it during compilation, but ruby is not compiled, so in the end, you in both cases ends up with runtime error or error catched by test suite.
Better yet, if you have to DECLARE your stuff (functions, variables), you are making a commitment (or a contract, however you want to name this) what you are going to do with that thing and what you don't. And the parser (no matter if it's an interpreter or a compiler) can catch those problems.
This is discussion between static and dynamic languages and about explicit types specification. I think there is enough discussion on internet regarding this stuff and I worry I cannot add anything new here.
E.g. in ycp one nil can result in cascade of nils.
I really wouldn't call YCP, of all things, a shining example of good behaviour when it comes to this. Yet, even it had (after years of painful debugging) static type checking that at least did some minimal amount of plausibility checks.
What is ruby philosophy how to solve it? Tests. Do not trust code that is not tested. Of course some tools can detect some misusage, but only good tests can prove that code really works.
Tests are good, but they have limits. In particular, when your number of code paths is too high, the possible permutations just explode. That's why achieving good test coverage is so difficult.
Thats more phylosophy discussion about egg or the egg problem. Ruby phylosophy is that if something is not tested ( manually or automatic ), then you cannot believe in code. And with good code design almost everything can be tested.
Ruby (and the tools in its ecosystem like Rubocop) try to make you believe that you can easily handle this by dumbing down functions enough so they become trivial. Well, that would be good - if only there were a practical way to go through each code path at least once (better yet, with some permutations of your data set / variables to test fringe cases in the less frequently taken code paths, too).
well, trivial = single purpose. Actually what you mention already exists for ruby - https://github.com/mbj/mutant it tests if you do not have fake test coverage ( martin played with it in past ). Regarding automatic tool to go thrue all path, it is still not enough as 1) that tool need to know behavior, sometimes exception is correct 2) need to verify it do what is expected, just passing function without exception is not enough
But as seen in this example, this is often not practical. If your code depends on the status of things beyond your immediate control, you'd have to mock all that. In this particular case, who would have foreseen that a seemingly unrelated scenario like having a RAID on the previous installation might lead to such a crash?
If it happen first time like in this case I usually capture target map ( as hand crafting target map is pain ) and then write at least regression test, that I know that covering this case.
Sure, better test coverage might have caught this. But it would have been even simpler (very much simpler!) to have the parser throw an error if the code is inconsistent - like not returning a value in this case if in the other case it does.
It is question if you are on side at least have some check or having good tests that verify working solution. Again it is part of mandatory types discussion topic.
And to cut the reply that immediately comes to mind short: If in some pathological case I want the code to return 'nil', I can explicitly make it return 'nil'.
On other hand there is many cases where nil is nature return code like in each, find, etc. So for language authors it can mean to use specific statement for other loops or be consistent, which can cause troubles.
IMHO there is no real excuse for the Ruby parser to behave this dumb. They just became collateral damage of their own "anything goes" philosophy.
I agree that faster failure during runtime will be better, but there can be maybe code that use this code path. Josef
CU
-- To unsubscribe, e-mail: yast-devel+unsubscribe@opensuse.org To contact the owner, e-mail: yast-devel+owner@opensuse.org