有条件地在鱼中设置局部变量

时间:2018-12-08 17:17:34

标签: fish

我已经仔细阅读了鱼壳文档,并且试图找出如何在fish函数中有条件地设置局部变量。

换句话说,如果您有一个函数,并且希望使用if-then-else逻辑来修改局部变量。

function foo
    set --local variable something
    if blah
        set --local variable something_else
    end
end

例如,假设我有一个琐碎的函数,它接受文件名作为参数,如果文件扩展名丢失,我想将其添加到参数中。

function frob
    set --local filename $argv[1]
    echo "Before: $filename"

    if not string match --regex --entire "\.fish" $filename
        set --local filename $filename.fish
    end

    echo "After: $filename"
end

问题在于,由于局部变量仅具有块作用域,因此无法正常工作。运行“ frob”功能只会在“ Before”和“ After”中打印相同的内容。

我能想到的唯一解决方法是使用临时全局变量,然后在函数末尾手动将其删除。

示例:

function frob
    # Use global variable, and try to handle collisions
    if  set --query --global filename
        set --global filename_saved $filename
    end

    set --global filename $argv[1]
    echo "Before: $filename"

    if not string match --regex --entire "\.fish" $filename
        set --global filename $filename.fish
    end

    echo "After: $filename"

    # Restore old saved value
    if set --query --global filename_saved
        set --global filename $filename_saved
        set --erase --global filename_saved
    else
        set --global --erase filename
    end
end

但是,此方法存在两个问题。首先,我想检查与先前存在的全局变量的可能冲突,并保存所有要在脚本退出时恢复的现有值。

不幸的是,如果我的脚本由于错误而意外结束,则有可能永远不会执行“清理”代码。

我是否缺少解决此问题的更好方法?

1 个答案:

答案 0 :(得分:3)

“本地”有点用词不当。它是“块作用域”的。

这意味着您这样做

begin
   set -l foo
end

$foo仅在该块中定义。

类似

set -l foo
begin
    set -l foo
end

将在该块中创建$foo的第二个版本,并在该块结束后返回另一个版本。

因此,您需要做的是在块外部定义它,然后在内部进行更改:

set -l foo
begin
    set foo bar
end

function frob
    set --local filename $argv[1]
    echo "Before: $filename"

    if not string match --regex --entire "\.fish" $filename
        set filename $filename.fish
    end

    echo "After: $filename"
end