修改 package 中函数定义

抱歉我是一个新手,可能接下来的问题非常的蠢,还请见谅:

  • 在 julia meta-programming 时看到 macro 可将函数调用作为参数,而使用户可以 macro 实现在函数执行前后插入代码的功能。我在想这种方式的侵入性是否还是太大了,如果是开发一个 package 的话,会给用户引入多余操作。同时使用 macro 的方式貌似也并不特别强大。(据我理解,macro 应该仅能处理传入的 expr,而对 expr eval 过程中的具体内容无能为力,比如:)
function say233()
    println("233")
end

function sayhello()
    say233()
    println("Hello")
end

macro saybyebye(f)
    return quote
        $f
        println("byebye")
    end
end

// saybyebye 可以在 Hello 后打印 byebye,但无法做到在 233 后打印 byebye
@saybyebye sayhello()
  • julia 可以在运行时重定义函数。很自然的是,不能在重定义函数时使用先前定义的函数。比如:
f(x) = x+1
f(x) = x+2
println(f(2)) # 3

# f(x) = f(x) + 1 # failure

所以我的问题是,在 julia 中是否存在一种优雅的方法能够对某 package 中的特定个 function 进行修改,使之相较于原 function 都插入了一段或几段新的代码片段(函数定义上或执行效果上都可以)。我随便瞎写了几种我觉得侵入性更低的样子,但我不知道是否有类似实现方法,比如这样:

using Pkg
using PkgHacked # 可否在这个 package 中对 Pkg 的部分函数进行修改,且修改过后的 function 在 export 后还是将 Pkg 作为 Module

function add()
    Pkg.add("Plots") # 但它相较于原本的直接添加 package,多打印了一句 “Hello”
    Pkg.add("CSV") # 但它相较于原本的直接添加 package,多打印了一句 “Hello”
end

add()

或这样:

using Pkg
using PkgHacked: hackzone # 可否定义这样一个函数……

function add()
    Pkg.add("Plots") # 但它相较于原本的直接添加 package,多打印了一句 “Hello”
    Pkg.add("CSV") # 但它相较于原本的直接添加 package,多打印了一句 “Hello”
end

hackzone() do
    add()
end

不知道我有没有描述清楚我的问题,还希望各位大大不吝赐教~

取决与你怎么理解“优雅”,简单点,可能直接实现overwrite一个相同signature的函数就行了,但是用户执行的时候,会报一个warning

我对优雅的定义是对原 package 侵入性小,希望用户可以依旧通过调用原 package API 的方式调用我新实现的功能。

想请教下这里所说的 “直接实现 overwrite 一个相同 signature 的函数” 具体是怎么操作呢?

显式的 import 需要修改的函数然后定义一个同名函数就行,比如 import Foo:foo,然后定义

function foo(...)
    ...
end

或者不想导入也可以直接

function Foo.foo(...)
    ...
end

就能重载原函数或者定义新的参数