如何将函数标记为“@deprecate”?
How to mark functions as `@deprecate`d?
(问题参考Julia v1.5版本)
我正在尝试了解 @deprecate
宏在 Julia 中的工作原理。 documentation 不幸的是我不清楚:
@deprecate old new [ex=true]
Deprecate method old and specify the replacement call new. Prevent
@deprecate from exporting old by setting ex to false. @deprecate
defines a new method with the same signature as old.
Warning:
As of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().
Examples
julia> @deprecate old(x) new(x)
old (generic function with 1 method)
julia> @deprecate old(x) new(x)
false old (generic function with 1 method)
那我该怎么办?
function old(x::Int)
print("Old behavior")
end
function new(x::Int)
print("New behavior")
end
# Adding true/false argument doesn't change my observations.
@deprecate old(x) new(x) # false
old(3)
# Prints "Old behaviour". No warning.
# Also: The deprecation is not mentioned in the help (julia>? old)
这个@deprecate
宏的目的好像是替换函数?我觉得这违反直觉。如何将一个函数标记为已弃用(即用户应该收到警告和提示使用什么作为替代品,它也应该在文档中)?
编辑:我注意到我的错误。签名(在我的例子中是 ::Int
)必须相同才能工作。但是,如何获得警告?
假设您将此方法作为第 1 版库的 public API 的一部分:
# v1.0.0
mult3(x::Int) = 3x
在版本 2 中,您希望停止支持 mult3
(这是一项重大更改)。但是使用更通用的方法仍然可以使用相同的功能:
# v2.0.0
mult(x, y) = x * y
版本 1 的用户习惯使用 mult3
,这意味着当他们更新到 v2 时,他们的代码会崩溃。因此,您可能希望在 v1.x 系列中发布一个中间版本,其中 mult3
存在但已弃用并根据 mult
:
实现
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated and implemented using the old one
@deprecate mult3(x::Int) mult(3, x)
# The above is more or less equivalent to defining
# function mult3(x::Int)
# # print an error message is `--depwarn` has been set
# return mult(3, x)
# end
v1 API 在晚期 v1.x 版本中没有损坏,但调用已弃用方法的用户将看到以下类型的消息,以帮助他们过渡到较新的 v2 API:
julia> mult3(14)
┌ Warning: `mult3(x::Int)` is deprecated, use `mult(3, x)` instead.
│ caller = top-level scope at REPL[3]:1
└ @ Core REPL[3]:1
42
(但从 Julia 1.5 开始,只有在 Julia 的命令行中提供了 --depwarn=yes
或者它出现在测试套件 运行 中时才会显示警告 Pkg.test()
)
或者,如评论中所述,您可能希望保留旧的实现,只是在用户调用时警告用户。为此,可以直接使用Base.depwarn
:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated
# It is implemented by itself:
function mult3(x)
Base.depwarn("`mult3(x)` is deprecated, use `mult(3,x)` instead.", :mult3)
return 3x
end
当在 Julia 的命令行中提供 --depwarn=yes
时,这会产生与 @deprecate
相同类型的警告:
julia> mult3(14)
┌ Warning: `mult3(x)` is deprecated, use `mult(3,x)` instead.
│ caller = top-level scope at REPL[4]:1
└ @ Core REPL[4]:1
42
从 Julia 1.6 开始,depwarn
将接受一个关键字参数以强制发出警告,即使用户没有使用 --depwarn=yes
:
请求它们
julia> Base.depwarn("Foo is deprecated", :foo, force=true)
┌ Warning: Foo is deprecated
│ caller = ip:0x0
└ @ Core :-1
(问题参考Julia v1.5版本)
我正在尝试了解 @deprecate
宏在 Julia 中的工作原理。 documentation 不幸的是我不清楚:
@deprecate old new [ex=true]
Deprecate method old and specify the replacement call new. Prevent @deprecate from exporting old by setting ex to false. @deprecate defines a new method with the same signature as old.
Warning: As of Julia 1.5, functions defined by @deprecate do not print warning when julia is run without the --depwarn=yes flag set, as the default value of --depwarn option is no. The warnings are printed from tests run by Pkg.test().
Examples
julia> @deprecate old(x) new(x)
old (generic function with 1 method)
julia> @deprecate old(x) new(x)
false old (generic function with 1 method)
那我该怎么办?
function old(x::Int)
print("Old behavior")
end
function new(x::Int)
print("New behavior")
end
# Adding true/false argument doesn't change my observations.
@deprecate old(x) new(x) # false
old(3)
# Prints "Old behaviour". No warning.
# Also: The deprecation is not mentioned in the help (julia>? old)
这个@deprecate
宏的目的好像是替换函数?我觉得这违反直觉。如何将一个函数标记为已弃用(即用户应该收到警告和提示使用什么作为替代品,它也应该在文档中)?
编辑:我注意到我的错误。签名(在我的例子中是 ::Int
)必须相同才能工作。但是,如何获得警告?
假设您将此方法作为第 1 版库的 public API 的一部分:
# v1.0.0
mult3(x::Int) = 3x
在版本 2 中,您希望停止支持 mult3
(这是一项重大更改)。但是使用更通用的方法仍然可以使用相同的功能:
# v2.0.0
mult(x, y) = x * y
版本 1 的用户习惯使用 mult3
,这意味着当他们更新到 v2 时,他们的代码会崩溃。因此,您可能希望在 v1.x 系列中发布一个中间版本,其中 mult3
存在但已弃用并根据 mult
:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated and implemented using the old one
@deprecate mult3(x::Int) mult(3, x)
# The above is more or less equivalent to defining
# function mult3(x::Int)
# # print an error message is `--depwarn` has been set
# return mult(3, x)
# end
v1 API 在晚期 v1.x 版本中没有损坏,但调用已弃用方法的用户将看到以下类型的消息,以帮助他们过渡到较新的 v2 API:
julia> mult3(14)
┌ Warning: `mult3(x::Int)` is deprecated, use `mult(3, x)` instead.
│ caller = top-level scope at REPL[3]:1
└ @ Core REPL[3]:1
42
(但从 Julia 1.5 开始,只有在 Julia 的命令行中提供了 --depwarn=yes
或者它出现在测试套件 运行 中时才会显示警告 Pkg.test()
)
或者,如评论中所述,您可能希望保留旧的实现,只是在用户调用时警告用户。为此,可以直接使用Base.depwarn
:
# v1.1 - transition
# This is the new API for v2
mult(x, y) = x*y
# The old API is still supported, but deprecated
# It is implemented by itself:
function mult3(x)
Base.depwarn("`mult3(x)` is deprecated, use `mult(3,x)` instead.", :mult3)
return 3x
end
当在 Julia 的命令行中提供 --depwarn=yes
时,这会产生与 @deprecate
相同类型的警告:
julia> mult3(14)
┌ Warning: `mult3(x)` is deprecated, use `mult(3,x)` instead.
│ caller = top-level scope at REPL[4]:1
└ @ Core REPL[4]:1
42
从 Julia 1.6 开始,depwarn
将接受一个关键字参数以强制发出警告,即使用户没有使用 --depwarn=yes
:
julia> Base.depwarn("Foo is deprecated", :foo, force=true)
┌ Warning: Foo is deprecated
│ caller = ip:0x0
└ @ Core :-1