How to access module scope in module function - boost-python

I want to access the module scope in a c++ function. scope() isn't doing what I want.
void module_function()
{
\\ Want to access module scope here
}
BOOST_PYTHON_MODULE(my_module)
{
def("module_function", &module_function);
scope().attr("my_attribute") = "foo";
}

Related

Access a variable from parent scope

In Single Module Scenario: Running Set-Var returns 10.
# m.psm1
function Set-Var {
$MyVar = 10
Get-Var
}
function Get-Var {
$MyVar
}
In Nested Modules Scenario: Running Set-Var does not return any value.
# m1.psm1
function Get-Var {
$MyVar
}
# m.psm1
Import-Module .\m1.psm1
function Set-Var {
$MyVar = 10
Get-Var
}
How do I achieve the same effect as a single module with nested modules? Using $script:MyVar also does not work. However, I would like to keep the scope of the variable local to enable concurrent executions with different values.
Your code doesn't work because local variables are not inherited by functions in nested module context.
You can do this instead:
$null = New-Module {
function Get-Var {
[CmdletBinding()] param()
$PSCmdlet.SessionState.PSVariable.Get('MyVar').Value
}
}
The New-Module command creates an in-memory module, because this code only works when the caller is in a different module or script.
Use the CmdletBinding attribute to create an advanced function. This is a prerequisite to use the automatic $PSCmdlet variable, which we need in the next step.
Use its SessionState.PSVariable member to get or set a variable from the parent (module) scope.
This answer shows an example how to set a variable in the parent (module) scope.
See also: Is there any way for a powershell module to get at its caller's scope?

Is it possible to access static methods and attributes outside the class in Raku?

In raku it seems possible to define static methods (via sub keyword) and static attributes (via my) Those can be referenced inside the same class.
However, is it possible to access those methods and attributes outside of the class?
Something similar to this:
class MyClass {
my $attribute = 123;
sub my-method {
say 'Hello';
}
}
MyClass.$attribute;
MyClass.my-method;
it seems possible to define static methods (via sub keyword) and static attributes (via my) Those can be referenced inside the same class.
I can see why you're calling them static methods and attributes but Raku has a much simpler solution for those:
class MyClass {
method my-method {
say 'Hello';
}
method attribute is rw {
state $attribute = 123
}
}
say MyClass.attribute; # 123
MyClass.attribute = 99;
say MyClass.attribute; # 99
MyClass.my-method; # Hello
You could use our subs and our variables. our is the declarator used to define a lexical that is also for use outside the package it's declared withing. (mys are never shared; a sub declarator without an our is the same as my sub.)
So:
class MyClass {
our sub my-sub {
say 'Hello';
}
our $attribute = 123
}
import MyClass;
say $MyClass::attribute; # 123
$MyClass::attribute = 99;
say $MyClass::attribute; # 99
MyClass::my-sub; # Hello
As you can see, these aren't methods; this approach ignores OOP in the sense the prior solution does not.

Can I use in Google Apps Scripts a defined Class in a library with ES6 (V8)?

I'm trying to use a class defined in a library but I only receive an error as a result.
[LibraryProject]/library/model/Update.gs
class Update {
constructor(obj = {}) {
if(typeof obj == "string"){
options = JSON.parse(obj);
}
Object.assign(this, obj);
}
text(){
return (this.message && this.message.text)?this.message.text:''
}
}
TASKS
✅ Create a new version of the project. (File > Manage versions...)
✅ Load this library in another project [Alias: CustomService] (Resources > Libraries...)
✅ Use functions of CustomService
❌ Use class of CustomService
If I try to use a Class
[NormalProject]/index.gs
function test (){
Logger.log(CustomService.libraryFunction())
var update = new CustomService.Update("");
Logger.log(update)
}
TypeError: CustomService.Update is not a constructor (línea 3, archivo "Code")
How can I instantiate an Object of this Class?
If I run...
Logger
As written in the official documentation,
Only the following properties in the script are available to library users:
enumerable global properties
function declarations,
variables created outside a function with var, and
properties explicitly set on the global object.
This would mean every property in the global this object are available to library users.
Before ES6, All declarations outside a function (and function declaration themselves) were properties of this global object. After ES6, There are two kinds of global records:
Object record- Same as ES5.
Function declarations
Function generators
Variable assignments
Declarative record - New
Everything else - let, const, class
Those in the declarative record are not accessible from the global "object", though they are globals themselves. Thus, the class declaration in the library is not accessible to library users. You could simply add a variable assignment to the class to add a property to the global object(outside any function):
var Update = class Update{/*your code here*/}
References:
Library official documentation
Global environment records
Related Answers:
ES6- What about introspection
Do let statements create properties on the global object
Based on your tests, it appears that you cannot directly import a class from a GAS library. I'd recommend creating a factory method to instantiate the class instead.
Something along these lines:
// Library GAS project
/**
* Foo class
*/
class Foo {
constructor(params) {...}
bar() {...}
}
/* globally accessible factory method */
function createFoo(fooParams) {
return new Foo(fooParams);
}
// Client GAS project
function test() {
var foo = FooService.createFoo(fooParams);
Logger.log(foo.bar());
}

ghidra: how to get static variables using ghidra python api?

I have a following c code (from a benchmark):
int main(int argc, char *argv[])
{
static char buf[10] = "";
/* OK */
buf[9] = 'A';
return 0;
}
I am using ghidra api to get some information out of the binary (precompiled using flag -g). I want to get the variables defined in the function (or globally).
function.getStackFrame().getStackVariables()
gives me variables defined within the function, but it doesn't detect buf, as it is defined as static. From ghidra gui I was able to see that the variables is defined in the "main" under namespaces.
Is there way to get these type of variables (or global variables in general)?
If you compile with gcc, a static variable defined within a function (e.g., the variable buf, in your case) is represented as a global variable that starts with the same name and ends with a compiler-assigned numeric suffix. Such a variable will be assigned within Ghidra to the "global" namespace, rather than the function's namespace.
In Ghidra, each default global variable name ends with the variable's address. Each default local variable name starts with "local_" and ends with the variable's stack offset.
I've only used the Java API. But the Ghidra class hierarchy should be the same, regardless of whether you use Java or Python. Here is an example Java script that will list all non-default global and local variables in the current program:
// Lists non-default global and local variables in the current program.
//#category Example
import ghidra.app.script.GhidraScript;
import ghidra.program.database.ProgramDB;
import ghidra.program.database.symbol.NamespaceManager;
import ghidra.program.database.symbol.SymbolManager;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Variable;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolType;
public class ListVariables extends GhidraScript {
#Override
public void run() throws Exception {
// List globals
SymbolManager smgr = (SymbolManager)currentProgram.getSymbolTable();
NamespaceManager nmgr =
((ProgramDB)currentProgram).getNamespaceManager();
for (Symbol sym : smgr.getSymbols(nmgr.getGlobalNamespace())) {
if (monitor.isCancelled()) return;
if (sym.getSymbolType() == SymbolType.LABEL) {
String sname = sym.getName();
if (!sname.endsWith(sym.getAddress().toString())) {
printf("global : %s\n", sname);
}
}
}
//List local variables
for (Function func :
currentProgram.getFunctionManager().getFunctions(true)) {
for (Variable var : func.getLocalVariables()) {
if (monitor.isCancelled()) return;
String vname = var.getName();
if (!vname.startsWith("local_")) {
printf("%s : %s\n", func.getName(), vname);
}
}
}
}
}
The script writes its output to the Ghidra console window. Double-clicking a function or variable name in the Ghidra console window will jump the listing to the corresponding function/variable.

Add PowerShell function to the parent scope

I have some PowerShell helper functions in a file. I'd like to make them available to the scope of another file that I am writing, but not pollute the global scope.
Helpers.ps1
function global:Helper1
{
# this function pollutes the global scope
}
function Helper2
{
# this function is not visible to the Utility.ps1 file.
}
Utilities.ps1
&{
./Helpers.ps1
function global:Utility1
{
Helper1
}
function global:Utility2
{
Helper2
}
}
I found this question:
How do I dynamically create functions that are accessible in a parent scope? but the answers discuss adding functions to the global scope. What I really want to do is make the Helper functions from one PS1 file available to a calling PS1 file, without polluting the global scope with the helpers.
I want to avoid defining the functions as variables, which is possible with Set-Variable and the -Scope parameter. The closest I've seen (from the linked thread) is using Set-Item in the function: drive.
Any help would be appreciated!
Edit: here is the solution expanded from Mike's answer
Helpers.ps1
function Helper
{
}
Utilities.ps1
&{
function global:Utility
{
. ./Helpers.ps1
Helper1
}
}
Using the dot-source syntax to load Helpers.ps1 puts it's contents in the scope of the Utility function. Putting Helpers.ps1 outside the Utility function causes it to be in the &{...} scope but that scope ends once the functions are defined.
You can use this snippet in the Utilities.ps1 file. What we do is get all current functions then we dot source the helpers. We then make a diff of the before and after functions. From the diff we recreate the functions in the global scope.
$beforeFunctions = ls function:
. .\helpers.ps1
$afterFunctions = ls function:
$functionDiff = #(Compare-Object $beforeFunctions $afterFunctions)
foreach($diffEntry in $functionDiff){
$func = $diffEntry.InputObject
invoke-expression "function global:$($func.Name) { $($func.definition) }"
}
If you dot-source a .ps1 file in a function, the definitions that are in the ps1 file are not global, unless the function was itself dot-sourced.