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.
Related
There is a module that has an "initialize" function that sets a variable that gets used in other scripts/functions in the module to validate that the initialize function was run. Something like
Start-InitializeThing
Connect to the API
$Script:SNOWinit = $true
Then in another script/function it will check:
if ($Script:SNOWinit -eq $true) { Do the thing!}
Is there a way to grab that $Script:SNOWinit in the same PowerShell window, but not the same module?
I want to run the same check but for a different function that is not in the module.
Can I do this, can I "dig" into like the modules runspace and check that variable. I don't have the means to edit the functions in the module so I cant change what type of variable is set once the initialize script has run.
Assuming that the module of interest is named foo and that it has already been imported (loaded):
. (Get-Module foo) { $SNOWinit }
If you want to import the module on demand:
. (Import-Module -PassThru foo) { $SNOWinit }
The above returns the value of the $SNOWinit variable defined in the root scope of module foo.
See this blog post for background information.
Note that it is generally not advisable to use this technique, because it violates the intended encapsulation that modules provide. In the case at hand, $SNOWinit, as a non-public module variable, should be considered an implementation detail, which is why you shouldn't rely on its presence in production code.
From the bible, WPiA. More mysterious uses for the call operator.
# get a variable in module scope
$m = get-module counter
& $m Get-Variable count
& $m Set-Variable count 33
I am currently learning about Perls system of typeglobs and namespaces. So I wrote a module that takes two arguments the value and the name of a constant and exports the constant to the caller. The $package variable is equal to caller[2].
*{"$package::$name"} = sub () { return $value; };
This code above does the job of exporting a anonymous subroutine into the callers symboltable. Because my goal is to build my own constant-implementation the subroutine has a empty prototype which means its a read-only subroutine.
But this is my problem: the prototype does not work. So
print &TestConst; #works well
print TestConst(); #works well
print TestConst; #Name "main::TestConst" used only once: possible typo at testscript.pl line 7.
Is there something wrong in my thoughts? Is there another way of doing it?
You can define all the symbols you want during runtime, but prototypes will only affect code compiled afterwards since prototypes affect how calls to the sub are parsed and compiled. For example:
use strict;
use warnings;
package Foo;
BEGIN {
*Foo::bar = sub () { 42 };
}
*Foo::baz = sub () { 43 };
my $bar = bar;
my $baz = baz;
print "bar = [$bar], baz = [$baz]\n";
If we run this, it dies with:
Bareword "baz" not allowed while "strict subs" in use at tprot.pl line
13.
That's a compile-time error caused by strict: the compiler saw the symbol baz and didn't know what it was, because the typeglob *Foo::baz does not get altered until runtime. But bar worked fine because it was defined in a BEGIN block, which executes immediately during compilation.
IOW, because barewords are ambiguous, Perl needs to know at compile-time whether it's a sub or something else. So you can install these during import (which executes in an implicit BEGIN block) but not at runtime.
Additionally, prototypes affect compilation semantics; a constant subroutine (like those made by constant.pm) gets optimized away. Other prototypes cause the parser to change its behavior (e.g. subs which can take code blocks.) The compiler has to know about all this stuff before calls to the sub are actually encountered in the code, so they can be parsed correctly. The code runs after everything is already parsed.
Calling a sub with explicit parens or with an ampersand does not have this restriction because Perl is smart enough at runtime to know that these are subroutine calls, and to look them up dynamically in the symbol table.
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")
Is there a way to have a function in Lua that can be accessed from any module in a project without having to first require it?
something like:
module(..., package.seeall);
function globFoo()
print('global foo called');
end
and have it called from somwhere else, like main
--main
globFoo();
without requiring it?
A module is just a Lua script. You can do whatever you want there; you don't even have to call module in your module script. Indeed, module is generally considered harmful these days, which is why it was deprecated in Lua 5.2.
Really, it's a matter of simply moving your code around:
function globFoo()
print('global foo called');
end
module(..., package.seeall); --Module created after global function
So yes, you can have a module modify the global table. I would very much suggest that you don't (because it creates implicit ordering between Lua scripts, which makes it hard to know which script uses which stuff). But you can do it.
A sample of how this is done :
in global.lua (where the global function is located) :
globalFunction1 = function(params)
print("I am globalFunction1")
end
In the calling file, caller.lua :
globalFunction1(params) -- This will call the global function above
I'm going back to the basics here but in Lua, you can define a table like so:
myTable = {}
myTable [1] = 12
Printing the table reference itself brings back a pointer to it. To access its elements you need to specify an index (i.e. exactly like you would an array)
print(myTable ) --prints pointer
print(myTable[1]) --prints 12
Now functions are a different story. You can define and print a function like so:
myFunc = function() local x = 14 end --Defined function
print(myFunc) --Printed pointer to function
Is there a way to access the body of a defined function. I am trying to put together a small code visualizer and would like to 'seed' a given function with special functions/variables to allow a visualizer to 'hook' itself into the code, I would need to be able to redefine the function either from a variable or a string.
There is no way to get access to body source code of given function in plain Lua. Source code is thrown away after compilation to byte-code.
Note BTW that function may be defined in run-time with loadstring-like facility.
Partial solutions are possible — depending on what you actually want to achieve.
You may get source code position from the debug library — if debug library is enabled and debug symbols are not stripped from the bytecode. After that you may load actual source file and extract code from there.
You may decorate functions you're interested in manually with required metadata. Note that functions in Lua are valid table keys, so you may create a function-to-metadata table. You would want to make this table weak-keyed, so it would not prevent functions from being collected by GC.
If you would need a solution for analyzing Lua code, take a look at Metalua.
Check out Lua Introspective Facilities in the debugging library.
The main introspective function in the
debug library is the debug.getinfo
function. Its first parameter may be a
function or a stack level. When you
call debug.getinfo(foo) for some
function foo, you get a table with
some data about that function. The
table may have the following fields:
The field you would want is func I think.
Using the debug library is your only bet. Using that, you can get either the string (if the function is defined in a chunk that was loaded with 'loadstring') or the name of the file in which the function was defined; together with the line-numbers at which the function definition starts and ends. See the documentation.
Here at my current job we have patched Lua so that it even gives you the column numbers for the start and end of the function, so you can get the function source using that. The patch is not very difficult to reproduce, but I don't think I'll be allowed to post it here :-(
You could accomplish this by creating an environment for each function (see setfenv) and using global (versus local) variables. Variables created in the function would then appear in the environment table after the function is executed.
env = {}
myFunc = function() x = 14 end
setfenv(myFunc, env)
myFunc()
print(myFunc) -- prints pointer
print(env.x) -- prints 14
Alternatively, you could make use of the Debug Library:
> myFunc = function() local x = 14 ; debug.debug() end
> myFunc()
> lua_debug> _, x = debug.getlocal(3, 1)
> lua_debug> print(x) -- prints 14
It would probably be more useful to you to retrieve the local variables with a hook function instead of explicitly entering debug mode (i.e. adding the debug.debug() call)
There is also a Debug Interface in the Lua C API.