Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Suture: A Ruby gem that helps you refactor your legacy code (github.com/testdouble)
127 points by mooreds on Sept 5, 2021 | hide | past | favorite | 20 comments


The problem with these types of gems is that they're good for refactoring functional style code that takes an input and produces a result and has "few side effects" as they mention, but this is generally not the type of code you find in an old legacy rails application that you want to refactor. The whole thing that makes these refactors tricky is that they can just write to the db anywhere in a non obvious way.

If you naively go about refactoring something like:

POST /users

Thinking all you need to do is match the output of the current request and match the record it makes in the users table you're potentially missing a ton of side effects you didn't even know about.The problem has always been the side effects and until one of these gems can track and compare side effects in an intelligent way I don't see how they are that useful.


Really this is what drives me nuts about Rails. You can never really know what exactly any line of code is going to do.


Do you have an example of such code that does something off label or tricky to intuit?


Active record hooks. Observers especially are a spooky action at a distance factory.


Altering expected framework functionality. E.g. a custom getter method for an ActiveRecord attribute.

Technically this isn't a Rails-only thing; but since Rails relies so much on convention, there are many opportunities to break it (and possibly bring suffering to other devs).


Besides the other examples already given, monkey patching is another offender, as are proxy tricks with methods like send or respond_to (technically not Rails-specific but I associate this style with Rails).


I mean, this can be any highly expressive language. Common Lisp macros can get crazy, Haskell has sugar on sugar, Perl all looks like code golf to me, etc...


Yeah, as much as really like Ruby, there is just too much Magic going on.

I'm a programmer, not a wizard!


> I'm a programmer, not a wizard!

What if I consider those to be the same thing? Programming is an alchemical process through which we can contribute to humanity beyond the time-limit imposed by our physical bodies: https://en.wikipedia.org/wiki/Great_Work_(Hermeticism) :)

"The magnum opus is pre-eminently the creation of man by himself, that is, the full and complete conquest which he can make of his faculties and his future; it is pre-eminently the perfect emancipation of his will."


You are right, but there are many many methods in any codebase that really are, for all intents and purposes, read-only - ie, get a bunch of data from data sources, stitch it together, and return a json blob.

These tools would make me feel a lot more confident refactoring code like this (actually, right now I use Postman automated API response recordings with a manually extracted dataset of representative query parameters from production logs to validate our changes) - so this indeed looks like it might make my life easier :)


How do u stitch your logs params with Postman? And btw arent controller/request tests better for that?


Postman supports dynamic variables for tests [1]. Of course nothing requires you to use postman, you could just as easily script this with just ruby and curb/httparty.

The reason for this is that a lot of api endpoints support a large number of parameters, and we want to be sure that we test a decent sample of real world usage instead of only a few examples that we can think of to implement in controller/request tests.

We can take a month’s worth of request logs from production, deduplicate them, run the requests against prod and record responses, then run same requests against stage and verify responses match even after you rewrite half the backing queries. This helps a lot with peace of mind when we deploy :)

For another, more advanced approach to this idea, see traffic mirroring/shadowing [2].

[1]: https://learning.postman.com/docs/writing-scripts/test-scrip...

[2]: https://www.haproxy.com/blog/haproxy-traffic-mirroring-for-r...


Thanks for the detailed response! Never heard of this technique


Oh, and for a practical example of the second approach, check out this blog about how Shopify rewrote their rendering engine: https://shopify.engineering/how-shopify-reduced-storefront-r...


This looks really cool! It reminded me of another library I came across a while back, Scientist from GitHub: https://github.com/github/scientist


I follow the readme of creating a seam so you get nice isolated class you can easily test. Then I would suggest to write a lot of tests, understand the code and then refactor and ensure your test still pass.

No need for a gem like this. As others point out for functional small pieces of code this might work but api endpoints I'll rather go with a "add tests" approach


My impression is that this tool helps you do the exploratory work required to write tests in the first place, as well as helping you split up and rewrite the code to start making it more testable.


Does anything similar exist in Python ecosystem?


Laboratory[0] comes to mind.

[0]: https://github.com/joealcorn/laboratory


Thank you, looks very interesting!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: