前もって: R が関数型言語であることは認識しているので、噛まないでください ;-)
私は、多くのプログラムで OOP アプローチを使用して素晴らしい経験を積んできました。さて、 R でS4 参照クラスを使用するときに、パブリックメソッドとプライベートメソッドを区別する方法があるかどうか疑問に思っています。
例
クラス定義
setRefClass("B",
field=list(
b.1="numeric",
b.2="logical"
),
methods=list(
thisIsPublic=function(...) {
thisIsPublic_ref(.self=.self, ...)
},
thisIsPrivate=function(...) {
thisIsPrivate_ref(.self=.self, ...)
}
)
)
setRefClass("A",
field=list(
a.1="B"
)
)
ノート
私は通常、実際のthisIsPublic_ref
メソッド定義をクラス定義内に配置せず、次の理由でS4 メソッド (つまり ) に分離します。
- そうすれば、クラス定義は明確に配置されたままになり、個々のメソッド定義が非常に大きくなる場合でも読みやすくなります。
- これにより、いつでもメソッドの機能実行に切り替えることができます。特定のクラスのインスタンスになると、 の代わりに
x
呼び出すことができます。foo_ref(.self=x)
x$foo()
compiler::cmpfun()
「プレーンな」参照クラスメソッドがある場合は不可能だと思われるメソッドをバイトコンパイルできます。
この特定の例をそれほど複雑にすることは確かに意味がありませんが、それでもそのアプローチを説明したいと思いました。
メソッド定義
setGeneric(
name="thisIsPublic_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPublic_ref")
}
)
setGeneric(
name="thisIsPrivate_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPrivate_ref")
}
)
require(compiler)
setMethod(
f="thisIsPublic_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.1 * 1000
})
)
setMethod(
f="thisIsPrivate_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.2
})
)
インスタンス
x.b <- new("B", b.1=10, b.2=TRUE)
x.a <- new("A", a.1=x.b, a.2="hello world")
パブリック vs. プライベート
class のインスタンスA
(つまり) は、 classのpublicメソッドx.a
を使用できるようにする必要があります。B
> x.a$a.1$thisIsPublic()
[1] 10000
class のインスタンスA
(つまりx.a
) は、 classのプライベートメソッドの使用を許可されるべきではありません。したがって、これが機能しないようにしたいと思います。つまり、エラーが発生します。B
> x.a$a.1$thisIsPrivate()
[1] TRUE
これをどのように指定できますか?
これまでに思いついた唯一のこと:
各メソッドに引数を追加し、sender
メソッド呼び出しごとに明示的に指定して、 if を確認しますclass(.self) == class(sender)
。しかし、それは少し「明白」に思えます。