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?

5 comments
Comment actions Permalink

Hello Ulrik,

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

0
Comment actions Permalink

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.)

 

0
Comment actions Permalink

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

https://youtrack.jetbrains.com/issues/RUBY

0
Comment actions Permalink

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

https://youtrack.jetbrains.com/issue/RUBY-22918/Unable-to-find-De-Morgans-law-in-ruby-intentions

 

0
Comment actions Permalink

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

0

Please sign in to leave a comment.