Refactoring accordning to De Morgan's laws

I have this test:

if !(from.is_a?(String) && to.is_a?(String) && from.match(/\A\//) && to.match(/\A\//)) || internal_redirects[to].present? || !public_path?(from) || !public_path?(to)

and it's terrible. I'd like to refactor it, but since it is terrible it is hard to parse, understand and replicate correctly.

It would be much easier if the computer could do the first step and rewrite it to normal form; or something. Just so I can focus on one step at a time.


So my question is: is there such a refeactoring and I just missed it? Some plugin that could help?


Hello Ulrik,

Could you please specify which result you'd like so see after that refactoring/reformatting?


Yes of course.

My original test can be rewritten, with de Morgans law, !(a && b) == (!a || !b)  :

!from.is_a?(String) || !to.is_a?(String) || !from.match(/\A\//) || !to.match(/\A\//) || internal_redirects[to].present? || !public_path?(from) || !public_path?(to)

Which I did manually, and then all I had to do was return early for each condition instead:

return false if !from.is_a?(String)
return false if !to.is_a?(String)

Which is much easier to read an reason about.

So, just being able to place the cursor in the test and "apply de Morgans law" would help. It's not hard to do manually, but getting it right _every time_ is challenging.


More generally it would be nice to automatically rewrite long boolean conditions

a || !(b && (!c || d)) || (e && !(f || g)) || h

into disjunctive normal form

a || !b || (c && !d) || (e && !f && !g) || h

or into conjunctive normal form

(a || !b || c || e || h) && (a || !b || c || !f || h) && (a || !b || c || !g || h) && (a || !b || !d || e || h) && (a || !v || !d || !f || h) && (a || !b || !d || !g || h)

or other options. Depending on the exact test, some forms will be easier to understand and break apart into readable code.

(These were copied from wolfram alpha, I probably mistyped somewhere.)



Thank you for explanation. Unfortunately, at the moment there's no such possibility so could you please submit a feature request on our tracker:


I went to suggest it on the tracker and found the intention already exists; I just didn't know what it is called.



Oh, sorry I didn't get it correctly that you mean only this intention. Then yes, it's already implemented. 


Refactoring complex conditional statements like the one you have can indeed improve code readability and maintainability. While there isn't an automatic tool that can rewrite your code for you, you can break it down into smaller, more manageable pieces using intermediate variables or methods. This can make the code easier to understand and debug.

Consider creating separate methods or variables for each condition to clarify their purpose. This way, you can tackle one condition at a time and ensure that each part of the logic is well-documented and self-explanatory. Usaudiovisuals While it may take some manual effort, it's a good practice for writing clean and maintainable code