using modules in modules? #5397
Replies: 1 comment
-
Posted at 2016-08-11 by ClearMemory041063 The WIFI modules use the AT module. Posted at 2016-08-11 by @allObjects ...it all depends... On uploading: no, it's uploaded only once... On use, it may be different matter: what are your expectations? ...and what's the implementation of the module (Does it create something else than just executable code (and shared (config) object)? Inverting the require tree could simplify your work... Common is requested first. Each Specific registers with the Common. Then you ask the Common part to create a Specific for you, like a factory. More to come... Posted at 2016-08-12 by dwallersv Thanks for the feedback, guys. Ran into problems. I have successfully split the GUI code into 4 separate modules: Widget, Button, CheckBox, and Slider. Widget must always be included (require("Widget")), and must come first. I clearly didn't understand scoping and namespace particulars, however. Simply cutting up the source and adding exports lines didn't do the trick. The scope the module is loaded (and run) in is not the same scope as the main console prompt. After looking at other modules, it looks like I have to call a function exported and set everything up there. So, as a first-pass, I just took the entire "class" for one of these objects, and wrapped it in an init() function that's exported. Constructor function, prototype properties and functions, etc. -- literally indented the entire thing and put "exports.init = function() { ... }" around it. Then, I use it all this way in my demo code:
Not sure if this is the right way to do this (I'm really trying to do what #include does in C). What I found is that it seems to consume twice the memory space just getting the stuff into the system than if the code in those require statements is just literally there rather than being loaded through the module system. This is before even executing the start() function from the demo code, which creates the objects. I don't get it. Posted at 2016-08-12 by @allObjects I did not walk through the code yet. But somehow I feel that the elements act too individually and independent. I did not encounter the notion of focus. In a UI all elements interact somehow with each other... like the view (UI) elements are connected through the controller with each other and the model in the MVC concept. May be this interaction is there but I didn't notice. The other challenge is a typical javascript challenge - but it is only a challenge when thinking C/C++ (or any other) - so called - compiled language... Sorry - and not sorry at all - to repeat myself and pointing to some 3 cents contributed in a different conversation: simple explanation how to save code that espruino run on start?. What trips most non-Javascript-natives off is the fact that when the code is uploaded, 'things' already happen. I was used to Smalltalk before being 'brain-washed' with Javascript. What is kind of common in both of these languages, that after the code is loaded - there exists a cluster of objects (instances and class instances, so to speak). In Smalltalk, this is called an image, and when something new is defined, for example, a class, it is added to that image of objects. Similar to key words in Javascript, of which one the Btw, above aspects made me chose the DOM approach in my UI setup to follow the Browsers' great implementation choice. Last but not least is the Browser the world Javascript was born into: While HTML(5) is streaming into the Browser, the browser interprets the incoming tags... and so also the script tag. All what follows this tag is directly passed on to the Browser's Javascript engine and interpreted(note1) by it: if it is in top level / level 0 - it is executed directly, such as You mention space / memory concerns... a reason that I separated data from code and chose the cheapo-oo approach for my UI implementation: data is in simple and fast arrays and code are methods on the UI singleton. Your perfect oo representation and legibility just costs a bit too much in memory because of the amount of source code that is required to describe each element. Agreed, it allows you to have a nice omitting and defaulting of values when a property is not provided in the constructor parameter object. On the other hand, practically every time the core attributes show always and create a lot of property name repetition. Yes, the methods can easily be attached to the 'class' with prototype, but that's about it. Similar challenge is faced by the color info... Even though I like very much the freedom, most UI's (have to) use a color palette and a single integer can pick the color. When it comes to MCs, frugality is of the essence - I hated to go down this route and [leave the path of oo-virtue by going for parm list and storage in arrays - but it paid off in terseness without compromising ease of use. I could go even further, and make the UI elements definitions in top-level/level-0 in nested array and thus save even more space... I could think of your UI implementation to be used as a generator for condensed code to be executed on a runtime implementation (GWT uses such an approach, where stuff is even developed in a different language - Java - and cross-compiled/generated into Javascript and paired with a runtime piece). I hope some of this brain-dump is useful to you in moving your stuff forward. (note#)s in next post... Posted at 2016-08-12 by @allObjects //////////////////////////// (note1): Browser javascript engines just-in-time compile the code block first before executing it, where as Espruino - because running of source code - immediately - 'streaming-ly' - interprets the code... you can see the difference in the way the the browser throws a syntax error before even doing something, where as Espruino already may have executed parts of the code when noticing that something is - syntactically - not adding up (@gfwilliams correct me if I'm wrong or leaning too much out of the window...). (note2): Before a piece of code is uploaded to Espruino, it is literally grep-parsed for note3: This is the reason that upload should only contain a minimum of actual code execution. Therefore, it is better to stick ALL execution stuff into Posted at 2016-08-12 by dwallersv Thanks very much for the detailed discussion! I'm a geek about this sort of stuff, so the more understanding the better :-) In the end, the problem can be summed up pretty simply: Scope. Rereading the primer on making modules I think I found the solution -- the section declaring public members. I didn't do that. Giving that a try in a bit... Also, ran across this again (I need to get kicked in the head twice sometimes to notice I've been kicked at all :-)):
I think this is what's doubling the space usage over just loaded the same code directly from the IDE. IOW, there is a cached copy of the code, and another copy in the working space of the interpreter. I'll try using Modules.removeCached() in the main demo code to see what happens, but I suspect it will make the loaded code non-functional (as if it wasn't there). @gfwilliams? In the end, I may just have to structure this as a set of code files that must be literally appended to the application source in order to keep from wasting the very precious RAM on the F1, if code duplication because of the Module mechanism wastes all that space. It's ironic, because the Module caching mechanism seems intent on SAVING rather than WASTING space, and for the problem its intending to solve, it does. However, looks like there's an unintended side-effect of wasted space when there isn't the circumstance of loading the same module more than once. Posted at 2016-08-12 by @allObjects Regarding modules, the upload for every piece of code happens in two steps:
Note: you can 'escape' step one by using a variable... But in order that the code has what it needs to run successfully, the module has to be uploaded separately.
Above code will fail with already on upload because it is all in top-level/level 0 and interpreted when arriving at Espruino with this message:
You notice two things:
Bottom line the 2nd item is what matters. Interestingly though is that when you have an SD memory card connected and mounted and "myModule.js" or "myModule.min.js" (minified version of "myModule.js") on it, the module is found on the SD memory card, loaded and stored evaluated in the cache. You can actually ask Espruino which modules are cached. Enter in the console Modules.getCached() (command, reference):
What you would expect is (according to reference documentation):
but you get:
You will get what you expected with 'empty' Espruino (after you enter command
@gfwilliams, can that be fixed? ...backward compatible? Not successfully loaded modules should not show in the list or there should be an easy way to get to that info about the module - without Espruino throwing a fit / writing to console (and may be mess up if console not connected...) - or, worst case, with cumbersome try-catch-block that actually works... Try-catch is obviously not working as can be seen by the output produced (or not produces as expected by the catch-block), but sets the variable
(Since Back to hat I wanted to continue with (Sorry for this (even me) surprising detour...): Enter following commands and you get empty list of cached modules.
Now we 'hand'-fix the issue by entering the issue by entering the following in the console (copy-paste):
Then we enter in console (copy-paste):
And the expected output is:
We could not directly upload and execute previous code, because first thing of upload is
And here the expected output from output and entering
I guess this should put to peace many of the questions in regard of modules. ...another 2 cents from my part. PS: Read through related Struggling with modules conversation. Posted at 2016-08-15 by @gfwilliams Just got back from a holiday and I have a million e-mails and posts to get through, so sorry for not reading this fully, but this might help:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2016-08-11 by dwallersv
Can other modules be used in a module with the require() statement? The writing your own modules page addresses this to some degree, but it wasn't entirely clear to me what would happen if, for instance, the same "core" module is referenced in several different modules.
The scenario: I want to break up the GUI components I've been working on into separate modules so that only the elements being used can be individually referenced, saving space. So, I want to break the code up into a Button module, Slider module, Checkbox, Textbox, etc. All need a "core" set of functionality that would be included in each module.
So, if you were to create an interface that used buttons and sliders, you would include just these components in your code like this:
Each of those have in them,
which, of course, is then getting called twice.
Is this handled gracefully, the "right" way so there isn't duplication?
Beta Was this translation helpful? Give feedback.
All reactions