Change value of import parameter function module abap - import

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.

Related

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

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.

How to make a variable defined in a matlab function accessible outside the function

I have built a matlab function and I want to access one of its variables ,say x in the workspace. If I write x in the workspace it says Undefined function or variable "x"
Using the global modifier will definitely make your variable visible to the workspace, but it will also make it visible to any other function you call that happens to use that variable name. So if you insist on doing it this way, make sure that your variable name is unique.
A better way, in my opinion, is to pass back the value of the variable as a return value from the function, though this may require changes to calling functions.
Other options are detailed here:
http://www.mathworks.com/help/matlab/matlab_prog/share-data-between-workspaces.html

How could a simple optional argument lead to data corruption?

I have a FORTRAN code with a routine:
SUBROUTINE READ_NC_VALS(NCID, RECID, VARNAME, VARDATA)
integer ncid, recid
character*(*) varname
real*8 vardata
dimension vardata(15,45,75)
etc.
I want to add some flexibility to this code, and I thought I would do it by first adding an optional flag argument:
SUBROUTINE READ_NC_VALS(NCID, RECID, VARNAME, VARDATA, how_to_calculate)
! everything the same and then ...
logical, optional :: how_to_calculate
Now, at this point, I am not even using "how_to_calculate". I am just putting it into the code for testing. So I compile the code without a hitch. Then I run it, and I get an error in the subroutine. Specifically, some of the values in the code later on are "magically" altered from what they were without that optional argument. The new values don't make sense to the logic of the code, so it exits politely with an error message. Let me stress again that at this point, I am not even using this optional argument. So then, on a lark, I go back to all the places in the source that call this routine and, even though my new argument in optional, I put in values for it in all the calls. When I do that, the code runs fine. So, what's up? How can the mere presence of an unused optional argument in a subroutine result in other data being corrupted? And how can adding input parameters for this optional argument fix things again? This is being compiled with PGI, by the way.
Any ideas? Thanks.
BTW, sorry for not providing more code. My boss might not be too happy with me if I did that. I don't make the rules; I just work here.
Optional arguments in Fortran are implemented by passing 0 (a null pointer) for each optional argument that has no value provided by the calling subroutine. Because of this subroutines that take optional arguments have to:
either have an explicit INTERFACE definition inside the calling subroutine
or be a module-level subroutine (for them interfaces are generated automatically)
If you add an optional argument to a subroutine but it neither has an interface in the caller or is not a module-level subroutine, then the compiler will not generate the right calling sequence - it will pass less arguments than expected. This could pose a problem on Unix systems, where PGI passes the length of all CHARACTER*(*) arguments at the end of the argument list (on Windows it passes the length as the next argument after the address of the string). One missing argument would shift the length arguments placement in the stack (or put them in the wrong registers on x64) leading to the incorrect length of the VARNAME string being received by READ_NC_VALS. This could lead to all sorts of ill behaviour, including overwritting memory and "magically" changing values that should not change according to the program logic.
Obviously, just adding a dummy argument to a subroutine, with or without the optional attribute, shouldn't cause any problems. What might happen, though, is that the change exposes some other problem with the code, which was already there, but didn't cause any visible bad effects.
Without any more code, all we can do is guess, which usually isn't really useful.
One thing that pops into mind is the necessity of an explicit interface, when using optional arguments. Is the code organized into modules?

Undefined function or method for input arguments of type 'double' [duplicate]

A question that pops up quite frequently in different shapes and sizes is: Why do I get the following error message:
"Undefined function 'function_name' for input arguments of type 'double'."
This post attempts to address all the different scenarios where this error message can occur, and propose solutions for how it can be resolved.
If you stumble upon this error message and don't know what it means. Take comfort in this: 90% of us have googled the same phrase.
"Undefined function 'int' for input arguments of type 'double'."
The error message is pretty self-explanatory but may still cause confusion. (I chose 'int' at random, it could just as well be 'train', 'table', 'my_function' or anything else).
There are two main cases where this error occurs:
You are trying to use a function that doesn't exist (yet)
You are trying to access an element in a variable that doesn't exist (yet)
What do you do if you get this error?
First, you might want to try which. This will tell you whether or not the function or variable you're trying to use is defined.
which int
'int' not found.
It's quite obvious, that Matlab can't find any functions or variables named int. Trying to use it is therefore futile. Let's compare it to max:
which max
built-in (C:\Program Files\MATLAB\R2014b\toolbox\matlab\datafun\#logical\max) % logical method
But, you might get the following, even if you get the "Undefined function 'x' ...". If so, see point 3 below.
which x
x is a variable.
1. But the function "int" exists! It is even documented here!?
Yes, int exists, but only if you have the Symbolic Toolbox. Since Toolboxes are additional packages that must be purchased separately (and can be quite expensive), chances are you don't have that package.
If you get the "Undefined function" error, but find the function in the documentation, have a look in the menu to the left, or simply check the address. Standard Matlab functions have addresses such as:
mathworks.com/help/matlab/ref/max.html
^^^^^^
Notice the "matlab" part. If you see this, then you are using a function that is part of the core Matlab.
If however, you see an address such as the one below, then the function you are trying to use is part of the Symbolic Toolbox:
mathworks.com/help/symbolic/int.html
^^^^^^^^
or maybe it's part of the Neural Network Toolbox:
mathworks.com/help/nnet/ref/train.html
^^^^
Solution: Find another function that isn't part of a toolbox you don't have. Chances are you'll find what you are looking for if you are a skilled googler. If you can't find it, ask for help. Explain what you have tried, and show that you have done some effort!
2. But the function is documented here, and is part of core Matlab!?
Even though a function is part of the standard Matlab installation, and is well documented, you may still get this error. The most likely cause for this error is that you are using an older version of Matlab. If you check the documentation you'll see the following at the bottom of the page:
Introduced in R2013b
So, if you are using R2012b then you can't use for instance table.
Solution: Check if the function is defined in your version of Matlab. If it's not yet implemented then you either need to update Matlab or find another way to do it. An alternative to table can for instance be to use cells or structs.
3. But the variable "my_variable" exists! I created it in the line above!
No, you didn't. Chances are you created the variable myvariable, my_Variable, my_Variable or something similar in the line above. It's also possible that you have created it, but have accidentally cleared it.
Solution: Go through the code. Look for typos, places where you have accidentally cleared the variable etc. Inside the Matlab editor you will get the following line at the bottom if you mark a variable: "3 usages of "x" found" if you have defined and used the function. You will also get an orange line underneath unused variables.
4. But I get "y is a variable" when I type which y?
If you get the error above "Undefined function 'y', but which tells you y exists, your error message contains a few more lines:
my_function(x)
Undefined function or variable 'y'.
Error in my_function (line 2)
t = x*y;
>> which y
y is a variable.
What this tells you is that you have a variable called y in your Matlab Workspace (also check this link).
The problem is that functions can't access this workspace:
Functions do not use the base workspace. Every function has its own function workspace.
If you want a function to see and use a variable, you must pass it as an argument. This way the variable will be part of the local workspace for that function. Similarly, if you want variables created inside the function to be accessible outside of the function you must have them as output from the function.
Solution: Pass the variables you want to use as input arguments to the function you use. Make sure the names inside the functions are internally consistent. I.e. it must have the same name throughout the function. Note that there is no connection between the variable names outside and inside the function.
5. But I pass the variable as an input to the function, but I still get the same error message!?
Yes, you probably use the variable as input. However, the variable names are not necessarily the same in different functions (most often they are not).
Suppose you have the function:
function output = my_function(x)
output = 2*y;
end
You'll get the same error as above if you call it from the workspace as in the code below, even though you are using y as input variable, and use y inside the function.
y = 3;
res = my_function(y)
This is because, inside the function my_function, the variable you use as input will be called x, regardless of what it was called outside the function.
Solution: Change the name of the input variable name in the function header, or change the name of the variable throughout the function.
6. But I have created x as a global variable!?
First off: Chances are, if you're reading this post, then you are better off passing variables as arguments rather than using global variables.
It's not enough to declare a variable as global in the Matlab workspace. It must be declared in every function you use it in. So, if you have a global variable x, you need to do global x in every function.
Solution: Rewrite your code and pass variables as arguments instead of using global variables. If this is not an option, add global x in all functions where you're using it.
In addition to this answer, you can refer to the official Matlab FAQ.
I also got
Undefined function '...' for input arguments of type 'double'.
error and I tried the recommendations mentioned above but they could not solve my problem. Then, I realized that there is a special character (*) in my current working directory so I solve the problem when I changed the name of the directory.
Lastly, do not forget to change the current directory after the change operation by using cd argument.
Another way of looking at the problem:
the input arguments should be in an order such that the explanation of the function can read it.

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.