静電気
R6 クラスは、環境の参照渡しによるコピーの挙動を利用して、オブジェクト間でフィールドを共有できます。これを設定するには、shared という名前のプライベートフィールドを定義します。このフィールドは複数行で定義し、次を行う必要があります。
- 新しい環境を作成する。
- 共有するフィールドをその環境に代入する。
- その環境を返す。
共有フィールドにはアクティブバインディング経由でアクセスします。これは、これまで見てきた他のアクティブバインディングと同様に動作しますが、private$shared$ プレフィックスを使ってフィールドを取得します。
R6Class(
"Thing",
private = list(
shared = {
e <- new.env()
e$a_shared_field <- 123
e
}
),
active = list(
a_shared_field = function(value) {
if(missing(value)) {
private$shared$a_shared_field
} else {
private$shared$a_shared_field <- value
}
}
)
)
アクティブバインディングの名前は、取得・設定したい共有フィールド名と同じでなければならない点に注意してください。上の例ではどちらも a_shared_field です。
この演習はコースの一部です
R における S3 と R6 を使ったオブジェクト指向プログラミング
演習の手順
MicrowaveOven クラスが一部まで定義されています。
MicrowaveOvenクラスの private 要素にあるsharedフィールドを更新します。- このフィールドは中括弧
{}で囲まれた3行のコードを含みます。 - まず
new.env()(docs)を呼び出してeという新しい環境を作成し、次に… eにsafety_warningという変数を代入し、値は"Warning. Do not try to cook metal objects."とします。その後に…- その環境を返します。
- このフィールドは中括弧
- プライベートな共有フィールド
safety_warningを取得・設定する、safety_warningという名前のアクティブバインディングを追加します。- これは
active要素内の関数として定義します。 - 引数は
valueの1つです。 private$shared$safety_warningを取得・設定するようにします。
- これは
MicrowaveOvenオブジェクトを2つ作成し、それぞれa_microwave_ovenとanother_microwave_ovenという名前を付けます。a_microwave_ovenのsafety_warningフィールドを"Warning. If the food is too hot you may scald yourself."に変更します。- 変更が反映されていることを確認するため、
another_microwave_ovenのsafety_warningフィールドを確認します。
実践的なインタラクティブ演習
このサンプルコードを完成させて、この演習に挑戦してみましょう。
# Complete the class definition
microwave_oven_factory <- R6Class(
"MicrowaveOven",
private = list(
shared = {
# Create a new environment named e
___
# Assign safety_warning into e
___
# Return e
___
}
),
active = list(
# Add the safety_warning binding
safety_warning = ___(___) {
if(___(___)) {
___
} else {
___ <- ___
}
}
)
)
# Create two microwave ovens
a_microwave_oven <- ___
another_microwave_oven <- ___
# Change the safety warning for a_microwave_oven
___ <- "Warning. If the food is too hot you may scald yourself."
# Verify that the warning has change for another_microwave
___