📜 ⬆️ ⬇️

Good bad monkey patching

We are often asked questions about technology in letters and messages - we are happy to answer. But in this case, the answer is one person, and he could be useful to many.


Therefore, we decided to analyze weekly on one issue, literally in five minutes.



Today, the question about the development of Sergey, our teacher Igor Alekseenko answers:


Mankipatching - why is it so bad or not so bad?

It is difficult to answer this question without starting a holivar. Mankipatching works, so you can’t say that it’s bad, but it’s important to remember that it’s very easy to shoot yourself in the foot.


Mankipatching is when we change the code in runtime, that is, as the program runs. For example, add non-existent methods to an array or override some global function.


Array.prototype.shuffle = function() { const i = this.length; while (i--) { fisherYatesShuffle(this, i); } }; [1, 2, 3].shuffle(); 

Mankipatching is ideal for one-time tasks when reverse engineering is needed. For example, if you need to debug a solution to the problem or once to collect some analytics, this will do, but these are obviously one-time approaches.


If we talk about industrial code, then carelessly handling monkey patches, you can break the work of the built-in objects that will be used throughout the program. Imagine that for some reason you have changed the behavior of the setTimeout function. Externally, it works the same way, but additionally this function solves some other tasks, for example, it stores the context.


 const initNewTimeout = function() { const initialTimeout = window.setTimeout; window.setTimeout = function(fn, timeout, ctx) { initialTimeout(function() { fn.call(ctx); }, timeout); } }; initNewTimeout(); setTimeout(tickInContext, 100, this); 

Of course, in your code, setTimeout will work as you need, but you cannot guarantee that everything else will work just as smoothly in other places where it is used. There are more extreme examples, for example, earlier in JavaScript it was possible to override even undefined and window.


It turns out that with monkey patching you need to be very careful and adhere to certain rules:



According to these rules, polyfiles are created - patches that add support for new features to old browsers. Agree how much the name changes its attitude to the approach. There were monkey corrections, and it became a universal filler. There were incomprehensible changes to the built-in objects, and there was a fix for problems supporting the new standards.


It seems that polyfiles are a good idea: you connect a polyfile and regardless of what browser the user has, you can use new things in the code, for example, Fetch for HTTP requests, Promise or Object.entries for iterating over objects.


 <script src="./promise-polyfill.js"></script> <script src="./whatwg-fetch.js"></script> <script> fetch('/api/request') .then(resp => resp.json()) .then(json => render); </script> 

But there are problems with this approach:



In such situations, it is better to use wrapper functions, which are sometimes called Ponifil . In principle, they allow you to do the same as polyfiles, but clearly. They also have no problems with standards: for example, the popular Lodash library grew out of a wrapper over non-working iterators in arrays. The guys added to the library forEach, map and other some, every, but they were not tied to the standard and therefore they had their hands untied from the beginning. Over time, they added other convenient methods for arrays and collections, such as shuffle, unique, flatten, and others. Despite the fact that iterators in arrays have been supported for a long time, Lodash is successfully developing.


 //  [1, 2, 3].map(it => it / 2); //  arrayMap([1, 2, 3], it => it / 2); 

Still, functions are easier to test. It is very difficult to test a polyfil completely. If you connect it in the same place where the tests are performed, your patch may change the code of the framework itself, which may affect the testing. And if you test the logic of polyfiles separately, it will be unclear whether they are connected correctly.


Even in different environments, your tests will work differently, because in some environments the patch will work, in others it will not. Ponifil has no such problems: you always know what you are testing, they connect and work clearly.


Summarize


Is miscatching bad? Judging by the fact that it works, it is not so bad, but when using it you need to remember that it’s easier to break someone else’s code, it’s harder to test and you can forget that it is used.


Materials on the topic



Video version



Questions can be asked here .


')

Source: https://habr.com/ru/post/336312/


All Articles