Freemarker: difference between include and import? - freemarker

I am trying to create two templates and use the variables of one .ftl (freemarker) file in another.
I don't really understand why I should use include vs import.

#include is very much like if you copy-paste the content of the included file into the place of the #include tag. #import also processes the target file, but doesn't output anything. Instead, it assigns the set of variables (the namespace) created by the imported template to the variables after the as keyword. As #macro-s and #function-s just create variables, #import is practical for pulling in a collection of utility macros and functions. Also note that #import-ing the same file for the second time does nothing (as the namespace is only populated once), while calling #include twice will process the target file twice.
As for JavaScript, FreeMarker runs on the server side, and the JavaScript runs in the browser. So the browser only ever sees the final output from FreeMarker.

Related

ESP32 compiler giving "multiple definition of" errors

Got a new issue I've not come across before that's appeared when using the Espressif ESP32 ESP-IDF standard setup under VSCode. It uses the GNU compiler.
I'm getting "multiple definition of" errors on variables that share the same name, but which should be local.
So I use a .c and .h pair of files approach.
In my .c files I do this at the top
#define IO_EXPANDER_C //<<<This is a unique define for this file pair
#include "io-pca9539.h"
In my .h files I do this:
#ifdef IO_EXPANDER_C
//----- INTERNAL ONLY MEMORY DEFINITIONS -----
uint8_t *NextReadDataPointer;
//----- INTERNAL & EXTERNAL MEMORY DEFINITIONS -----
//(Also defined below as extern)
int SomeVariableIWantAvailableGlobally;
#else
//----- EXTERNAL MEMORY DEFINITIONS -----
extern int SomeVariableIWantAvailableGlobally;
#endif
It's a great simple system, any other .c file that includes the .h file (without the #define above its include statemnt), gets all of its extern variables, none of its local variables.
But, compiling in VSCode with my ESP-IDF based project, I'm getting "multiple definition of" errors relating to "NextReadDataPointer"
I use the same variable name NextReadDataPointer in another file pair in just the same way, but it's never declared anywhere as extern and each file pair uses a separate #define (IO_EXPANDER_C and LED_C). I do this all the time normally and I can't see any obvious mistakes.
I've never seen a C compiler do this before, it's as if it's mixing up the local definitions somehow. A #define should only have scope in the file it is declared in and in any includes within that file.
Even odder, the error is not generated if the project is built but a function is called from just one of the file pairs that share the same local variable name. It's only generated when functions are called from both file pairs from my main application.
Can anyone shed light on whether the GNU C compiler does something funky for a standard ESP-IDF project as it's got me baffled?
uint8_t *NextReadDataPointer; creates a variable which is visible across all translation units, i.e. it's the opposite of "private". If you include this header in multiple c files and the linker tries to link those together; it'll see a conflict. The keyword you're looking for is static, for example static uint8_t *NextReadDataPointer; creates a variable that is not visible across translation units. The reason you don't see the problem if calling a function from only one of those two files is because in this case the linker doesn't bother looking into the other one.
Personally I'd avoid such clever preprocessor hacks because it's quite difficult to see how files include one another and debug the resulting problems. I'd suggest sticking to the standard way of declaring shared things in header files and keeping the private stuff inside the c file (prepended by static).

How can I Split c++ code into seperate files

I would like to know if anyone can give me a solution to splitting my various functions out of main to separate files. I understand that you can do this with a single class with a class.h and a class.cpp, but how do you do this if you want to split up your code in your own way.
Let us say I have a bunch of functions that have to do with my Bluetooth connection and another bunch that have to do with working with JSON files, and then a few more that have to do with math calculations. Is there a way to split these up into single separate files without using the .cpp and .h system? ( I was thinking of a single file for declarations, includes and global variables, and then single .cpp files for each category for the rest of the functions) However, I cannot see how to do it.
How would you handle such a senerio?
Thanks for any advice.
Sam
Right now I have just linked them all together with each one including the next one (as a .h file) in the list like a chain. And although this works, it is a pain when I create a new bunch of code and need to split the link and insert them in the chain.
place each bundle of functional code (json, bluetooth...) into separate .cpp files (they dont have to be classes)
For each .cpp file have a .h file that callers of those functions will need. This is usually
function declarations
constants
structs
typedefs
Then callers of these functions #include the .h file
Then at compile time you need to compile all the cpp files into .o files, then link all the .o files. The syntax for that depends on the tool chain you are using

When should #include be used over #include-once?

According to AutoIt's online reference:
It is quite common to have the same "#include " line in several of the files included included in a script. If the same file were to be included several times, it is quite likely that this would generate a "Duplicate function" or "Cannot redeclare a Const" error. So when writing a script intended for use as an include file, add #include-once to prevent that file from being included more than once. Note that the #include-once line must be placed at the top of the script and before any other #include lines.
It is not recommended to add a #include-once line to scripts which are not intended to be used as include files within other scripts.
So #include-once should not be used in scripts that are not intended to be included in other scripts. Why?
If the benefit of using #include-once is to prevent errors triggered by duplicate #include, then what is the benefit(s) of using #include over #include-once?
"… what is the benefit(s) of using #include over #include-once?"
None; they serve different purposes.
#include <filename.au3> includes filename.au3. #include-once (no parameters) prevents a file containing that directive from being included more than once.
If two different include files contain #include <FileConstants.au3> and FileConstants.au3 contains #include-once, then FileConstants.au3 does not get added again on inclusion of the second file (preventing constant- and function re-declaration errors). Usually every to be separately included file starts with #include-once.
"So #include-once should not be used in scripts that are not intended to be included in other scripts. Why?"
It serves no purpose. Effects (if any) classify as undocumented behavior (unintended by developers and subject to unannounced changes).
"When should #include be used over #include-once?"
You could use #include to execute code from another file at a certain (or multiple) other location(s) from within a file.

F# interactive - how to use precompiler directives when multiple files reference the same assembly?

So, in Project AB I have FileA.fs and FileB.fs. FileB uses definitions from FileA, and both FileA and FileB use definitions from Project C (written in C#).
In FileA.FS, I have:
#if COMPILED
namespace ProjectAB
#else
#I "bin\debug"
#r "ProjectZ.dll"
#endif
...which works how it's supposed to -- I can run the whole file in F#-Interactive and it's great.
In FileB.fs, my header is:
#if COMPILED
module ProjectAB.ModuleB
#else
#load "FileA.fs"
#I "bin\debug"
#r "ProjectZ.dll"
#endif
But when I run this (from FileB), I get the error:
FileA.fs(6,1): error FS0222: Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration.
According to the fsi.exe reference, the #load directive "Reads a source file, compiles it, and runs it". But it seems like it must be doing so without the COMPILED directive defined, because it doesn't see the "namespace ProjectAB" declaration.
How can I set up my headers so that I can run either file in F#-interactive?
Edit Per latkin's answer below, I created a script as the last file in the project, _TestScript.fsx. I removed all the precompiler stuff from the other files and set this as the header of the .fsx file:
#if INTERACTIVE
#I "bin\debug"
#r "ProjectZ.dll"
#load "FileA.fs"
#load "FileB.fs"
#endif
When I run this in the interactive, it correctly loads ProjectZ, FileA, and FileB for me to access in the interactive window.
However, in _TestScript.fsx, I get squiggly red lines and no intellisense on any of the functions/types from the referenced files (including the "open" statements).
Is there something else I need to set up in the script file to make the intellisense work? (The answer might be pretty basic since I have not used .fsx files before.)
I don't think there is a way to do this smoothly. A few things to consider:
INTERACTIVE is always defined when you are being processed by fsi.exe, whether you are a .fsx, .fs, #load'ed, whatever. COMPILED is similarly always defined when you are being processed by fsc.exe. I can see how the quoted phrase from the docs maybe doesn't make this totally crystal clear.
You can only declare namespaces in fsi from a #load'ed file
So if you want your file to declare a namespace, and to work as the single file in interactive, then the namespace has to be #ifdef'ed out. But that also means the namespace will be #ifdef'ed out when the file is #load'ed...
You might be able to work around this by conditionally declaring it as a module, not a namespace. Or perhaps creating additional, more granular defines. It will be tricky.
Trying to get source files to work properly as part of a compiled library and simultaneously as single-file scripts is not easy, and I don't think the tooling was designed with this scenario in mind. More common is to have all of your library files behave purely as library files, then use dedicated standalone scripts which #loads the .fs files they need. This keeps the driving code and the library code separate, and things fit together more cleanly.

Defining name strings for NSNotification usage without coupling

I'm going to be using NSNotifications in my app to decouple the code.
I want the compiler to help me when using strings as the names of the notifications, ie, if I mistype one, I want the compiler to tell me.
Using normal strings for this won't work, because the compiler won't know that if I typed "myNotificaion" that I really meant "myNotification".
One way to do this would be to use #defines, or const NSString variables, but that would mean they would have to be declared in a file, either the class they're originating from, or a globally included file.
The problem with having them declared in the class they originate from is that it will need to be included wherever the notifications are listened for, therefore creating a coupling that I don't want.
The problem with a global file is that it could possibly become long and messy and will contain lots of unrelated things.
Is there a way to accomplish this without this coupling or untidiness??
No, not as far as I'm aware, #defines and NSString constants is where it's at and you can't get around having to include these in whatever file requires access to the string.
You could create header files for the different parts of your app, so you might have JJDocumentNotifications.h and JJViewNotifications.h for example. You could then #import them into your precompiled header (.pch) file, so the file looks something like this:
#import <Cocoa/Cocoa.h>
#import "JJDocumentNotifications.h"
#import "JJViewNotifications.h"
That way, the headers will automatically be included in all the files in your target and you won't need to import them specifically.

Resources