1

私は、グラフ データベースの REST API ラッパーにすぎない R パッケージに取り組んできました。クラスとcreateNodeオブジェクトを返す関数があります:nodeentity

# Connect to the db.
graph = startGraph("http://localhost:7474/db/data/")

# Create two nodes in the db.
alice = createNode(graph, name = "Alice")
bob = createNode(graph, name = "Bob")

> class(alice)
[1] "node"   "entity"
> class(bob)
[1] "node"   "entity"

createRelデータベース内の 2 つのノード間の関係を作成する別の関数 があります。次のように指定されます。

createRel = function(fromNode, type, toNode, ...) {
  UseMethod("createRel")
}

createRel.default = function(fromNode, ...) {
  stop("Invalid object. Must supply node object.")
}

createRel.node = function(fromNode, type, toNode, ...) {
  params = list(...)

  # Check if toNode is a node.
  stopifnot("node" %in% class(toNode))

  # Making REST API calls through RCurl and stuff.
}

を使用...すると、ユーザーはキー = 値の形式で関係に任意の数のプロパティを追加できます。例えば、

rel = createRel(alice, "KNOWS", bob, since = 2000, through = "Work")

これにより、db に (Alice)-[KNOWS]->(Bob) の関係が作成され、プロパティsincethroughそれぞれの値が作成されます。ただし、ユーザーがキーfromまたは引数toでプロパティを指定すると...、R は と のクラスについて混乱しfromNodeますtoNode

key でプロパティを指定するとfrom、 のクラスについて混乱が生じfromNodeます。使用していcreateRel.defaultます:

> createRel(alice, "KNOWS", bob, from = "Work")

Error in createRel.default(alice, "KNOWS", bob, from = "Work") : 
Invalid object. Must supply node object. 
3 stop("Invalid object. Must supply node object.") 
2 createRel.default(alice, "KNOWS", bob, from = "Work") 
1 createRel(alice, "KNOWS", bob, from = "Work")

同様に、ユーザーが keytoでプロパティを指定すると、 のクラスについて混乱が生じtoNode、 で停止しますstopifnot()

Error: "node" %in% class(toNode) is not TRUE 
4 stop(sprintf(ngettext(length(r), "%s is not TRUE", "%s are not all TRUE"), 
  ch), call. = FALSE, domain = NA) 
3 stopifnot("node" %in% class(toNode)) 
2 createRel.node(alice, "KNOWS", bob, to = "Something") 
1 createRel(alice, "KNOWS", bob, to = "Something")

パラメータを明示的に設定するとうまくいくことがわかりましたcreateRel

rel = createRel(fromNode = alice,
                type = "KNOWS",
                toNode = bob,
                from = "Work",
                to = "Something")
# OK

createRelしかし、次の構文がエラーなしで機能するように、関数をどのように編集する必要があるのか​​ 疑問に思っています。

rel = createRel(alice, "KNOWS", bob, from = "Work", to = "Something")
# Errors galore.

この問題を開いた GitHub ユーザーは、とsetAsという引数を持つ on dispatch との競合である可能性が最も高いと述べました。解決策の 1 つは、削除して次のように変更することです。fromto...createRel

createRel = function(fromNode, type, toNode, params = list()) {
  UseMethod("createRel")
}

createRel.default = function(fromNode, ...) {
  stop("Invalid object. Must supply node object.")
}

createRel.node = function(fromNode, type, toNode, params = list()) {
  # Check if toNode is a node.
  stopifnot("node" %in% class(toNode))

  # Making REST API calls through RCurl and stuff.
}

しかし、この変更を行う前に、他のオプションがあるかどうかを確認したかった.

4

1 に答える 1

2

全然答えになってないけど…

問題は、ユーザー提供の引数「from」が (部分的に) 正式な引数「fromNode」と一致していることです。

f = function(fromNode, ...) fromNode
f(1, from=2)
## [1] 2

ルールは、 のセクション 4.3.2 で概説されていますRShowDoc('R-lang')。ここでは、名前付き引数が完全に一致し、次に部分一致し、名前のない引数が位置によって割り当てられます。

単一文字の引数名を使用する以外に、完全一致を強制する方法を知るのは困難です! 実際、ジェネリックの場合、これは思ったほど陳腐ではないかもしれませんx。かなり一般的な変数名です。'from' と 'to' が ... への共通の引数である場合、引数リストを "fromNode, , ..., from, to" に変更し、関数の本体で行方不明 (from) をチェックして、アクションを実行できます。によると; これは喜ばしいことではないと思いますし、ユーザーは常に引数 'fro' を提供するでしょう。

global を設定して完全一致 (および warn=2 によるエラー) を強制するoptions()ことは、デバッグに役立つかもしれません (ただし、それまでには、何を探していたのかがわかるはずです!)一般的なユーザーに対して機能するコード。

R-devel メーリング リストで、この動作を変更する時期が来ているかどうかを尋ねるのが妥当かもしれません (「数回のリリース」のタイム スケールで)。部分一致は、おそらくタブ補完の数日前から「便宜」として日付が付けられています。

于 2014-08-29T12:17:09.117 に答える