You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/05/13 12:48:05 UTC

[20/28] incubator-tinkerpop git commit: Added "reuse" to the list of recipes. CTR

Added "reuse" to the list of recipes. CTR


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/5c3ca93d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/5c3ca93d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/5c3ca93d

Branch: refs/heads/TINKERPOP-1297
Commit: 5c3ca93db72c900916057f26f01214e604f8b22d
Parents: 2cafe68
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed May 11 16:23:06 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Wed May 11 16:23:32 2016 -0400

----------------------------------------------------------------------
 docs/src/recipes/index.asciidoc                 |  8 +++
 .../recipes/traversal-component-reuse.asciidoc  | 71 ++++++++++++++++++++
 2 files changed, 79 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/5c3ca93d/docs/src/recipes/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/recipes/index.asciidoc b/docs/src/recipes/index.asciidoc
index a9c3796..3d18387 100644
--- a/docs/src/recipes/index.asciidoc
+++ b/docs/src/recipes/index.asciidoc
@@ -33,10 +33,18 @@ Recipes assume general familiarity with Gremlin and the TinkerPop stack. Be sure
 link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/getting-started[Getting Started] tutorial and the
 link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/the-gremlin-console/[The Gremlin Console] tutorial.
 
+Traversal Recipes
+=================
+
 include::shortest-path.asciidoc[]
 
 include::if-then-based-grouping.asciidoc[]
 
+Implementation Recipes
+======================
+
+include::traversal-component-reuse.asciidoc[]
+
 [[contributing]]
 How to Contribute a Recipe
 ==========================

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/5c3ca93d/docs/src/recipes/traversal-component-reuse.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/recipes/traversal-component-reuse.asciidoc b/docs/src/recipes/traversal-component-reuse.asciidoc
new file mode 100644
index 0000000..2b65644
--- /dev/null
+++ b/docs/src/recipes/traversal-component-reuse.asciidoc
@@ -0,0 +1,71 @@
+////
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+////
+[[traversal-component-reuse]]
+Traversal Component Reuse
+-------------------------
+
+Good software development practices require reuse to keep software maintainable. In Gremlin, there are often bits of
+traversal logic that could be represented as components that might be tested independently and utilized
+as part of other traversals. One approach to doing this would be to extract such logic into an anonymous traversal
+and provide it to a parent traversal through `flatMap()` step.
+
+Using the modern toy graph as an example, assume that there are number of traversals that are interested in filtering
+on edges where the "weight" property is greater than "0.5". A query like that might look like this:
+
+[gremlin-groovy,modern]
+----
+g.V(1).outE("knows").has('weight', P.gt(0.5d)).inV().both()
+----
+
+Repeatedly requiring that filter on "weight" could lead to a lot of duplicate code, which becomes difficult to
+maintain. It would be nice to extract that logic so as to centralize it for reuse in all places where needed. An
+anonymous traversal allows that to happen and can be created as follows.
+
+[gremlin-groovy,modern]
+----
+weightFilter = outE("knows").has('weight', P.gt(0.5d)).inV();[]
+g.V(1).flatMap(weightFilter).both()
+----
+
+The `weightFilter` is an anonymous traversal and it is created by way `__` class. The `__` is omitted above from
+initalization of `weightFilter` because it is statically imported to the Gremlin Console. The `weightFilter` gets
+passed to the "full" traversal by way for `flatMap()` step and the results are the same. Of course, there is a problem.
+If there is an attempt to use that `weightFilter` a second time, the traversal with thrown an exception because both
+the `weightFilter` and parent traversal have been "compiled" which prevents their re-use. A simple fix to this would
+be to clone the `weightFilter`.
+
+[gremlin-groovy,modern]
+----
+weightFilter = outE("knows").has('weight', P.gt(0.5d)).inV();[]
+g.V(1).flatMap(weightFilter.clone()).both()
+g.V(1).flatMap(weightFilter.clone()).bothE().otherV()
+g.V(1).flatMap(weightFilter.clone()).groupCount()
+----
+
+Now the `weightFilter` can be reused over and over again. Remembering to `clone()` might lead to yet another maintenance
+issue in that failing to recall that step would likely result in a bug. One option might be to wrap the `weightFilter`
+creation in a function that returns the clone. Another approach might be to parameterize that function to construct
+a new anonymous traversal each time with the idea being that this might gain even more flexibility in parameterizing
+the anonymous traversal itself.
+
+[gremlin-groovy,modern]
+----
+weightFilter = { w -> outE("knows").has('weight', P.gt(w)).inV() }
+g.V(1).flatMap(weightFilter(0.5d)).both()
+g.V(1).flatMap(weightFilter(0.5d)).bothE().otherV()
+g.V(1).flatMap(weightFilter(0.5d)).groupCount()
+----
\ No newline at end of file