Can't get OpenScad $Special variables to work "Correctly" - openscad

I'd like to create some functions in a library whose behavior I want the option to modify using $Precision similar to how $fn controls the number of facets in many built-in objects and operations.
For example if I use the cylinder object or the linear_extrude operation I need not specify $fn, $fa or $fs anywhere in my object file. The library has defaults and no warning or error occurs. However if I DO specify '$fn=45;' at the beginning of my object file then all objects or operations that make use of the variable will use this value rather than the default unless I override in a lower scope or explicitly with a parameter.
The problem seems to be that this isn't possible for USER libraries.
If I DON'T declare the variable $Precision (and assign a value) in my library then any use of the library throws a warning on EVERY library call unless I specify a value in my object file.
If I DO specify a value in my library then there doesn't seem to be any way of overriding the value other than by explicitly listing one as a parameter in every function call. That kind of defeats the purpose. Specifying a value at any other scope in my object file DOES NOT override any default set in my library. This seems to be true no matter where in the library I set the default and no matter where in my object file I put the "use" or "override assignment" statement.
As an example, I want a function like this in a library.
function fn(r=0) = ((r<=0?1:r*2)*3.1415926)/($Precision==undef?0.5:($Precision<0.1 ? 0.5 : $Precision));
When I use it I don't want to be required to specify $Precision=... to avoid
WARNING: Ignoring unknown variable '$Precision', in file...
But if I do declare $Precision in my object file I want it used in all ways similar to how $fn is seen by the objects and operations that interrogate it.

Using $Precision == undef will still always cause the warning with newer versions of OpenSCAD.
For this specific check is_undef was introduced, making it possible to check a variable without producing a warning.

Related

Make the compiler tell me that two variables can’t have the same value

I have a list of objects that need to be loaded into my app. But the load order matters. I’ve created a var which is a part of each object that indicates the load order where the lowest number gets loaded in first. Then I’ve set the default to be 9999. I can manually set this value on each object and override the default. Currently this is where I’m at.
Should I add more objects which need to be loaded in a specific order in the future, I want to make sure there are no conflicts. It seems to me like I could do that by making each load order number on the objects unique, (i.e. no duplicate numbers in all the load order variables).
Is there a way I can make Xcode throw an error or warning if it detects that anything conforming to a protocol has the same value on a variable from that protocol as any of the other conforming objects?
Well, you could list all the objects in an array literal in the order you want them loaded, and forgo the load order property entirely:
let objectsToLoad = [
ObjectDescriptor("hello"),
ObjectDescriptor("world"),
]
But if you have objects defined in disparate places and don't want a single unified array literal that lists them all, then I don't think you can get help from the compiler (or the linker).
In a few months, when Swift will have macros, you'll probably be able to get help from the compiler or the linker. The strategy is to use a macro to wrap each load-order constant in a macro that also generates some type definition whose name includes the constant, e.g. enum _LoadOrder_1 {}, enum _LoadOrder_357 {}, etc. Then, if you have a duplicate, either the compiler or the linker will fail due to the multiple definitions for a single identifier.

Collect internal variables of nested functions in matlab

I have a project consisting of multiple nested functions.
For debugging purpose I want to save all internal variables in one way or another, in order to display figures, replay parts of code etc...
I also want to keep this as transparent as possible regarding calculation time.
My first thought was to create a global variable, and store programmatically at the end of each function the inputs and outputs inside the variable as a structure :
globalVariable.nameOfParentfunction_NameOfFunction.nameInput1 = valueInput1;
globalVariable.nameOfParentfunction_NameOfFunction.nameInput2 = valueInput2;
...
globalVariable.nameOfParentfunction_NameOfFunction.nameOutput1 = valueOutput1;
...
Is it possible to use some kind of reflection to get the name and value of inputs/outputs without necessarily parse the file where the function is written?
I found a good but maybe outdated topic about parsing
How do I collect internal signals?
The simple solution is to use save, which will save all variables in the current workspace (the function’s context) to file.
If you want to keep the values in memory, not in a file, you can use names = who to get a list of all variables defined in the current workspace, then use val = eval(names{i}) to get the value of the variable called name{i}.
I would recommend putting all of that in a separate function, which you can call from any other function to store its variables, to avoid repeating code. This function would use evalin('caller',…) to get names and values of variables in the workspace of the calling function.
Note that using eval or evalin prevents MATLAB from optimizing code using its JIT. They also are dangerous to use, since they can execute arbitrary code, however in this case you control what is being executed so that is no a concern.

Change value of import parameter function module abap

I have a FM with structure in importing. When I try to change field value (wa_str-data = '31129999' for example), the change works, but when I get out of the FM, the field value is reset.
Is it possible to change the field value of a Function Module importing parameter which is of structured type?
Thanks to all.
No, you can't change the value of an IMPORTING parameter (unless it happens to be a TYPE REF TO, in which case you can change the value of the referenced object/data). You can only change values of CHANGING parameters. However, there is a dirty trick you might be able to use here. If you want to access the variable foo in the calling program Z_BAR, then you can do this:
FIELD-SYMBOLS <foo>.
ASSIGN ('(Z_BAR)FOO-DATA') TO <foo>.
IF sy-subrc = 0.
<foo> = newValue.
ENDIF.
(By the way, Z_BAR does not even need to be the direct caller of the function module. It just needs to be somewhere in the call stack.)
Why am I calling this a "dirty" trick?
It creates "spooky effects at a distance". Anyone examining Z_BAR would never expect a function module to change foo when it's not in its parameter list.
The variable name gets resolved at runtime, so there is no syntax check when you misspell it.
It breaks when the variable in the calling program gets renamed, and you won't know until it fails at runtime.
You need to know the name of the calling program in advance. When the function module gets called from another program, then it's not going to work anymore.
So I would only recommend this as a last resort measure.

MATLAB best practice: reading variables from a saved workspace within a method

I have a a workspace called "parameters.mat", which contains many variables (really, constants) used by several methods throughout my simulation. The reason that I want these in one workspace is to have them in a handy place for the user to change.
I want to access these variables within class methods. I've found two ways of doing this, and I'd like to know which one is considered better (or perhaps if there's an even better way):
Load the workspace before anything else, as the base workspace, and whenever I want to use a variable from it within a method, I call evalin('base', 'variable_name') first.
Load the workspace within the method whenever I need it. This works,
but it gives me a warning when I use an undefined variable name in
the rest of the method (because MATLAB doesn't know it will be
loaded from a workspace). Is there a clean way to remove this warning?
Probably the cleanest way to do this is to use a wrapper function. Building on my comment, assuming your parameter constants are in a file parameters.mat:
function value = param(name)
s = load('parameters.mat');
value = getfield(s, name);
Now you can use a syntax like
var = param('name');
wherever you need the value of this variable. This way to do it is easily understandable to humans, and transparent to Matlab's code checker. You can also use param('name') directly in your computations, without assigning the value to a local variable.
If the parameter file contains more than just a few numbers, and loading it time after time slows down things, you can cache the data in a persistent variable:
function value = param(name)
persistent s
if isempty(s)
s = load('parameters.mat');
end
value = getfield(s, name);
Now the mat-file is read only on the first call to param(). The persistent variable s remains until the next clear all (or similar, see clear) or the end of the Matlab session. A drawback of this is that if you changed the mat-file, you have to clear all in order to make param() re-read it.
If on the other hand your mat-file does only consist of a few numbers, maybe a mat-file is not even necessary:
function value = param(name)
s.x0 = 1;
s.epsilon = 1;
s.dt = 0.01;
value = getfield(s, name);
With this approach the function param() is no longer a wrapper, but a central location where you store parameter values instead of a mat-file.

lua - capturing variable assignments

Ruby has this very interesting functionality in which when you create a class with 'Class.new' and assign it to a constant (uppercase), the language "magically" sets up the name of the class so it matches the constant.
# This is ruby code
MyRubyClass = Class.new(SuperClass)
puts MyRubyClass.name # "MyRubyClass"
It seems ruby "captures" the assignment and inserts sets the name on the anonymous class.
I'd like to know if there's a way to do something similar in Lua.
I've implemented my own class system, but for it to work I've got to specify the same name twice:
-- This is Lua code
MyLuaClass = class('MyLuaClass', SuperClass)
print(MyLuaClass.name) -- MyLuaClass
I'd like to get rid of that 'MyLuaClass' string. Is there any way to do this in Lua?
When assigning to global variables you can set a __newindex metamethod for the table of globals to catch assignments of class variables and do whatever is needed.
You can eliminate one of the mentions of MyLuaClass...
> function class(name,superclass) _G[name] = {superclass=superclass} end
> class('MyLuaClass',33)
> =MyLuaClass
table: 0x10010b900
> =MyLuaClass.superclass
33
>
Not really. Lua is not an object-orientated language. It can behave like one sometimes. But far from every time. Classes are not special values in Lua. A table has the value you put in it, no more. The best you can do is manually set the key in _G from the class function and eliminate having to take the return value.
I guess that if it REALLY, REALLY bothers you, you could use debug.traceback(), get a stack trace, find the calling file, and parse it to find the variable name. Then set that. But that's more than a little overkill.
With respect at least to Lua 5.2: You can capture assignments to A) the global table of a Lua State, as mentioned in a previous reply, and also B) to any other Lua Object whose __index and __newindex metamethods have been substituted (by replacing the metatable), this I can confirm as I'm currently using both these techniques to hook and redirect assignments made by Lua scripts to external C/C++ resource management.
There is a gotcha with regards to reading them back though, the trick is to NOT let the values be set in a Lua State.
As soon as they exist there, your hooks will fail to be called, so if you want to go down this path, you need to capture ALL get/set attempts, and NEVER store the values in a Lua State.