How can I set a global variable from a script/command line? - variables

I'm trying to create a little menu to switch from "YouCompleteMe" to "Supertab" and vice versa.
function! TabFunction()
if !exists("g:WhatTab")
let g:WhatTab = "Tab function?"
endif
if !exists("g:MenuTab_choices")
let g:MenuTab_choices = "&SuperTab\n&YouCompleteMe"
endif
let n = confirm(g:WhatTab, g:MenuTab_choices, "Question")
if n == 1
let g:SuperTabMappingForward = '<Tab>'
let g:SuperTabMappingBackward = '<S-Tab>'
let g:ycm_key_list_select_completion = ['<C-Tab>', '<Down>']
let g:ycm_key_list_previous_completion = ['<C-S-Tab>', '<Up>']
elseif n == 2
let g:SuperTabMappingForward = '<C-Tab>'
let g:SuperTabMappingBackward = '<C-S-Tab>'
let g:ycm_key_list_select_completion = ['<Tab>', '<Down>']
let g:ycm_key_list_previous_completion = ['<S-Tab>', '<Up>']
endif
endfun
This doesn't work.
When I try to check the value of these variables from the commandline
:echo 'global variable'
the values are correct but they don't work as expected.
Is it not possible to declare a global variable like this?

The use of the g: variable prefix ensures that the global variables are set from within a function; this is correct. Your problem is that the plugin configuration variables like g:SuperTabMappingForward are only evaluated once during plugin load (when Vim starts up), but not during runtime. This mechanism wasn't meant for dynamic reconfiguration.
Solutions
Instead of toggling the (ignored) config variables, you have to do the remapping yourself. At least SuperTab defines corresponding <Plug>... targets; I guess YCM does this, too:
if n == 1
imap <Tab> <Plug>SuperTabForward
...
elseif n == 2
imap <C-Tab> <Plug>SuperTabForward
Alternatively, the brute-force variant would be to reload the plugins (:runtime plugin/supertab.vim) to get the changed global variable values to be considered, but that's very inefficient, may cause errors, and makes you work around plugin load guards in addition.

Related

IBM DOORS: DXL script that follows link chain

Im totally new in DXL scripting and try to get deeper into it. Unfortunately DXL is not the best documented kind of language.
First of all let me describe the situation. I have 3 different folders. The first folder includes just a start modul. The other both folders include in each case some more modules.
I want to start with the start modul going through all objects inside of it to look out for incoming links. If there is an incoming link I want to follow this link to the outgoing object which is just a further object in a module in the second folder
and switch to it. From there I want to do the same procedure until objects in folder 3 are reached or rather until check if folder 2 module objects have incoming links from folder 3 module objects.
The reason I want to do this is to check if the link chain is complete or not and how many of them are complete or not. Means if folder 1 module objects have incoming links from folder 2 module objects
and folder 2 module objects have incoming links from folder 3 module objects.
Thats want I ve got so far:
pragma runLim, 0
int iAcc = 0
int iRej = 0
int linkChainComplete = 0
int linkChainNotComplete = 0
string startModulPath = "/X/X.1"
Module m
m = read(startModulPath)
Object o
Link l
filtering off
Filter f = hasLinks(linkFilterIncoming, "*")
for o in m do {
bool isComplete = true
set(m, f, iAcc, iRej)
if(iAcc == 0){
isComplete = false
}
else{
for l in o <- "*" do {
Object src = source l;
set(m, f, iAcc, iRej)
if(iAcc == 0){
isComplete = false
}
}
}
if(isComplete){
linkChainComplete++
}
else{
linkChainNotComplete++
}
}
The first question is, am I on the right path?
And one question or rather problem is for example that I want to proof if there are incoming links by using the hasLinks function (concerning this also see "set(m, f, iAcc, iRej) and if(iAcc == 0)" part.
But this function refers to the module (m) instead objects (o). Is there another way to proof if an object has got incoming links or not?
Hope anyone could help me. Thank you very much indeed.

Why is a DOORS Module sometimes null when trying to edit the Module via DXL?

I'm new to DXL programming language in IBM DOORS. However, I think I have managed to do many interesting things: create Modules, create Objects, create Links, delete Objects etc.
However, I have a very specific problem regarding "null" Modules. I've just written null between "" because the modules exist and they are referenced with a correct name.
When doing this:
Module m1 = edit("1. MY_MODULE", false)
save(m1)
close(m1)
An error like this appears:
enter image description here
You could not understand what does that mean as it is spanish. Basically states this: "Module null parameter in the first position of the argument." That means that the "m1" is null, as the parameter for save() method is null.
The point is that it is an error which appears only sometimes. It seems that the Module is null as it has been previously opened and DOORS does not close properly.
Is there any way, any method...whatever to avoid this error?
I assume that the script cannot find the module when another folder is active.
Try
Module m1 = edit ("/myproject/myfolder/mysubfolder/1. MY_MODULE", false)
There might be many reasons that the module can't be opened in edit mode. For example: User do not have write access OR Module is being used by other user, etc.
However, you can get around the error with the below code snippet:
Module m = edit('My_module', false)
if(!null m) {
//execute program
...
}
else {
//do something
}
I hope this helps.
How does your script work? do you open the same module again and again and sometimes get the error or do you open lots of modules and for some of them it works and for others it doesn't? In the latter case, perhaps you misspelled the path. You could add some sanity checks like
string fullPathToMod = "/myproject/myfolder.."
Item i = item fullPathToMod;
if null i then error "there is no item called " fullPathToMod
if "Module" != type i then error "there is an item, but it's not a module, it's a " type i
This is how the Code is structured:
void checkModule(string folderPath, string mName, Skip list, int listSize, int listLastIndex, string headers[], string heading[], string headerKey, bool uniqueKey, string combinedKey[]){
if (module mName){
Folder f = folder(folderPath)
current = f
Module m = edit(folderPath""mName, false)
current = m
Object o = first(m) // error sometimes: Se ha pasado un parametro Module null en una posiciĆ³n de argumento 1
if (o == null){
loadModule(m, list, listSize, listLastIndex, headers, heading)
} else {
updateModule(m, mName, list, listSize, listLastIndex, heading, headerKey, headers, uniqueKey, combinedKey)
save(m)
close(m)
}
if (lastError() != ""){
print "Error: " lastError() "\n"
}
} else {
print "No module " mName ".\n"
}
}
Exactly it breaks in line:
current = m
But as said, only sometimes, not always.
BTW, I'm executing this script via Batch, via Java code. One curious thing is that if I close DOORS, and execute the script it does execute correctly. It is as if it needs to be closed in order to edit modules correctly.
I pressume current can be used more than once with different types of Items. I guess it should not be wrong, but it breaks saying (more or less):
Null value passed to DXL commmand (current Module).
Obviously, it means that m is null, but I cannot see any reason for that.

Define a variable and set it to a default value if something goes wrong during definition

I have the following code in my build.gradle
Contents in version.properties are:
buildVersion=1.2.3
Value of $v variable during the Gradle build is coming as: 1.2.3
Value of $artifactoryVersion variable in JENKINS build is coming as: 1.2.3.1, 1.2.3.2, 1.2.3.x ... and so on where the 4th digit is Jenkins BUILD_NUMBER available to gradle build script during Jenkins build.
BUT, when I'm running this build.gradle on my desktop where I dont have BUILD_NUMBER variable available or set in my ENVIRONMENT variables, I get an error saying trim() can't work on null. (as there's no BUILD_NUMBER for Desktop/local build).
I'm trying to find a way i.e.
What should I code in my script so that if BUILD_NUMBER is not available, then instead of gradle build processing failing for an error, it'd set jenkinsBuild = "0" (hard coded) otherwise, pick what it gets during Jenkins build.
For ex: in Bash, we set a variable var1=${BUILD_NUMBER:-"0"} which will set var1 to a valid Jenkins BUILD number if it's available and set to a value, otherwise if it's NULL, then var1 = "0".
I DON'T want to have each developer/user set this BUILD_NUMBER in some property file. All I want is, if this variable doesn't exist, then the code should put "0" in jenkinsBuilds variable and doesn't error out during desktop builds. I know during Jenkins build, it's working fine.
// Build Script
def fname = new File( 'version.properties' )
Properties props = new Properties()
props.load( new FileInputStream( fname ) )
def v = props.get( 'buildVersion' )
def env = System.getenv()
def jenkinsBuild = env['BUILD_NUMBER'].trim()
if( jenkinsBuild.length() > 0 ) {
artifactoryVersion = "$v.$jenkinsBuild"
}
All you need is some regular Java/Groovy code:
def jenkinsBuild = System.getenv("BUILD_NUMBER") ?: "0"
The code above uses Groovy's "elvis" operator, and is a shorthand for the following code, which uses Java's ternary operator:
def buildNumber = System.getenv("BUILD_NUMBER")
def jenkinsBuild = buildNumber != null ? buildNumber : "0"
Here's the answer to using a Java plain object (JDK8):
public class Sample {
private String region;
private String fruit;
public Sample() {
region = System.getenv().getOrDefault("REGION", null);
fruit = System.getenv().getOrDefault("FRUIT", "apple");
}
}
With the Env-Inject plugin you can get and set build parameters.
For example, under "Inject environment variables to the build process", add a Groovy script such as:
def paramsMap = [:]
def build = Thread.currentThread().executable
def my_var = build.getEnvVars()["MY_PARAM"]
if (!my_var) paramsMap.put("MY_PARAM", "default value")
// Return parameters map
out.println("Injecting parameters:\n" + paramsMap)
return paramsMap

How to set constant seeds for Haskell's quickCheck function

Every time I run "quickCheck prop_xyz", a new random seed is used. How do I enforce QuickCheck to always use the same random seed?
Thanks!
The functionality you need is in Test.QuickCheck; use quickCheckWith to specify custom Args. In particular, there's the replay :: Maybe (StdGen, Int) field, which allows you to replay tests. So you can use the stdArgs defaults and tweak them; for instance,
ghci> :load Main.hs
ghci> import Test.QuickCheck
ghci> import System.Random -- for mkStdGen
ghci> quickCheckWith stdArgs{replay = Just (mkStdGen 42, 0)} prop_xyz
The second component of the tuple has to do with the size of the test cases, but I forget exactly what.
Use the quickCheckWith function
quickCheckWith (stdArgs{replay = Just (myNewGen, testSize)}) property
If you have a test that's failing and you want to reuse it,
result <- quickCheckResult failing_prop
let gen = usedSeed result
let size = usedSize result
to get the size and seed used in a failing test.
Since you also want reproducible errors, a good shrinking algorithm may help. By default it returns [] but provide a nice enough one, then you can end up with the same (minimal) failures even on different random runs.
Example with QuickCheck >= 2.7 and tf-random.
If the output of your failing test run looks something like this:
Failure {
usedSeed = TFGenR 1CE4E8B15F9197B60EE70803C62388671B62D6F88720288F5339F7EC521FEBC4 0 70368744177663 46 0,
USEDSIZE = 75,
...
}
Then you can reproduce the failure as follows:
import Test.QuickCheck.Random (QCGen(..))
import System.Random.TF (TFGen)
qcheck :: Testable a => a -> IO ()
qcheck prop = quickCheckWith args prop
where
usedSeed = QCGen (read "TFGenR 1CE4E8B15F9197B60EE70803C62388671B62D6F88720288F5339F7EC521FEBC4 0 70368744177663 46 0"::TFGen)
usedSize = 75
args = stdArgs{
replay=Just(usedSeed, usedSize)
}
If you want to determine the Generator that caused the failure you could do the following:
import Test.QuickCheck
import System.Random
reproducableTest :: Testable a => a -> Maybe (StdGen, Int) -> IO ()
reproducableTest prop repl = do result <- quickCheckWithResult stdArgs{replay = repl} prop
case result of
Failure{interrupted = False} -> do putStrLn $ "Use " ++ show (usedSeed result) ++ " as the initial seed"
putStrLn $ "Use " ++ show (usedSize result) ++ " as the initial size"
_ -> return ()
Only the first of the two seed numbers should be used as an argument for the function.
So if you have your property prop, your initial call would be reproducableTest prop Nothing. You will get something like
Use x y as the initial seed
Use z as the initial size
Then you would call again with reproducableTest prop $ Just (mkStdGen x , z)

boost::asio and make_shared does not work?

I seem to be able to use boost::make_shared everywhere except with boost asio?
example: _ioService = boost::shared_ptr<io_service>(new io_service)
if I turn this into: _ioService = boost::make_shared<io_service>()
I get all kinds of errors?
Same problem if I take:
_acceptor = boost::shared_ptr<tcp::acceptor>(new tcp::acceptor(*_ioService));
and turn it into this:
_acceptor = boost::make_shared<tcp::acceptor>(*_ioService);
As boost::asio::tcp::acceptor takes a boost::asio::io_service by non-const reference you need to change:
_acceptor = boost::make_shared<tcp::acceptor>(*_ioService);
to:
_acceptor = boost::make_shared<tcp::acceptor>(boost::ref(*_ioService));