p5.js
p5.js copied to clipboard
Version 1.4.1 adds reserved function “size”
Topic
Between version 1.4.0 and 1.4.1 a reserved function “size” was added. I feel like this variable name is used way too commonly in sketches to have it as a reserved function.
As far as I can see there is no size
function exposed or defined by p5.js in the global scope and trying to assign a value to size
in 1.4.1 does not result in a warning. Can you provide more info about what you have observed?
This might be web-editor specific then. But when I change the source from 1.4.1 to 1.4.0 the error goes away.
Can you share a link to the sketch you are using to test this? Thanks.
Hello, yes it’s an incomplete sketch, but it has a class that uses “size” as one of the attributes. But, even when I change those variable names inside the class, there is still a variable “size” in the main sketch and I still get the warning. I even went to some of my old sketches and updated the source from 1.4.0. to 1.4.1 and I get the same warning on those (because I frequently use “size” as a variable name.
https://editor.p5js.org/UnOriginalPun/sketches/xYNvt_mYr
@almchung Can you perhaps have a look at this as I think it may be related to some FES bug?
It looks like this line in the FES source is getting its list of reserved function names from the names of all the methods on all p5 classes: https://github.com/processing/p5.js/blob/194c0dc472e6eeea1f3460d850b5680772eb7123/src/core/friendly_errors/sketch_reader.js#L305
I wonder if it's marking size
as reserved because it exists on p5.TypedDict.prototype
?
https://github.com/processing/p5.js/blob/374acfb44588bfd565c54d61264df197d798d121/src/data/p5.TypedDict.js#L118
so what is the solution to reserved function "size"?
For now, you can ignore it, it's FES misreporting it as a reserved word when it isn't really.
If someone wants to make a PR to fix this, I believe they would need to update this line to only include some p5 constructors instead of all of them: https://github.com/processing/p5.js/blob/194c0dc472e6eeea1f3460d850b5680772eb7123/src/core/friendly_errors/sketch_reader.js#L305
I think maybe just p5
, p5.Renderer
, p5.RendererGL
, and p5.Renderer2D
? Am I missing anything else that contributes global methods?
For now, you can ignore it, it's FES misreporting it as a reserved word when it isn't really.
If someone wants to make a PR to fix this, I believe they would need to update this line to only include some p5 constructors instead of all of them:
https://github.com/processing/p5.js/blob/194c0dc472e6eeea1f3460d850b5680772eb7123/src/core/friendly_errors/sketch_reader.js#L305
I think maybe just
p5
,p5.Renderer
,p5.RendererGL
, andp5.Renderer2D
? Am I missing anything else that contributes global methods?
But what to do if the code doesn't run cause of the issue? How can I ignore it?
Does it go away if you use p5.disableFriendlyErrors = true
? https://p5js.org/reference/#/p5/disableFriendlyErrors
@mishaushev FES warnings does not cause the sketch to halt, it merely prints the message to console. If your code is halting there probably is another problem causing an actual error.
I think maybe just
p5
,p5.Renderer
,p5.RendererGL
, andp5.Renderer2D
? Am I missing anything else that contributes global methods?
These seem right to me. Looping in @limzykenneth @almchung to double check. Thanks!
p5.TypedDict
has a member method of size
as well so may want to check that. Some manual test after a fix would help as there may be some that we missed.
I would love to help fixing this one. I had a look at the existing code and understand why the current code is inaccurate in determining reserved function names. size
is definitely not the only word that should not be in here, add
and invert3x3
are some other example, see the full list here: current-reserved-functions.txt. As a result some words are currently missing, such as resizeCanvas
.
I tried another method such as the following
const reservedFunctions = Object.entries(p5.instance.constructor.prototype)
.filter(([k, v]) => typeof v === "function" && !k.includes("_"))
.map(([k, v]) => k);
This gives us something very close to what we find in the reference documentation here: https://p5js.org/reference/
So before I get into implementation, I would like to understand, what functions do we want to warn about overriding exactly? I would imagine it should be any function which added by p5 on the global context this
, am I correct?
Thanks for your interest @Ucodia! I think the issue is that on this line https://github.com/processing/p5.js/blob/194c0dc472e6eeea1f3460d850b5680772eb7123/src/core/friendly_errors/sketch_reader.js#L305 we are adding all methods on all p5 classes as reserved functions. However, not all p5 classes have their methods added to the global scope: I believe only p5, p5.Renderer, p5.RendererGL, and p5.Renderer2D do. So I think by using those classes instead of the full list of all p5 classes (p5Constructors
), we can fix this issue.
Got it, thanks I'll experiment with the suggestion and report the list of words that comes out of it.
https://github.com/processing/p5.js/blob/194c0dc472e6eeea1f3460d850b5680772eb7123/src/core/friendly_errors/sketch_reader.js#L305
we are adding all methods on all p5 classes as reserved functions. However, not all p5 classes have their methods added to the global scope: I believe only p5, p5.Renderer, p5.RendererGL, and p5.Renderer2D do. So I think by using those classes instead of the full list of all p5 classes (
p5Constructors
), we can fix this issue.
@davepagurek I think I can do it. I just want to ask that if we only want to include 4 classes ( namely p5, p5.Renderer, p5.RendererGL, and p5.Renderer2D ) can't we do it by being explicit about it and add them directly on basis of their name, instead of adding all of them and filtering them later ? Like below -
see here for more details https://github.com/processing/p5.js/blob/d49417ce6f02f4cefce2361699d08f40b7d72561/src/core/friendly_errors/sketch_reader.js#L321
@aditya-shrivastavv Agreed, it's not necessary to literally use filter(...)
on the array, but rather just to only iterate over those four classes' methods.
Please assign this issue to me, I am working on it.
Hi everyone. I revisited this issue while reviewing a PR and wanted to outline reserved function Friendly Errors issues and propose another approach to resolving this problem.
To provide some context, there are currently 326 reserved functions that should NOT be overridden by a user. (v.1.6.0)
- Current implementation:
- The current function in
sketch_reader.js
checks 239 functions. As noted in this issue, we get 172 false positives (ex:size
,name
,value
) while catching 67 true positives. But it misses 259 cases (false negatives, ex:shininess
,round
,red
). - There is another error handling code catching most reserved function cases (and generating separate messages) without the false positives, but only 10 false negatives: main.js L691-L695. False negatives include
print
andloadX
(loadBytes
,loadFont
,loadImage
,loadJSON
, ...) functions.
- The current function in
- The suggestions in this thread (fixing
sketch_reader.js
-functionArray
) will resolve the OP's concern regardingsize,
as well as will reduce false positives (63). On the other hand, this approach will yield more false negatives (273).- In addition, I think this approach of dynamically loading/retrieving objects and functions each time may not be efficient (computation-wise) and error-prone (due to limitations that we cannot accurately obtain a complete list of reserved function names).
- I would like us to consider a slightly different approach where we obtain a complete list of functions at build time (statically), which has the additional benefit of supporting future decoupling of FES. More specifically, we can obtain a complete list of reserved functions during the build step of
browserify
where we finalize the code and write to a file.- For instance, we are already replacing a placeholder string (for version) here at build time. We can do something similar by declaring a placeholder array in
constants.js
to be replaced at build time. - Right before writing to the p5.js file, we can use regex to extract all global function names (e.g.
_main.default.prototype.<name> = function ...
) and replace the placeholder string with these names. - In
sketch_reader.js,
instead of retrieving a dynamic list of functions, we can use the fixed list of function names from the previous step (as it is declared inconstants.js
). - The caveat is this method will depend on
browserify,
so the code may need to be updated if we decide to move away frombrowserify.
- For instance, we are already replacing a placeholder string (for version) here at build time. We can do something similar by declaring a placeholder array in
I feel that if we can manage to make this approach (in 3) work, then we may not have to worry about false positives/negatives, so I want to know what others think. I am hopeful that this approach would work, but I admit I may be missing something.
Thanks @almchung! I think that approach sounds good and would avoid some of the current issues we have, so if @aditya-shrivastavv feels like taking it on, I'd support that, but otherwise I think it's fine to accept incremental progress on the current system in the mean time.
I think the approach is sound as long as we aren't dynamically assigning values to p5.prototype
(which it seems like we only do for constants) so I think it should be ok!
On the other hand, this approach will yield more false negatives (273).
Are those false negatives caught by main.js L691-L695? If so, I think it's OK to proceed with the change. Otherwise, agreed, we probably want to try to catch these in some other way.
One other concern would be a dependency on having a full build. We don't support anything else currently, but there are some open issues discussing paths to being able to only include used files when importing p5 (https://github.com/processing/p5.js/issues/5740), so we'd probably want to think about how this would affect a future where that's possible. It might mean that generating the list of reserved strings is a separate build command that builds a full p5 release, then extracts function names via a regex, then writes the result out to a file, which is then read as a regular array of strings during regular builds.
@davepagurek: Sounds great! I also agree we should work on this issue incrementally.
Are those false negatives caught by main.js L691-L695? If so, I think it's OK to proceed with the change. Otherwise, agreed, we probably want to try to catch these in some other way.
Yes, main.js L691-L695 will catch most cases, just excluding ~10 false negatives listed in 1-ii.
@almchung Thanks to #6055 I think this particular issue can be closed, but I don't want your suggestion for an update to how FES to be lost. Would you be interested in opening a new issue about the refactor you have in mind?