Delete variables named in an "unconventional" way - kdb

A while ago I was reviewing some legacy code, and I incurred in the following issue: the developer create many variables starting with a dot (like .variable1), syntax reserved to define namesspaces.
When quizzed about the use of that convention, he replied that essentially that was a way to create global variable within the scope of a function - what in Python you would achieve doing the following:
def define():
global a
a = 2
define()
print(a)
In q, that translated in something like this:
f1:{.b1:2;}
f2:{b1:2;}
f1[] / this creates a variable .b1, which you can use globally
f2[] / this creates a variable b1 within the scope of the function, not usable outside
While my preference would have been to create a global variable using a namespace (something like f1:{.my_namespace.b1:2;}), the code was doing its job without any issues.
The problem arises if I want to delete the global variable defined which starts with a dot (.b1 in the case just described), given that approaches like
delete .b1 from `.
do not seem to work. All the references I was able to find (like this) suggest that namespaces cannot be delete, which would imply these unproperly defined variable will stay there.
To be clear, the problem is not about how to delete variables from namespaces, but to delete those namespaces which are used as variables - if possible at all.
Any ideas?

Based on your question, you want to delete variables from a namespace. You can do this by running:
delete b1 from `.my_namespace
Which is also explained in the link you pasted.
What you can't do is actually delete the reference to my_namespace.
As a side note you can also set variables globally in the root namespace using the set keyword:
{`var set 2}[]
Which will let you avoid having to create single use namespaces.

Related

Is it possible to declare a persistent variable in a Stateflow subchart?

I'm using a Stateflow chart to generate some code (C action language). I would like to declare a subchart variable as persistent (or static), so the value is remembered the next time the subchart is executed.
A solution is to attach this variable to one of the parent states, but then this variable is visible to all the subcharts, which is not ideal.
Another solution is to create an embedded Matlab function with persistent variables on it, but this is too cumbersome, since I would need to read all the variables in the beginning and write them before leaving the state.
Is there a simpler way to achieve this?
Yes. Open Model Explorer, go to the subchart, add data.

Assign multiple local variables by name

How can I assign multiple local variables by names?
For example, within a lambda, something like this:
{
#[;:;] (.') flip (`a`b;4 2);
(a;b)
}[] / should return 4 2
But obviously does not work, because
q)#[`a;:;4]
'type
Also,
q):[`a`b;4 2]
'assign
and using set:
q)set'[`a`b;4 2]
assigns to global, not local environment.
I believe you'll have difficulty saving local variables this way without a hacky solution and without knowing the reason for it needing to be local it's hard to produce a solution that could help. However, here's some suggestions:
if just you don't want global variables at the end of execution you could save these as global and remove them before exiting
if you don't want existing globals overwritten then I suggest saving these variables in a local dictionary instead with variable names as the key. eg.
(!). (`a`b;4 2)
You can access local variables using
q){c:3;?[(`$())!();();0b;`c]}[]
3
but the problem here is the assigning of values to local variables.

Is there a way to use VSTS Variable Groups per environment?

I'm moving my configuration from using web.config transforms to being based on VSTS variables. I get process variables, you define a variable, pick an environment, and you're good to go. I also see "Variable Groups", these seem great, have KeyVault integration, and overall seem like a much better option.
But...I don't see a way to bind a Variable Group to a specific environment in my VSTS release process. I can't honestly see how these would be any use to me without this feature.
I've experimented with one workaround, but it didn't work. I tried:
Naming my variable group & variables with an environment prefix e.g.
Variable Group Name="Production ConnectionStrings"
Variable name="Production_LoggingConnectionString"
I thought once I linked the "Production_ConnectionStrings" variable, I could reference $(Production_LoggingConnectionString) from within a standard Process variable, but this didn't work.
I think I could come up with some powershell that would do something like the above and set variables, but this seems a bit too custom for me.
Does anyone else have an idea that I can use variable groups per environment, easily, without waiting around for VSTS to build this feature (if ever). Btw, if you want this feature, there is a suggestion here you can upvote: Make it possible to link a variable group to a specific environment in a release definition
This has now been implemented in VSTS variable groups as scopes. Go to your release definition -> Variables -> Variable Groups -> Link variable group, and you get the link window as below, where you can choose the scope to be either release or one or more of your environments!
I did not manage to find any release information on this feature, I just stumbled upon it as I was tweaking my releases.
I ended up using a powershell script to define my process variable based on the variable groups, it works great.
Let's say I want a variable named "LoggingConnectionString" and this has different values per environment
Steps:
Define a Variable group, e.g. "SharedLoggingVariables"
Inside this Variable group, define a variable/value for each environment, e.g. "LoggingConnectionStringDev", "LoggingConnectionStringProduction"
Back in your Process Variables for the Build/Release, make SURE you don't have a variable named "LoggingConnectionString", otherwise this will overwrite the value coming from the variable group
In your Release process, create a Powershell inline script at the beginning of the Agent with the following code
Param(
[string]$LoggingConnectionString
)
Write-Host "##vso[task.setvariable variable=LoggingConnectionString]$LoggingConnectionString"
Pass your variable group as an argument to this inline powershell, e.g.
-LoggingConnectionString "$(LoggingConnectionStringDev)"
The final powershell step should look something like this:
During release, the powershell will set your process variable from the variable groups. If powershell isn't an option for you, there are other options
No, there is no way to use variable Groups per environment.
As the user voice you linked, you can vote and follow up for the suggested feature.
The work around for now is using environment variables to overwrite the variables in variable Group.
Assume the variable LoggingConnectionString with the value Server=myDB in variable group need to be used both for Dev environment and staging environment. But for staging environment, it needs to use another value (such as Server=stageDB) from the variable LoggingConnectionString. So you can add the an environment variable LoggingConnectionString with the value Server=stageDB for staging environment.
When the variable $(LoggingConnectionString) is used in Dev environment, it will use the value (Server=myDB) defined in variable group.
When the variable $(LoggingConnectionString) is used in staging environment, since the variables both defined in environment variable and variable group, it will use the value (Server=stageDB) defined in environment variable.

How to retrieve local variables?

Is it possible to retrieve a local variable from a programme-function i've run in matlab? i.e. i want to retrieve a variable from the code, which is not appeared in the outputs.
Thanks in advance
The following describes code to add to the function itself to make the variable available outside the local scope. When you can't change the function, from the outside there is nothing to be done about changing the scope of course (which is intended, correct behaviour!!).
Dirty ways:
global variables
global t
t=2.468;
For scalars, strings, simple values: assign to variables in base workspace using evalin:
t=2.468;
evalin('base', ['var_in_base=' num2str(t) ';']);
Any other variable, use assignin:
A=magic(20);
assignin('base','A',A);
Proper way:
Inspect them during debugging
If you really want them outside the local scope, add them as output variable!!
Look at Declare function. You can access local variables if you return them as return values. If you do not, you can't access them from outside.
So in
function [mean,stdev] = stat(x)
n = length(x);
mean = sum(x)/n;
stdev = sqrt(sum((x-mean).^2/n));
You have access to mean and stdev but there is no way to access n.
I don't know matlab at all, but from programmer's logic
that seems improper and impossible without hacking the code.
That being said, through Google I saw this:
When you call a script from a function, the script uses the function workspace.
Like local functions, nested functions have their own workspaces. However, these workspaces are unique in two significant ways:
Nested functions can access and modify variables in the workspaces of the functions that contain them.
All of the variables in nested functions or the functions that contain them must be explicitly defined. That is, you cannot call a function or script that assigns values to variables unless those variables already exist in the function workspace.
Base and Function Workspace
Not sure if this helps you at all, but it may clarify some points

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.