始める無料で始める

静電気

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 という新しい環境を作成し、次に…
    • esafety_warning という変数を代入し、値は "Warning. Do not try to cook metal objects." とします。その後に…
    • その環境を返します。
  • プライベートな共有フィールド safety_warning を取得・設定する、safety_warning という名前のアクティブバインディングを追加します。
    • これは active 要素内の関数として定義します。
    • 引数は value の1つです。
    • private$shared$safety_warning を取得・設定するようにします。
  • MicrowaveOven オブジェクトを2つ作成し、それぞれ a_microwave_ovenanother_microwave_oven という名前を付けます。
  • a_microwave_ovensafety_warning フィールドを "Warning. If the food is too hot you may scald yourself." に変更します。
  • 変更が反映されていることを確認するため、another_microwave_ovensafety_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
___ 
コードを編集して実行