I'm trying to create a config.ps1 file which contains all of the variables my scripts needs. Inside those scripts there are several functions. But when i dot source these variables they do not work inside my function. How do i get them to work?
. ./config.ps1
function RollOut {
write-host "$Rolling"
}
Where $Rolling is defiend in config.ps1
$Rolling="Go"
Thanks!
You need to make your variables in config.ps1 available on the global scope.
Change the definition to:
$Global:Rolling = "Go"
Related
I would like to define function in file functions.ps1 and then call it from another script. Something like this:
Functions.ps1:
Function Hi()
{
"hi"
}
Call it from another script (Call.ps1).
Call.ps1:
invoke-expression -Command .\functions.ps1
Hi
But function is defined in local scope of script functions.ps1 and I get err:
The term 'hi' is not recognized as the name of a cmdlet, function,
script file , or operable program. Check the spelling of the name, or
if a path was included, v erify that the path is correct and try
again.
Is there a simple way to fix this ?
You have to dotsource your script to load it into your current runspace:
. .\functions.ps1
Hi
I think the way to do this would be to dot soruce the file in the script that should use the function(s).
So in the script that will use the function put something like this.
. .\functions.ps1
Then you can start calling funcitons in that file.
A bit by memory , but think it would work.
Edit: removed a brainfart.. :)
Yup, dotsource is what you're looking for.
If your script contains spaces, you would dot source it like this
."C:\Dotsourced script.ps1"
Without space, is as the other people say
.C:\function1.ps1
All the functions and logic contained in the dotsourced script will be loaded upon sourcing it. So try to keep the scripts your'e dotsourcing in functions, otherwise it will run when sourced.
Read more about it on SS64 for example:
https://ss64.com/ps/source.html
I've got an auto hotkey function:
loadkeyboard(ALanguage)
{
local i
k:=1
loop{
if k=512
break
a:=GetBits(k)
IniRead letter%a%,Keyboards.ini,%ALanguage%,%a%
if letter%a%=ERROR
letter%a%=
else
if(letter%a%="space")
letter%a%:=" "
k:=k+1
}
return true
}
in this function, what does local i mean? because i is not getting used anyware, and I think that in functions, all variables are by default local, so, what's the use of this line? I tried removing this line, and after removing / commenting, function stopped working. and I've changed the variable name after local keyword, but it worked good, can anyone please help?
By declaring a local variable on the first line of a function you are putting the function in to Assume-global mode
This makes all other Variables then "i" global so that there value can be used or set outside of your function.
So in a way you can replace "local i" with global and get the same result.
I am having a few issues, calling Python functions defined in another script using tkinter. I would prefer to have a separate script for my functions that the GUI uses when needed. At the moment I am doing it like this.
ttk.Button(mainframe, text="1", command=one).grid(column=1, row=1, sticky=NW)
def one():
code_entry.insert(END,"1")
The above calls the command one on a button click, which will print the character one in a entry field with the GUI. I thought I could create a separate script to hold my functions and call them like this:
ttk.Button(mainframe, text="1", command=functions.one()).grid(column=1, row=1, sticky=NW)
And then simply add an import statement at the top of my GUI, like below:
import functions
This doesn't work and looking for some advice on how to approach this.
You didn't specify any error messages, but it's most likely that you're doing fuctions.one() - actually calling the one() function of that module before the Button is created. It's simply fixed by removing the () part - when you specify a function without (), you are passing a reference of the function object.
Also keep in mind the scope of the code_entry variable - if you were using it as a module level global before (or function local, if one() was inside the same function as your ttk.Button call), it won't be available when you move it to a new namespace without code_entry.
To solve this you should pass code_entry as a parameter to the callback without calling one() at first. The usual approach for this is creating a lambda - essentially creating a function that works on the same scope of the original one(), having access to variables like code_entry, but also calling a function in a different module.
ttk.Button(mainframe, text="1", command=lambda: functions.one(code_entry))
Note that this is basically the same as:
def some_anonymous_function():
functions.one(code_entry)
ttk.Button(mainframe, text="1", command=some_anonymous_function)
Both examples create a function object and pass that object as reference - the functions.one() call of the lambda is actually inside the body of the lambda function, to be called later by tkinter.
Of course you also have to redefine one() to accept this new parameter:
def one(code_entry):
code_entry.insert(END,"1")
I had an old ipy_user_conf.py in which I included a simple function into the user namespace like this:
import IPython.ipapi
ip = IPython.ipapi.get()
def myfunc():
...
ip.user_ns['myfunc'] = myfunc
Then, I could use myfunc in the prompt.
However, I updated to IPython 0.12.1 and now the ip_user_conf.py does not work. I haven't seen how to translate such a custom function for prompts to the new configuration model.
Which is the way to do this?
Best regards,
Manuel.
UPDATE: Changed the subject to question
After reading a bit of the documentation (and peeking at the source code for leads) I found the solution for this problem.
Simply now you should move all your custom functions to a module inside your .ipython directory. Since what I was doing was a simple function that returns the git branch and status for the current directory, I created a file called gitprompt.py and then I included the filename in the exec_file configuration option:
c.InteractiveShellApp.exec_files = [b'gitprompt.py']
All definitions in such files are placed into the user namespace. So now I can use it inside my prompt:
# Input prompt. '\#' will be transformed to the prompt number
c.PromptManager.in_template = br'{color.Green}\# {color.LightBlue}~\u{color.Green}:\w{color.LightBlue} {git_branch_and_st} \$\n>>> '
# Continuation prompt.
c.PromptManager.in2_template = br'... '
Notice that in order for the function to behave as such (i.e called each time the prompt is printed) you need to use the IPython.core.prompts.LazyEvaluation class. You may use it as a decorator for your function. The gitprompt.py has being placed in the public domain as the gist: https://gist.github.com/2719419
PowerShell provides a simple technique to view the contents of a function, e.g.
Get-Content function:MyFuncName # (A)
or equivalently
(Get-ChildItem function:MyFuncName).definition # (B)
where MyFuncName is the name of my function. That is great for simple functions (i.e. functions that use only base language constructs and do not call other functions). But consider the function foo shown below that contains a call to the function bar. In a typical scenario these would both be contained in the same module whose public API consists solely of the function foo and thus it is the only function exported.
function foo ()
{
$p = bar "here"
"result is '$p'"
}
function bar ([string] $s)
{
$s + $s
}
Export-ModuleMember foo
Is there any way to view the nested, non-exported functions (like function bar) within another function in a fashion comparable to (A) or (B) above? (That is, without opening the .psm1 file in an editor :-)
I'm not sure if you can do it for a particular function in a module but you can do it for the whole module:
Import-Module C:\Test.psm1
(Get-Module Test).Definition
I think the fact that function foo calls function bar is not known until runtime.
Update
Where there's a will, there's a way :-) Here's how you can access private module members. Invoke the module with a scriptblock. Inside the scriptblock the private members are visible.
Import-Module C:\Test.psm1
$module = Get-Module Test
& $module { (get-item function:bar).Definition }
Thanks to PowerTips :-) http://powershell.com/cs/blogs/tips/archive/2009/09/18/accessing-hidden-module-members.aspx
Update 2
After finding the little PowerTip snippet I was kinda curious what was really going on... The snippet uses the call operator & with two arguments.
The module object (System.Management.Automation.PSModuleInfo)
A script block
So what's really going on is the Invoke method of the PSModuleInfo type is being called. The code in the script block runs within the same session state as the rest of the module code so it has access to the private members. This code does the exact same thing as the PowerTip snippet:
$module = Get-Module Test
$module.Invoke( { (get-item function:bar).Definition } )
Check out the invoke method here: http://msdn.microsoft.com/en-us/library/system.management.automation.psmoduleinfo.invoke(v=vs.85).aspx
No. The method you're using is getting the definition of the function via the function provider in the local scope. It will only see functions that have been defined in the local scope or that are visible in parent scopes.
When you call a function, it runs in it's own scope. Any functions the function creates will be created in that child scope, and only exist during the time that function is running. When the function is done, the scope it was running it gets disposed of, and all the functions it created go with it.