从文件到函数内部全局范围的点源函​​数 [英] Dot-sourcing functions from file to global scope inside of function

查看:25
本文介绍了从文件到函数内部全局范围的点源函​​数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从文件中导入外部函数,而不是将其转换为模块(我们每个函数有数百个文件,因此将它们全部视为模块是多余的).

I want to import external function from file, not converting it to a module (we have hundreds of file-per-function, so treat all them as modules is overkill).

这里是代码解释.请注意,我在 Import-Function 中有一些额外的逻辑,例如添加脚本根文件夹并检查文件是否存在并抛出特殊错误,以避免在需要这种导入的每个脚本中出现此代码重复.

Here is code explanation. Please notice that I have some additional logic in Import-Function like adding scripts root folder and to check file existence and throw special error, to avoid this code duplication in each script which requires that kind of import.

C:\Repository\Foo.ps1:

C:\Repository\Foo.ps1:

Function Foo {
    Write-Host 'Hello world!'
}

C:\InvocationTest.ps1:

C:\InvocationTest.ps1:

# Wrapper func
Function Import-Function ($Name) {
    # Checks and exception throwing are omitted
    . "C:\Repository\$name.ps1"

    # Foo function can be invoked in this scope
}

# Wrapped import
Import-Function -Name 'Foo'
Foo          # Exception: The term 'Foo' is not recognized

# Direct import
. "C:\Repository\Foo.ps1"
Foo          # 'Hello world!'

有什么技巧可以将源点到全局范围吗?

Is there any trick, to dot source to global scope?

推荐答案

您不能让脚本在父作用域中运行,但您可以通过显式设置作用域在全局作用域中创建函数.

You can't make the script run in a parent scope, but you can create a function in the global scope by explicitly scoping it.

这样的事情对你有用吗?

Would something like this work for you?

# Wrapper func
Function Import-Function ($Path) {
    # Checks and exception throwing are omitted
    $script = Get-Content $Path
    $Script -replace '^function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)', 'function Global:$1'
    .([scriptblock]::Create($script))

}

上面的正则表达式只针对根函数(函数左对齐;左边没有空格词 function).为了定位所有函数,不考虑间距(包括子函数),将 $Script -replace 行更改为:

The above regex only targets root functions (functions left justified; no white space to left of the word function). In order to target all functions, regardless of spacing (including sub-functions), change the $Script -replace line to:

$Script -replace '^\s*function\s+((?!global[:]|local[:]|script[:]|private[:])[\w-]+)','function Global:$1'

这篇关于从文件到函数内部全局范围的点源函​​数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆