On Mon, Aug 5, 2024, at 20:49, Ilija Tovilo wrote:
> On Mon, Aug 5, 2024 at 3:33 PM Nick Lockheart <li...@ageofdream.com> wrote:
> >
> > This is a different problem that could be solved by a sandbox API.
> 
> Not sure which case we were talking about then. ClockMock is what I've
> been referencing all along.
> 
> > > Well, ok. But then we're back to prefixing global calls, which
> > > defeats the purpose of the proposal.
> >
> > Global functions would only need a prefix `\` in the *very rare* cases
> > where local functions are set as the default. For most people, the \
> > would be omitted, as globals would be set as default for unqualified
> > function names.
> 
> Right. But apart from mocking, what are these cases? If performance
> were no longer an issue, "using global functions" just makes the
> language harder to use, removing the local fallback. "using local
> functions" may be useful in namespaced code making many calls to
> functions within the same namespace. In that case, it would probably
> be more useful to switch the lookup order back instead. If you want to
> pay zero performance penalty, you can prefix global calls with \.
> You'd need to do that with "using local functions" anyway.

So. Fun story. I’ve seen this technique used to patch out fgetcsv due to a 
memory leak, with a pure php polyfill, in at least four unrelated codebases. I 
believe the leak is still there too and now that I know so much more about zend 
strings, I can probably guess what the issue is as well.

I digress. The point is, there are code bases that use this technique to get 
around php issues or even “implement older versions” of core functions to 
retain backwards compatibility until the code can be updated to deal with the 
new core version.

> 
> As for mocking: If the code needs to change either way, why not make
> it testable in the first place, e.g. through dependency injection for
> time()? At least this only requires changing the calls that are
> mocked, instead of all the calls that aren't.

Have you ever worked on some legacy code where you aren’t really sure how it is 
working in the first place? Even something as simple as shimming out time() 
could cause race conditions in the overall system. Refactoring these systems is 
an art form all by itself and you attempt to add tests to understand the system 
end-to-end, long before you ever change a line of production code. 

> 
> The main benefit of the approach from ClockMock is that your code
> (probably) doesn't need to change. I do think that the entire approach
> is hacky, and probably worth solving on a language-level, at least if
> possible without adding limitations to the engine. A good first start
> would be to know what functions are commonly mocked with this
> approach.
> 
> Ilija
> 

Time functions are the most obvious ones, and then any function that changes 
between versions and breaks something would be the non-obvious ones. (Ex: 
counting null: https://3v4l.org/hmNiL) This allows you to upgrade php / support 
higher versions while slowly upgrading core function calls.

— Rob

Reply via email to