メモ:S3のクラスでS4のメソッドをディスパッチする
ちょっと気になったのでメモ。
準備
クラス定義をつくる
setClass("Greeting") .EG <- setClass("EnglishGreeting", contains = "Greeting") .JG <- setClass("JapaneseGreeting", contains = "Greeting") .NG <- setClass("NinjaGreeting", contains = "Greeting") # メソッドを定義してみるテスト setGeneric("sanzuke", function(x, to) standardGeneric("sanzuke")) #> [1] "sanzuke" setMethod("sanzuke", "Greeting", function(x, to) to) #> [1] "sanzuke" # EnglishGreetingにはメソッドがない。スーパークラスのメソッドがディスパッチされる。 setMethod("sanzuke", "JapaneseGreeting", function(x, to) paste0(to, "さん")) #> [1] "sanzuke" setMethod("sanzuke", "NinjaGreeting", function(x, to) paste0(to, "=サン")) #> [1] "sanzuke" # インスタンスをつくる eg <- .EG() jg <- .JG() ng <- .NG() # どれも予想通り動く sanzuke(eg, "V8") #> [1] "V8" sanzuke(jg, "V8") #> [1] "V8さん" sanzuke(ng, "V8") #> [1] "V8=サン" # メソッドを定義してみるテストその2、今度はすべてにメソッドがある setGeneric("doGreet", function(x, to) standardGeneric("doGreet")) #> [1] "doGreet" setMethod("doGreet", "Greeting", function(x, to) stop("Not implemented")) #> [1] "doGreet" setMethod("doGreet", "EnglishGreeting", function(x, to) cat(glue::glue("Hello, {sanzuke(x, to)}"))) #> [1] "doGreet" setMethod("doGreet", "JapaneseGreeting", function(x, to) cat(glue::glue("こんにちは、{sanzuke(x, to)}"))) #> [1] "doGreet" setMethod("doGreet", "NinjaGreeting", function(x, to) cat(glue::glue("ドーモ、{sanzuke(x, to)}"))) #> [1] "doGreet" doGreet(eg, "V8") #> Hello, V8 doGreet(jg, "V8") #> こんにちは、V8さん doGreet(ng, "V8") #> ドーモ、V8=サン
S4クラス用に定義されたメソッドをS3クラスでディスパッチする
dummy_ng <- structure(list(), class = "NinjaGreeting") doGreet(dummy_ng, "V8") #> ドーモ、V8=サン # classには`EnglishGreeting`しか書いてないが、ちゃんとGreetingのメソッドをディスパッチできている dummy_eg <- structure(list(), class = "EnglishGreeting") doGreet(dummy_eg, "V8") #> Hello, V8
S3のクラスをシグネチャに使ってS4のメソッドを定義する
# 特殊なS3クラスを作ってみる nm <- "V8" class(nm) <- "god_name" # 警告は出るけどシグネチャとして使える setMethod("doGreet", c("EnglishGreeting", "god_name"), function(x, to) cat(glue::glue("Praise the {sanzuke(x, to)}!!"))) #> in method for 'doGreet' with signature '"EnglishGreeting","god_name"': no definition for class "god_name" #> [1] "doGreet" doGreet(dummy_eg, nm) #> Praise the V8!! # setOldClassしておくと警告は出ない setOldClass("god_name") setMethod("doGreet", c("EnglishGreeting", "god_name"), function(x, to) cat(glue::glue("Praise the {sanzuke(x, to)}!!"))) #> [1] "doGreet"
参考
このへん?