lifecycle は、エクスポートされた関数や引数の状態を記録するために使用します。ドキュメントに lifecycle ステージを記述するための標準的な方法と、非推奨の関数からユーザーを引き離すためのツールを提供します。
関数1 の lifecycle ステージを下図にまとめました。
デフォルトの開発ステージは、 です。関数は、作者がそのインタフェースや動作に十分満足し、多くのユーザと共有できる場合に安定したとみなされます。安定した機能には保証があります。もし破壊的な変更が必要な場合は、以下に説明する非推奨のプロセスを通じて、徐々に行われるでしょう。
エクスポートされた関数の安定性は、エクスポート元のパッケージのバージョン番号に基づいて、さらに細かく設定することができます。>1.0.0パッケージでは、主要な機能は作者によって「完成」されたとみなされます。ブレークチェンジや非推奨はあり得ません。1.0.0 以下のパッケージでは、パッケージのいくつかの部分 (内部バックエンド、外部 UI など) はまだ作業が必要であり、変更が可能です。安定した >=1.0.0 パッケージは、依存し、頼るのに最も安全なパッケージです。
パッケージと関数の中には、 ステージで公開されるものもあります。実験的な機能は、人々がそれを試してフィードバックを提供できるように公開されていますが、作者は変更を壊さないようにすることを約束するものではありません。壊れるような変更に対する非推奨のプロセスは保証されていません(ただし、十分に多くのユーザーがその機能に依存している場合には、起こるかもしれません)。
ある関数が寿命を迎えるには、2つの方法があります。
特に重要な機能については、非推奨のサイクルを2段階追加することができます。
ソフト非推奨 (soft-deprecated) は非推奨 (deprecated)の前に来るものです。これは非推奨の中でも穏やかなもので、関数の新たな利用を防ぎ、パッケージ開発者に新しい機能への移行を促すように設計されています。ソフト非推奨 はパッケージが拡張インターフェイスを変更する際に、ユーザが変更を強いられる前に下流の依存関係が適応できるような方法で変更することを可能にします。
非推奨の次が廃止 (defunct) です。廃止された関数はまだエクスポートされ、廃止された引数はまだシグネチャの一部ですが、それらの使用は情報付きのエラーを発生させます。
関数の作者は、ある関数が最適なアプローチであることを確信できなくなることがありますが、より良い方法をまだ知らないのです。このような関数は、 としてマークすることで、作者がその関数に疑問を抱いていることをユーザーに警告することができます。
実験的、疑問的、上書きのある、非推奨(ソフト非推奨、廃止された機能を含む)は、文書中にバッジで明確に表示されるべきです。
usethis::use_lifecycle()
を呼び出して、パッケージにあるバッジをインポートします。そして、バッジを挿入するために lifecycle::badge()
を使用します。
このバッジは、HTML以外のドキュメントではテキストとしてレンダリングされます。関数全体の状態を記録するには、@description
ブロックの一番上にバッジを置くとよいでしょう。引数のドキュメントを作成するには、引数の説明の中にバッジを記述します。
lifecycle::badge()
は roxygen によってのみ実行されるため、これはビルド時の依存関係にあります。ドキュメントにバッジを含めるためだけに lifecycle をインポートする必要はありません。
また、なぜその機能がその状態になっているのか、簡単な説明を入れておくとよいでしょう。
古い関数や非推奨の関数については、古い構文から新しい構文への変換方法を示す例を書き直します。
非推奨の関数については、@keywords
を内部に追加し、_pkgdown.yaml
(pkgdown を使用している場合) を更新して、ドキュメントインデックスに表示されないようにします。
非推奨の関数は、その非推奨の状態を明確に示す必要があります。メッセージの多さ (verbosity) には3つのレベルがあります。
Soft deprecation: deprecate_soft()
を呼び出すと、最も混乱を招かない方法で、非推奨に関する警告をユーザに開始します。この関数は、(a) グローバルなワークスペースからその機能を試すユーザ (最大で 8 時間に一度)、および (b) その機能を直接使う開発者 (testthat テスト実行時) にのみ警告を出します。非推奨の機能が他のパッケージから間接的に呼び出された場合は、警告を発しません。
Deprecation: deprecate_warn()
を呼び出すと、廃止される機能について無条件に警告を出すことができます。警告は8時間に一度だけ発行されます。
Defunct: deprecate_stop()
を呼び出すと、エラーで失敗します。
以下の項では、関数や引数を非推奨とする場合の詳細を説明します。
最初の2つの引数は、非推奨が発生したバージョン3と、何が非推奨であるかの説明を与えます。
deprecate_warn("1.0.0", "mypkg::foo()")
#> Warning: `foo()` is deprecated as of mypkg 1.0.0.
#> This warning is displayed once every 8 hours.
#> `lifecycle::last_warnings()` をコールして、この警告がどこで発生したかを確認します。
可能であれば、第3引数に置換を記述します。
deprecate_warn("1.0.0", "mypkg::foo()", "new()")
#> Warning: `foo()` is deprecated as of mypkg 1.0.0.
#> Please use `new()` instead.
#> This warning is displayed once every 8 hours.
#> `lifecycle::last_warnings()` をコールして、この警告がどこで発生したかを確認します。
これらの例では、明示的に名前空間に言及していますが、ライフサイクルが呼び出し環境から推論するため、通常は名前空間を省略することができます。名前空間を指定することは、その置換が別のパッケージで実装されている場合にほとんど有効です。
非推奨の引数の構文も同様です。
deprecate_warn("1.0.0", "mypkg::foo(arg = )")
#> Warning: The `arg` argument of `foo()` is deprecated as of mypkg 1.0.0.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_warnings()` to see where this warning was generated.
deprecate_warn("1.0.0", "mypkg::foo(arg = )", "mypkg::foo(new = )")
#> Warning: The `arg` argument of `foo()` is deprecated as of mypkg 1.0.0.
#> Please use the `new` argument instead.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_warnings()` to see where this warning was generated.
引数は、特定の入力タイプを禁止することで、部分的に非推奨とすることができます。
deprecate_warn("1.0.0", "mypkg::foo(arg = 'must be a scalar integer')")
#> Warning: The `arg` argument of `foo()` must be a scalar integer as of mypkg 1.0.0.
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_warnings()` to see where this warning was generated.
lifecycle はまた、デフォルトの引数として使用する deprecated()
センチネルを提供します。これはユーザに対してセルフ・ドキュメンテーションを提供し、外部ツールはどの引数が廃止されたかを判断することが可能になります。lifecycle::is_present()
で、呼び出し元から引数が与えられたかどうかテストします。
foobar_adder <- function(foo, bar, baz = deprecated()) {
# Check if user has supplied `baz` instead of `bar`
if (lifecycle::is_present(baz)) {
# Signal the deprecation to the user
deprecate_warn("1.0.0", "foobar_adder(baz = )", "foobar_adder(bar = )")
# Deal with the deprecated argument for compatibility
bar <- baz
}
foo + bar
}
lifecycle::last_warnings()
を呼び出すと、最後のトップレベルコマンドで発行されたすべての非推奨 警告のバックトラックを見ることができます。
非推奨の機能のステータスを上げるには、手動での検索と置換が必要です。廃止された機能から始めて、順次対応することをお勧めします。
deprecate_stop()
を検索して、パッケージから機能を削除してください。これでその機能はアーカイブされます。
deprecate_warn()
を検索して deprecate_stop()
に置き換えてください。
deprecate_soft()
を検索して、deprecate_warn()
に置き換えてください。
新たに非推奨となった関数からdeprecate_soft()
を呼び出します。
ドキュメントトピックのバッジを更新することを忘れないでください。
test_check()
が呼ばれる直前に tests/testthat.R
ファイルで verbosity オプションを設定することにより、あなたのパッケージが非推奨の機能に直接または間接的に依存しているかどうかをテストすることができます。
これにより、非推奨の機能はすべて強制的に失敗するようになります。また、関連するオプションを手動で設定して、セッションで警告やエラーを強制的に発生させることもできます。
# Force silence
options(lifecycle_verbosity = "quiet")
# Force warnings
options(lifecycle_verbosity = "warning")
# Force errors
options(lifecycle_verbosity = "error")
警告の強制は last_warnings()
との組み合わせで有用であり、最後のトップレベルコマンドで発行されたすべての非推奨 警告のバックトラックを表示します。
lifecycle_verbosity
を "quiet"
に設定することによって、非推奨の機能がまだ動作するかどうかをテストします。
test_that("`baz` argument of `foobar_adder()` still works", {
withr::local_options(list(lifecycle_verbosity = "quiet"))
foobar_adder(1, baz = 2)
})
setup()
と teardown()
ブロックの中で testthat ファイル全体に対してメッセージの多さを設定することも可能です。
expect_deprecated()
または expect_defunct()
を用いて、機能が正しく非推奨であることをテストしてください。
test_that("`baz` argument of `foobar_adder()` is deprecated", {
expect_deprecated(foobar_adder(1, baz = 2))
})
test_that("`foo()` is defunct", {
expect_defunct(foo())
})
lifecycle_verbosity
オプションを使用すると、メッセージの多さをさらに制御することができます。 ?verbosity
をご覧ください。